Reservation Infrastructure

予約基盤に関するポータルサイト

公開予約フロー・管理画面・API・Stripe 決済・SMS/LINE 通知・分析レポート・埋め込みウィジェットまでを備えた マルチテナント対応の予約プラットフォームです。

稼働中テナント

2

現在有効化されている店舗数

通知チャネル

メール / SMS / LINE

3 チャネル同時対応

API エンドポイント

9

公開 3 件 + 管理 6 件

決済

Stripe Checkout

Connect 対応・自動返金

Overview

この基盤の位置づけ

何ができるか

公開予約フロー、管理画面、管理 API、Stripe 決済、SMS/LINE 通知、バックアップ、監査までをまとめて提供する予約基盤です。

どう使うか

複数店舗や複数ブランドを 1 つのアプリケーションで運用しつつ、店舗ごとに予約導線・設定・顧客データを分離して使えます。

どんなサイト構築に向くか

美容室、整体・鍼灸、サロン、スクール、相談予約、来店予約など「メニューと時間枠」で受け付ける予約サイト構築に向いています。

Reservation Flow

予約フロー(公開サイト)

顧客が予約を完了するまでの一連のステップ

01

メニュー選択

テナントごとに設定されたサービス一覧から予約内容を選択。所要時間と料金を確認できます。

02

スタッフ指定

「指名なし」を含むスタッフ選択ステップ。担当メニューが設定されたスタッフのみ表示されます。

03

空き枠確認・日時選択

営業時間・休業日・既存予約・スタッフ稼働状況を考慮した空き枠をリアルタイムで表示。最小リードタイム制御付き。

04

顧客情報入力

お名前・電話番号・メールアドレス・備考を入力。顧客アカウントでログイン中は自動入力されます。

05

予約確定・確認メール

予約完了と同時に顧客へ確認メールを送信。店舗の通知メールアドレスにも同時通知します。

06

Stripe 決済(料金設定時)

メニューに料金が設定されている場合、Stripe Checkout へリダイレクト。Webhook で payment_status を更新します。

07

前日リマインド

毎朝 08:00 のスケジューラーが翌日予約者へリマインドメール / SMS / LINE を自動送信します。

08

変更・キャンセル

トークンベースで前日まで変更・キャンセル可能。キャンセル時は Stripe Refund を自動発行します。

Capability Matrix

何ができるのか

公開予約サイトとして使える機能

店舗情報ページ メニュー一覧 スタッフ指定 空き枠確認 予約作成 予約変更・キャンセル 顧客アカウント / マイページ 前日リマインド

店舗運営サイトとして使える機能

予約一覧・詳細管理 メニュー CRUD スタッフ CRUD 営業時間・休業日設定 顧客管理 売上・稼働レポート CSV エクスポート Stripe 決済設定

基盤として使える機能

マルチテナント分離 公開 API / 管理 API API トークン認証 ロールベース認可 監査ログ バックアップ / リストア SMS / LINE 通知 埋め込みウィジェット

Site Types

どういうサイト構築に利用できるか

美容室・ヘアサロン予約サイト

メニュー、スタッフ、店舗情報、空き枠確認を組み合わせて、公開予約サイトとして構築できます。

整体・鍼灸・治療院の来店予約サイト

施術メニュー単位の予約受付、顧客情報管理、前日リマインドなどを組み合わせて利用できます。

複数店舗を束ねるポータル型予約サイト

独自ドメインを分けなくても、店舗一覧から各テナントへ切り替える運用ができます。

外部システム連携を含む予約基盤

公開 API、管理 API、トークン認証、監査ログを使って周辺システムとの連携基盤としても使えます。

補足ポイント

  • ・利用者向けの公開予約導線と、運営者向けの管理機能を両方備えています。
  • ・テナントごとに予約データ、設定、メニュー、顧客を分離して運用できます。
  • ・二重予約防止、冪等制御、通知、監査など予約基盤として必要な要素を持っています。
  • ・ローカル開発、VPS 配備、将来的な SaaS 拡張を見据えた構成です。

Safety & Reliability

予約の安全性・信頼性

二重予約防止(2 層)

  • アプリ層 — 予約作成前に区間重複チェックを実施
  • DB 層 — active_slot_key に (tenant_id, active_slot_key) のユニークインデックス
  • スロット競合時は 409 を返却してリトライを促す

冪等制御(API)

  • Idempotency-Key ヘッダーで同一リクエストの重複実行を防止
  • 同一キー・同一ペイロードは初回レスポンスをリプレイ(X-Idempotent-Replay: 1)
  • 同一キー・異なるペイロードは 409 を返却

顧客データ管理

  • 電話番号をキーに同一テナント内の顧客レコードを名寄せ
  • 顧客アカウント(customer_users)でメール / 電話番号との紐づけ
  • テナント間でデータは完全分離(グローバルスコープで保護)

Notifications

