連載「YOKOSO PAY の舞台裏」第 1 回
YOKOSO PAY のシステム構成小さく始めて、伸びたら広げる
YOKOSO PAY とは
- 旅行者・お店・町をつなぐ、町おこしのプラットフォームです。旅のプランづくりから、予約・注文・支払い、帰ったあとのおみやげやお知らせまでを、ひとつのアプリでつなぎます
- 訪日外国人も、日本人のリピーターも使えます。11 の言語に対応し、アプリのインストールは要りません
- 飲食・体験・物販・通販のお店と、スタンプラリーや AR の宝探しなどの町のイベントを、同じ土台で動かしています。実際のお店で使われています
はじめに
合同会社Techno Vision AO は、町おこしのプラットフォーム「YOKOSO PAY」を作り、運営しています。
この連載では、ふだんは見えない YOKOSO PAY の舞台裏を、4 回に分けて紹介します。
- システムの構成 (この記事)
- AI ネイティブな開発体制
- 守る・気づく・直す ── セキュリティと運用
- 企画から一緒に ── イベントや地域の取り組みへの伴走
第 1 回は、全体の構成です。何をどこに置いたのか、なぜそれを選んだのかを説明します。
YOKOSO PAY でできること
旅の前から旅のあとまで、旅行者・お店・町のそれぞれに機能があります。
- 旅の前 (旅のプラン)行き先と泊数を選ぶだけで、その町の旅のプランができます。町の名所とモデルコースは、地域の方と一緒に作ります
- 飲食のお店お客様は席の QR から、11 の言語のメニューで注文します。お店には日本語で届き、厨房の画面に送られます。会計・予約・出前・テイクアウトにも対応しています
- 体験・ツアー体験やツアーの予約と、事前の支払いを受け付けます
- 物販のお店店頭の会計を、スマホの QR でも、店頭のカード端末でも受け付けます。レシートプリンタともつながります
- 通販 (YOKOSO EC)旅先で気に入ったおみやげを、旅のあとに自宅で買えます。出店するお店は、商品を出すところから発送まで行えます
- 町・イベントスタンプラリーと AR の宝探しで、町を回ってもらいます。町からのお知らせを届けたり、個人が分からない集計で施策の効果を確かめたりできます
どれも、体験版の実際の画面で試せます。
全体の構成
構成は、大きく 5 つに分かれます。
| 部分 | 役割 | 使っているもの |
|---|---|---|
| 画面 | お客様とお店が操作する画面 | Cloud Run |
| API | 画面とデータの間で、処理を受け持つ窓口 | Cloud Run |
| データ | 注文や予約などの記録 | Firestore |
| 定期処理 | 決まった時刻に動く仕事 | Cloud Scheduler・Cloud Run Jobs |
| 見張り | 異常を見つけて、運営に知らせる | Cloud Logging・Cloud Monitoring |
外側には、決済の Stripe などの外部サービスがあります。ここからは、それぞれを選んだ理由を説明します。
画面: アプリを入れずに開ける
- 選んだものブラウザで動くアプリ (PWA と呼ばれる形)
- 理由旅行中の方に「まずアプリを入れてください」とお願いすると、多くの方がそこでやめてしまいます。QR を読んだらすぐ開けることを優先しました
- 使い心地一度開いた画面は、電波の弱い場所でもすぐに表示されます
AR: ブラウザだけで動く宝探し
- 選んだものブラウザで動く AR (WebAR)
- 理由イベントの参加者に、AR のためのアプリを入れてもらわずに済みます。QR を読めば、そのままカメラで宝を探せます
- 守りスタンプを付けるかどうか、同じ人が二度もらっていないかは、API が判断します。AR の画面は、会員の情報を持ちません
API: 共通の機能をまとめて、保守しやすく
- 共通の機能として切り出す注文・会計・予約・決済のように、どの業務でも使う機能は、業務ごとに作らず 1 か所にまとめています (抽象化)。飲食のお店も物販のお店も同じ「注文・会計」を使い、体験やツアーは「予約」を使います
- 直すのは 1 か所改善や修正は 1 か所で済み、すべての業務に同時に行き渡ります。業務ごとに同じ直しを繰り返さずに済みます
- 新しい業態も早く新しい業態も、今ある機能を組み合わせて始められます
データ: 変化がすぐ画面に届く
- 選んだものGoogle の Firestore
- 理由データの変化を、すぐに画面へ届けられます。お客様が注文するとすぐ厨房の画面に出て、お店が「できました」を押すと、お客様のスマホの表示が変わります
- 守りデータを書き換えられるのは API だけです。ブラウザが読めるのも、本人に関係するデータだけです (詳しくは第 3 回で書きます)
- 分け方本番のデータは、開発やテストで使うデータとは別の置き場所にあります。テストが本番のデータに触れることはありません
決済: カード番号を持たない
- 選んだものStripe (世界で使われている決済サービス)
- カード番号を持たないお客様のカード番号は、Stripe の画面に直接入力されます。当社のサーバは通りません
- 売上の流れお店ごとに Stripe のアカウントを作り、売上はそこからお店の口座に入ります。店頭のカード端末も、同じ Stripe の仕組みです
- 金額はサーバで計算注文の会計では、スマホから届いた金額をそのまま使いません。メニューの値段から、サーバで計算し直します
定期処理: 人が忘れても止まらない
決まった仕事は、人の手ではなく、時刻で動かします。「忘れずにやる」は、いつか必ず抜けるからです。
- 毎朝、Stripe と当社の記録を突き合わせる
- 期限が過ぎた予約や注文を取り消す
- 退会した方の個人情報を消す
AI: メニューを訳す・写真から読み取る
- 翻訳Google の Vertex AI で、メニューを各国の言葉に訳します
- 読み取り紙のメニューを撮るだけで、品目と値段を読み取ります
- ねらいお店が多言語のメニューを用意する手間を減らします
エンジニアの方へ: Google Cloud の構成図
ここまでの内容を、Google Cloud のサービス名で描くと次のとおりです。
- 入口にロードバランサを置いていません利用者は HTTPS で Cloud Run に直接つながり、証明書は Google が管理します。今の規模ではロードバランサの固定費に見合わないため、外しています (足すときの形は「これからの構成」に書きます)
- デプロイに鍵ファイルを使いませんGitHub Actions から Google Cloud へは、Workload Identity 連携で認証します。漏れると困る長期の鍵を持たずに済みます
- 通知は Slack に集めますCloud Monitoring のアラートを、Pub/Sub と Cloud Functions で Slack に流しています。どこで何が起きたかを、運営が 1 か所で見られます
- 設定はコードで管理します設定は Terraform で管理し、毎晩、実際の設定との違いを確かめています。手作業の変更が紛れ込みません
お金のトラブルを防ぐ ── 返金・二重払い・チャージバック
カード決済でもめやすいのは、決済そのものより、その前後です。「二重に払ってしまった」「返金したはずが返っていない」「身に覚えのない請求だと言われた」。YOKOSO PAY は、こうした場面まで仕組みで受け止めます。
二重に払わせない
- 同じ支払いは 1 回だけ電波が不安定で同じ支払いが 2 回送られても、1 回分として扱います。QR 決済・注文・予約・体験・通販・月額の請求・返金のすべてで、この仕組みを使っています
- 使いすぎを止める1 回あたり・1 日あたりの上限と、同じカードを短い時間に何度も使えない制限があります。盗まれたカードで試し打ちをされる被害を防ぎます
- 本人確認アプリでのカード払いでは、カード会社の本人確認 (3D セキュア) を求めます
返金を確実に
- 返金はアプリからだけ返金は、アプリの操作からだけ行えるようにしています。決済サービスの画面から直接返金された場合も見つけて、売上の記録に反映します
- 二重に返金しない返金の操作が重なっても、二重には返金されません
- 失敗した返金は自動でやり直すカード会社の都合で返金が失敗したときは、自動でやり直します
- 「返したつもり」をなくす「返金しました」とお伝えしたのに、まだ返っていないものがあれば、毎朝の突き合わせで見つけて運営に知らせます
チャージバックに備える
チャージバックは、カードの持ち主が「身に覚えがない」とカード会社に申し立てて、支払いが取り消されることです。
- 証拠を自動で集める購入したときの記録・本人確認の記録・注文の内容・レシートを、決済のときから残しています
- 期限までに出す申し立てには、証拠を出す期限があります。お店が気づかなくても、期限が迫ったら集めた証拠を自動で提出します
お店の売上を守る
- 振込先の変更に気づくお店の売上の振込先口座が変えられたら、すぐにお店へメールで知らせ、記録に残します。乗っ取りによるすり替えに気づくためです
実装中のこと
次の 4 つは、いま作っているところです。
- 店頭の端末で通信が途切れたとき店頭のカード端末で通信が途切れても、決済の結果を取り違えず、二重に払わせないようにします
- エラーのあとの「もう一度」お金が動いた後にエラーが出ても、もう一度押して二重に払わせないよう、すべての画面でそろえます
- カードに返せなかった返金カードが使えなくなっていて返金できなかったときに、お店で直接お返しできるようにします
- 通販の返品誰が送料などを負担するかの判定と、出店するお店との精算を仕組みにします
YOKOSO EC: 同じ土台に、通販を足す
- 出店するお店の操作出店するお店は、毎日管理画面を開くとは限りません。そこで注文が入ると、在庫の確認と発送の記録のためのメールをお送りします。届いたメールから、そのまま対応できます
- 配送配送サービスとも連携しています
体験版: 誰でも試せる入口を、本番から切り離す
紹介ページの「体験版」では、お店とお客様の両方の立場で YOKOSO PAY を試せます。業態 (飲食・体験・物販・通販) を選ぶと、お店の画面とお客様の画面が左右に並びます。注文から会計までを、1 人で体験できます。
誰でも使えるので、作るときに 2 つの課題がありました。
課題 1: 同じブラウザで、店員とお客様が混ざる
1 つのブラウザに 2 つの画面を並べると、ログインの情報が混ざります。お客様の画面なのに、店員として動いてしまうことがあります。
解決2 つの画面を、別のドメイン (アドレス) で表示しました。ブラウザはドメインごとに記録を分けるので、店員とお客様は別の人として扱われます。
課題 2: 誰でも使える入口から、本番に届いてはいけない
体験版の API は、誰でも使える入口です。本番と同じ権限で動かすと、体験版に弱点が 1 つあるだけで、本番のデータや決済の鍵に届いてしまいます。
解決体験版は、本番とは別の環境で動かしています。
- 専用のデータ体験のデータは、本番とは別の置き場所に入ります
- 専用の権限体験版が使えるのは、体験用のデータと、体験用・テスト用の鍵だけです。本番のデータや鍵には届きません
- お金は動かない決済はテストモードだけです
- 24 時間で消える来た人ごとに見本のお店を複製し、24 時間たつと自動で片付けます
使われた分だけ費用がかかる仕組みなので、体験用のお店を常に用意しておく必要もありません。
エンジニアの方向けに、Google Cloud のサービス名で描くと次のとおりです。
- 埋め込める先を限る体験の画面を埋め込めるのは、紹介ページだけです。ほかのサイトに埋め込まれて悪用されるのを防ぐためです
- 回数に上限体験を始められる回数に、1 人あたりと全体の上限があります
- 見本は架空のお店体験に使う見本のお店は、架空のものです。実在のお店の名前や連絡先は使いません
これからの構成 ── 今は小さく、伸びたら広げる
今は小さく、安く
利用の規模に合わせて、今の構成はあえて小さくしています。
- 使った分だけCloud Run は、使われた分だけ費用がかかります。使われていない時間は、動いている台数が 0 になります
- お店の負担を小さく毎月決まって出ていく費用 (固定費) がほとんどありません。そのぶん、お店の負担を小さくできます
- 大きく始めない理由最初から大きな構成にすると、まだ来ないアクセスのために、毎月の費用を払い続けることになります
土台にしているサービスには、毎月の無料枠があります。超えた分も、使った量に応じた小さな単価です。
| サービス | 毎月の無料枠 | 超えた分の料金 |
|---|---|---|
| Cloud Run (画面と API) | 200 万リクエスト、CPU 18 万秒、メモリ 36 万 GiB 秒 | 100 万リクエストあたり $0.40。ほかに、処理にかかった秒数に応じて |
| Firestore (データ) | 1 日あたり読み取り 5 万回・書き込み 2 万回、保存 1 GiB | 10 万回あたり数セント |
金額は Google Cloud の公開価格です (2026 年 10 月時点、米ドル)。
伸びたら、速く・強く
小さく始めても、伸びたときに作り直さずに済むことが大事です。何をどの順で足すかは決めてあり、どれも今の作りのまま足せます。
| 順番 | 足すもの | 切り替えの目安 |
|---|---|---|
| 1 | 見張り: サービスが止まった・エラーが増えた・遅くなったことに気づく仕組み (外形監視・Error Reporting) | 近いうちに。費用はほとんどかかりません |
| 2 | 待機する台数と、台数の上限: しばらく使われなかった後の最初の表示も速くし、混んでも詰まらないようにする | 導入してくださるお店が増え、営業時間中ずっと使われるようになったら |
| 3 | Cloud CDN: 画面のファイルを、利用者の近くから配る仕組み。CDN から返した分はサーバまで届かないので、利用が多いほど費用も抑えられる | 実際に使うお客様が増え、画面を開く回数が多くなったら |
| 4 | 入口の守り: ロードバランサと Cloud Armor (不正なアクセスやボットを止める仕組み) | 取引の規模が大きくなり、狙われる心配が増えたら |
足したときに毎月増える費用は、公開価格から次のように試算しています (1 ドル 150 円で計算)。
| 足すもの | 毎月増える費用の目安 |
|---|---|
| 見張り | ほぼかかりません。外形監視は毎月 100 万回まで無料、Error Reporting は無料です |
| 待機する台数 | CPU 1 つ・メモリ 0.5 GiB の台を 1 台待たせて、月 $10 前後 (約 1,500 円) |
| Cloud CDN | ロードバランサが月 $18 前後 (約 2,700 円)。ほかに配った量に応じて、アジア向けは 1 GiB あたり $0.09 |
| Cloud Armor | 守りの設定 1 つで月 $5、ルール 1 つにつき月 $1。ほかにリクエスト数に応じて |
最初から全部を入れると、本番だけで月 $40 前後 (約 6,000 円) の固定費が、使われていなくてもかかり続けます。検証や体験の環境にも入れれば、その数倍です。
どれも、使ってくださるお店とお客様の増え方を見ながら、困ることが起きる前に足します。 足すときは、上のように費用も見積もったうえで決めます。Cloud Run は混み具合に応じて自動で台数を増やし、ロードバランサの後ろにもそのまま置けるので、足すときに画面や API を作り直す必要はありません。
まとめ
- 運用の手間をかけずに止まらないよう、サーバレスの Cloud Run と Firestore を選びました
- 共通の機能を 1 か所にまとめ、保守しやすくしています
- カード番号は Stripe に任せ、請求する金額はサーバが決めます
- 返金・二重払い・チャージバックなど、もめやすいところまで仕組みで受け止めます
- 誰でも試せる体験版は、本番から切り離しています
- 今は小さく安く始め、伸びたときに足すものと順番を決めています
次回は、この仕組みを少人数で速く作りながら、壊さないための開発体制を紹介します。AI のエージェントの使い方と、人が確かめているところも書く予定です。
ご意見・ご相談
構成へのご意見や、「うちの地域やイベントで使えないか」「こんな仕組みを一緒に作れないか」というご相談をお待ちしています。
旅行者・お店・町をつなぐ観光アプリ
YOKOSO PAY のご紹介を見る