QuickClick / Collect Checkout 集成版|用于 Celoria 预约完成后收取定金
目标:用户线上预约完成后,必须完成定金支付,预约才进入已确认状态。
Test Mode,再切生产。QuickClick 客户端支付链路可跑通,测试交易 ID 11772491727,金额 1.23 USD,状态 Approved。
/booking/{store}/success?appointment_id=...。POST /api/public/booking/deposit-payment-link。business.require_deposit 且百分比有效则按比例)。UP_PAYMENT_URL_TEMPLATE 生成 UP Hosted/QuickClick 支付链接并返回。当前版本重点是“预约后可在线收款跳转”。支付结果回写(Webhook/验单自动更新预约状态)可在下一阶段补齐。
flowchart TD
A["用户提交预约"] --> B["Backend 创建 appointment
status=awaiting_deposit"]
B --> C["Backend 创建 deposit_payment 记录
status=pending"]
C --> D["Backend 生成托管支付链接
(QuickClick/Collect Checkout)"]
D --> E["前端展示并跳转支付页"]
E --> F{"用户操作"}
F -- "支付成功" --> G["网关返回 successUrl + transaction_id"]
F -- "取消/关闭页面" --> H["回到 cancelUrl 或无回跳"]
G --> I["Backend Query API 二次验单
状态/金额/订单号一致性校验"]
I --> J{"验单通过?"}
J -- "是" --> K["deposit_payment=paid
appointment=confirmed"]
J -- "否" --> L["deposit_payment=verification_failed"]
H --> M["保持 awaiting_deposit,等待重试/超时取消"]
N["Webhook: transaction.sale.success"] --> I
M --> O["超时任务扫描"]
O --> P["appointment=deposit_expired 或 canceled"]
stateDiagram-v2
[*] --> draft
draft --> awaiting_deposit: 用户提交预约
awaiting_deposit --> deposit_paid: 支付成功且验单通过
awaiting_deposit --> deposit_failed: 支付失败/验单失败
awaiting_deposit --> deposit_expired: 支付超时
deposit_failed --> awaiting_deposit: 用户重试支付
deposit_paid --> confirmed: 系统确认预约
deposit_expired --> canceled
confirmed --> [*]
canceled --> [*]
stateDiagram-v2
[*] --> pending
pending --> paid: Query API verify success
pending --> failed: 网关明确失败
pending --> canceled: 用户取消
pending --> expired: 超时
pending --> verification_failed: 回跳成功但验单不通过
failed --> pending: 发起重试(新支付链接)
canceled --> pending: 发起重试(新支付链接)
verification_failed --> pending: 发起重试(新支付链接)
paid --> [*]
expired --> [*]
sequenceDiagram
participant U as 用户
participant FE as Web App
participant BE as Celoria Backend
participant GW as UP Gateway
U->>FE: 提交预约
FE->>BE: POST /api/appointments (含定金要求)
BE->>BE: 创建 appointment + deposit_payment(pending)
BE-->>FE: payment_url + payment_ref
FE->>GW: 跳转 payment_url
U->>GW: 输入卡信息并支付
GW-->>FE: successUrl?transaction_id=xxx
FE->>BE: POST /api/payments/deposit/confirm (transaction_id, payment_ref)
BE->>GW: POST /api/query.php (security_key + transaction_id)
GW-->>BE: transaction status/amount/order info
BE->>BE: 验证通过后更新状态
BE-->>FE: confirmed
GW-->>BE: webhook(transaction.sale.success) 作为兜底
| 字段 | 说明 |
|---|---|
id |
预约主键 |
status |
awaiting_deposit / confirmed / deposit_expired / canceled |
deposit_amount |
应付定金金额 |
| 字段 | 说明 |
|---|---|
id |
支付单主键 |
appointment_id |
关联预约 |
tenant_id |
租户隔离键 |
amount |
定金金额 |
status |
pending/paid/failed/canceled/expired/verification_failed |
gateway_provider |
universal_processing |
gateway_txn_id |
网关交易号(如 11772491727) |
payment_url |
发给用户的托管支付链接 |
expires_at |
支付超时时间 |
| 接口 | 职责 |
|---|---|
POST /api/appointments |
创建预约并生成定金支付单 + 支付链接 |
POST /api/payments/deposit/confirm |
处理 successUrl 回跳,执行 Query API 二次验单 |
POST /api/payments/up/webhook |
接收网关 webhook,做异步补偿与最终一致性 |
POST /api/payments/deposit/retry |
支付失败或取消后重新生成新链接 |
gateway_txn_id + tenant_id 建唯一约束,避免重复入账。deposit_payment.id 只允许从 pending 单向进入终态。awaiting_deposit 变 confirmed。awaiting_deposit 并允许重试。Test Mode = Disabled、配置 Private API Key、配置 Webhook Endpoint、校验 URL Allowlist。