通知チャネル

NotificationDispatcher が confirmed / cancelled / changed / reminder を各チャネルへ振り分けます

メール

Laravel Mail
  • 予約作成(顧客・店舗)
  • キャンセル確認
  • 日時変更確認
  • 前日リマインド

管理画面「店舗設定」から per-tenant で設定

SMS

Twilio
  • 予約作成
  • キャンセル
  • 変更
  • 前日リマインド

管理画面「店舗設定」から per-tenant で設定

LINE

LINE Messaging API
  • 予約作成
  • キャンセル
  • 変更
  • 前日リマインド

管理画面「店舗設定」から per-tenant で設定

Payment

Stripe 決済

テナントごとに Stripe キーを設定できます。 Stripe Connect を使えば connected account への直接入金も可能です。

  • メニューに料金が設定されている場合のみ決済フローが有効化される
  • Stripe Checkout セッションを発行し、予約完了画面で Stripe ホスト型ページへリダイレクト
  • checkout.session.completed Webhook で payment_status を paid に更新
  • キャンセル時に payment_status = paid であれば Stripe Refund を自動発行
  • Stripe Connect で テナントごとに connected account への直接入金が可能
  • stripe_enabled フラグで テナントごとに決済機能を個別に有効化・無効化

Admin API

管理 API

Bearer トークン認証 + ロール × ability の 2 層認可

公開 API(認証不要)

GET

/api/v1/slots

空き枠一覧(date / service_id / staff_id でフィルタ)

POST

/api/v1/reservations

予約作成(Idempotency-Key 対応)

POST

/api/v1/reservations/cancel

キャンセルトークンで予約キャンセル

管理 API(Bearer トークン必須)

GET

/api/v1/admin/reservations

reservations.read
PATCH

/api/v1/admin/reservations/{id}

reservations.write
GET

/api/v1/admin/services

services.read
POST

/api/v1/admin/services

services.write
GET

/api/v1/admin/settings

settings.read
PUT

/api/v1/admin/settings

settings.write

ロール × ability マトリクス

owner すべて(*)
manager reservations.read / write, services.read, settings.read
staff reservations.read, services.read

Analytics

分析・レポート

管理画面の「レポート」セクションで確認できます

売上レポート

月別・サービス別・スタッフ別の売上を棒グラフで可視化

稼働率レポート

時間帯別・曜日別のスロット埋まり率を分析

顧客リテンション

新規 vs リピーター・来店回数バケット

CSV エクスポート

予約一覧・顧客一覧をダウンロード

Embed

埋め込みウィジェット

外部サイトに予約フォームを iFrame で埋め込めます

iFrame ベース(Alpine.js + CSS 変数)

表示色・言語は管理画面から設定。外部サイトのデザインに合わせた調整が可能

テナント単位の CORS 管理

WidgetCors ミドルウェアが許可オリジンをテナントごとに制御

埋め込みコードスニペット

管理画面でコピーするだけで外部サイトへ設置できる HTML を生成

<iframe src="https://reservation-platform.iplusone.co.jp/widget?tenant={code}" ...></iframe>

Multi-tenant

テナント解決順

ResolveTenant ミドルウェアが以下の順で解決します

  1. 1 認証済みユーザーの tenant_id
  2. 2 サブドメイン({code}.{APP_BASE_DOMAIN})
  3. 3 X-Tenant-Code ヘッダー
  4. 4 ?tenant= クエリパラメータ(解決成功時は tenant_code Cookie に永続化)
  5. 5 tenant_code Cookie
  6. 6 未解決時は店舗選択画面へ移動

Data Isolation

テナント単位で分離されるデータ

BelongsToTenant スコープがすべてのクエリにテナントフィルタを自動付与します

shop_settings shop_holidays services staff customers customer_users reservations audit_logs api_idempotency_keys api_access_tokens

テナント登録フロー

GET /register からセルフ登録可能。 Tenant + User + ShopSetting を DB トランザクションで一括作成します。 プラットフォーム管理者は /platform-admin から全テナントを管理できます。

Operations

運用コマンド

Artisan コマンドで日常運用・メンテナンスを自動化できます

テナント管理

php artisan tenant:create {code} "{name}"
php artisan tenant:list
php artisan tenant:activate {code}
php artisan tenant:deactivate {code}

API トークン発行

php artisan tenant:token:create {email} {name} --abilities=reservations.read,...

バックアップ / リストア

php artisan tenant:backup {code}
php artisan tenant:backup {code} --disk=s3
php artisan tenant:restore {file} --code={code}

データ保持期間管理(スケジューラー自動実行)

php artisan tenant:idempotency-prune --days=7
php artisan tenant:audit-prune --days=90
php artisan tenant:send-reminders

Next Action

店舗一覧から実際の予約サイトを確認できます

各テナントの公開予約ページ・管理画面・API を実際に操作して確認できます。