首页 / 业务功能与流程 / 支付与订阅开通流程
支付与订阅开通流程
Checkout 会话、支付尝试、异步通知、对账与订阅激活的完整流程。
流程总览
App 下单 → 创建 Checkout 会话 → 创建支付尝试 → 跳转提供商 → 支付
→ 提供商异步通知 → 校验/幂等 → 订单支付成功 → 订阅激活 → Seat 占用
→ 对账(定期)→ 未知状态恢复(补偿)
涉及 pay 模块事实分层(订单/尝试/通知/对账)与 subscription 模块激活链路,与绑定 Saga 联动。
Checkout 与支付尝试
- App 调用
AppPayCheckoutController创建 Checkout 会话(PayCheckoutService.createCheckout:用户、类型、金额、产品映射) - 按
PayProductMappingService选择提供商渠道(PayProviderAccountService维护渠道账户) - 创建支付尝试(
PayAttemptPersistenceService / createAttempt),生成客户端幂等键与提供商幂等键 - 返回支付地址/凭证;
PayReturnUrlValidator校验回跳地址合法性 - 用户完成支付,App 可选
verifyStoreTransaction校验门店交易
异步通知与状态迁移
- 提供商回调进入
PayProviderWebhookController:验签 + 幂等(attempt 幂等键) - 通知事实落表,
PayNotifyJob驱动订单/尝试状态迁移 - 订单支付成功 → 发布订阅激活事件(绑定 Saga 的
paid.activation.requested或独立激活链路) - 通知失败进重试;超过阈值由
PayUnknownAttemptRecoveryJob主动查询提供商
回调处理必须验签 + 幂等;处理失败进重试/Outbox,不直接修改业务行伪造成功。
订阅激活
- 支付成功事件触发订阅激活(
subscription.paid.activation.requested) - Subscription 执行
handlePaidActivationRequested:创建/更新subscription_active、记录subscription_record - 占用
subscription_seat(session/device guard 唯一) - 回发
paid.activation-completed,绑定流程继续;到期由SubscriptionExpireJob处理过期
对账与未知状态恢复
| 机制 | 实现 | 说明 |
|---|---|---|
| 结算对账 | PaySettlementReconciliationJob | 定期以提供商流水核对订单/结算 |
| 差异 case | PayReconciliationCaseJob + ReconciliationCaseService | 差异生成 case 人工/自动处理 |
| 未知尝试恢复 | PayUnknownAttemptRecoveryJob | 超时未回调尝试主动查询恢复 |
| 订单过期 | PayOrderExpireJob | 超时未支付订单关闭 |
| 提供商事件/资源 | PayProviderEventJob、PayProviderResourceSyncJob | 同步提供商事件与资源状态 |
事实表与状态机
| 事实 | 状态机(示例) | 唯一约束 |
|---|---|---|
| Checkout 会话 | CREATED → ATTEMPT_CREATED → PAID / EXPIRED / CANCELLED | 会话 ID 唯一 |
| 支付订单 | CREATED → WAITING → SUCCESS / FAILED / CLOSED | 租户订单号、app_id+merchant_order_id |
| 支付尝试 | CREATED → PROCESSING → SUCCESS / FAILED / UNKNOWN | 公开 attempt ID、客户端/提供商幂等键 |
| 订阅 active | PENDING → ACTIVE → EXPIRED / CANCELLED / TRANSFERRED | 主体 + 产品组合 |