顧客向けメニュー
顧客向けメニューは、handy.cafe/{your-slug} にある公開 Web ページです。顧客はテーブルに貼られた QR コードを読み取ってここにアクセスします。このページは顧客の流れを最初から最後まで説明するので、スタッフへの案内や導入計画に役立ちます。
URL 構造
各テーブルには handy.cafe/{cafe-slug}/{table-code} 形式の固有 URL があります。QR コードには、この URL と、そのステッカーが本物であることを証明する短命トークンが含まれます。顧客が QR を読み取ると、次のようになります。
- 端末の既定ブラウザーで URL が開きます。
- ページはクラウド API に対して slug とテーブルコードを解決します。
- テーブルが
out_of_orderの場合、利用不可の案内が表示されます。 - テーブルが
idleの場合、まだスタッフが着席させていないことが説明され、サポートを呼ぶよう案内されます。 - テーブルが
in_useの場合、6 桁のセキュリティコードの入力を求められます。
セキュリティコードの検証
セキュリティコードは、その時点でそのテーブルに着席している顧客だけが注文できるようにする仕組みです。QR の写真や店外から見ただけの人が不正に注文することを防ぎます。
顧客がコードを入力すると:
- API が、テーブルに保存されているハッシュ値と照合します。
- 有効ならセッションが作成され、トークンが返されます。
- トークンは Cookie(
hc_menu_session)に保存されます。端末のローカルストレージには Bearer トークンのフォールバックも保存されます。iPhone の Safari は一部構成でサードパーティ Cookie をブロックするため、この仕組みが必要です。 - 顧客はメニューへ移動します。
セッションの有効期間は発行から 24 時間です。顧客がブラウザーを閉じて同じ端末に戻ってきても、セッションは維持され、再検証なしで再入場できます。
言語
メニューは 24 言語に対応しています: アラビア語、ドイツ語、ギリシャ語、英語、スペイン語、ペルシア語、フランス語、ヒンディー語、インドネシア語、イタリア語、日本語、韓国語、マレー語、ポーランド語、ポルトガル語、ルーマニア語、ロシア語、タイ語、タガログ語、トルコ語、ウクライナ語、ウルドゥー語、ベトナム語、中国語です。
初回訪問時、ページはブラウザーの Accept-Language ヘッダーを確認して最適な言語を選びます。顧客はメニュー上部のピッカーでいつでも言語を変更できます。選んだ言語はそのセッション中記憶されます。
商品名、説明、材料は自動翻訳されません。メニューエディターで入力した言語のまま表示されます。「カートに追加」「チェックアウト」や支払いフローのメッセージなどの UI ラベルは完全にローカライズされます。
テーマ
メニューはライトテーマとダークテーマをサポートします。既定は端末依存です。顧客の OS がダークモードなら、メニューはダークモードで開きます。上部のテーマ切り替えで、顧客はいつでも変更できます。
ブランドヘッダー
メニュー上部のヘッダーには次が表示されます。
| 要素 | 取得元 |
|---|---|
| ヘッダー画像 | 設定 > カフェテリア からアップロードしたもの(任意) |
| ロゴ | 設定 > カフェテリア からアップロードしたもの |
| 表示名 | ビジネスプロフィールから取得 |
| 住所 | ビジネスプロフィールから取得(フッターに表示) |
| 電話番号 | ビジネスプロフィールから取得(フッターに表示) |
これらを適切に設定すると、顧客に強い印象を残せます。メニューが店舗の実物サインと似ていると、顧客はブランドを認識しやすくなります。
メニューの閲覧
メニューはカテゴリごとにまとめられています。カテゴリ内では、商品がサムネイル、名前、短い説明、価格とともに表示されます。
商品をタップすると商品シートが開きます。シートには次が表示されます。
- 全体写真。
- Markdown の説明文。
- 材料欄。
- 準備時間チップ(「メニューに準備時間を表示」が有効な場合のみ)。
- 設定されていれば単位ラベル(例:
250 ml)。 - 商品に紐づく各バリアントグループの選択肢。
- 数量ステッパー。
- カートに追加 ボタン。
必須のバリアントグループがある場合、顧客が選択するまで カートに追加 ボタンは使えません。
カート
カートアイコンはどの画面からでも開けるよう、固定位置にあります。カートの内容はサイト内の移動でも保持されます。カートとメニューを行き来しても、商品が消えることはありません。
カートでは顧客が次を行えます。
- 行ごとの数量調整。
- 行の削除。
- 任意メモの追加。
- 電話番号の入力(任意)。
小計、VAT、合計はリアルタイムで表示されます。
注文の送信
チェックアウトでは、設定に応じて 1 つまたは 2 つの支払い方法が表示されます。
現金
設定でオンライン決済を無効にしている場合は、Cash のみが表示されます。顧客が注文を確定すると、その場で送信されます。商品が届いたときに、顧客はレジで支払います。
オンライン(Stripe Checkout)
オンライン決済が有効な場合、Online が選択肢として表示されます。送信時には次の流れになります。
- 注文が保留状態で作成されます。
- Stripe Checkout の client secret が返されます。
- Stripe の埋め込み UI がその場で開きます。顧客はカード情報を入力します。
- 認証が成功すると、Stripe が請求を確定し、注文は paid に移行します。
- 顧客には成功ページが表示されます。
支払いが失敗したり途中で中断された場合、注文は保留状態のまま残ります。同じセッションで再試行することも、スタッフが Orders ダッシュボードからキャンセルすることもできます。
成功ページ
送信が成功すると、顧客はレシートページに移動し、次の内容が表示されます。
- 注文番号と時刻。
- 各行の数量、バリアント、行合計。
- 小計、VAT、総計。
- 支払い方法。
- 支払い状態アイコン(現金は pending、オンラインは paid)。
- セッションを維持したままメニューに戻る「もう一度注文する」CTA。
- 「メニューへ戻る」リンク。
注文ステータスのポーリング
送信後、顧客の注文画面はステータスエンドポイントをポーリングし、厨房からの更新を反映します。スタッフが明細を preparing から ready に進めると、顧客の画面では数秒以内にその行のバッジが自動更新されます。
これは、カウンター受け取りのセルフサービスに便利です。メニューが注文完了を知らせるまで、顧客はテーブルでくつろいでいられます。
顧客ができないこと
- セキュリティコードなしではメニューを閲覧できません。検証ステップは必須です。
idleまたはout_of_orderのテーブルには注文できません。- 送信後の注文を編集またはキャンセルすることはできません。キャンセルは Orders ダッシュボードからスタッフが行います。
きれいな顧客体験のヒント
- カフェ名と、たとえば「Scan to order. Ask staff for the code.」のような明確な案内を入れた QR ステッカーを印刷してください。そうしないと、顧客が検証ステップを見逃すことがあります。
- カテゴリ名と商品名は短くしてください。名前が長いとモバイルで折り返され、画像がファーストビューから押し出されます。
- 各商品に少なくとも 1 枚は写真をアップロードしてください。画像が多いメニューは、文字だけのメニューより注文率が高くなります。
- 「メニューに準備時間を表示」は、動的推定が学習した後に有効にしてください。最初の 30 日間は静的値が実情より長すぎたり短すぎたりすることがあり、顧客にもそれが分かります。
- 開店前に、必ず自分のスマートフォンで全体の流れを試してください。本物の QR を読み取り、コードを入力し、テスト注文を行い、注文がダッシュボードに表示されることを確認します。