当前线上支付流程中,PayPal/Alipay/Stripe 的支付会话和业务订单强绑定,导致以下问题:
orders/continue 曾出现支付渠道错乱,例如原 Alipay 订单继续支付时返回 Stripe 支付结果。本 PRD 用于定义当前阶段的支付网关改造目标、边界、数据模型、流程和验收标准。
当前阶段不落地独立 payment_intents 表,也不引入完整三层支付模型。
采用两层模型:
对应现有表:
原因:
Order 承担当前阶段的轻量支付意图。paying order。paying order 同一时刻只能有一个 active provider session。continue 只能继续当前 active session,或在安全条件下同渠道重建 session。payment_intents 表。payment_attempts 表。paying order。paying order。paying order 同一时刻只能有一个 active provider session。当前重点使用:
含义:
paying: 当前支付订单待支付。paid: 支付成功,业务已或可履约。cancelled: 用户取消当前支付订单,wallet deduction 已按现有流程退款/释放。三类 session 保持各自现有 enum,但网关层统一抽象为:
含义:
pending / requires_action: 用户需要打开支付页面或完成授权。processing: 渠道已受理,等待最终结果。finished / succeeded: 该渠道支付成功。expired: session 已过期。cancelled: session 被本地取消或渠道确认取消。failed: 渠道明确失败。conflicted: 渠道成功但本地 order 已取消/已支付/金额不匹配等,需要人工处理。规则:
work_tasks,并检查 active paying order。product_options 库存,创建 product_license,再创建支付订单。规则:
continue 只能继续当前 active provider session。当前阶段不设计“取消支付尝试”。
用户点击取消时,取消的是当前支付订单:
worktask 说明:
wait_pay 状态下有专门的 worktask cancel 接口。product 说明:
规则:
能力:
策略:
continue: 如果 session open,返回原 client_secret。能力限制:
timeout_express。策略:
continue: 未到 expires_at 前返回原 pay_url。out_trade_no,仍挂在同一个 order 下。out_trade_no。当前代码使用 PayPal intent = CAPTURE。
能力限制:
策略:
continue: pending/requires_action 返回原 pay_url。PaymentProcessing,不允许取消订单,不允许重建支付。用于 0 元支付或完全由钱包/礼品卡覆盖的支付。
策略:
当前系统支付渠道与币种有关:
当前金额计算与 pay_channel 有关:
amount_calc_process 中。当前阶段不做切换渠道,所以重新选择渠道时会重新创建 order,并重新计算金额、汇率、钱包抵扣。
未来如果要做“更换支付方式但保留 order”,需要重新设计 provider amount/currency 和 wallet deduction 的关系。该能力不属于本阶段目标。
第一阶段继续保留并复用现有 wallet deduction 机制。
规则:
worktask 同一时刻只能存在以下三类支付动作中的一个:
互斥判断以 worktask 为粒度,不以渠道为粒度。
不能同时存在:
建议新增领域服务:
复用入口:
worktask 的取消订单只取消当前支付订单:
如果用户要取消 worktask 本身,调用 worktask 专用取消接口。
product 有 product_license,更接近传统电商订单中心,但当前支付交互仍然是:
规则:
当前 project 流程:
结论:
Project 是招募/撮合容器,不是支付对象。ProjectRequest 是画师应征报价,不是支付对象。WorkTask 是支付对象。chooseAndCreateWorkTask 需要保证幂等和数据库锁:
project_requests。projects。第一阶段尽量不要求前端切换到全新接口。
继续保留:
语义说明:
/api/orders/continue: 继续当前 order 的 active provider session。/api/orders/cancel: 取消当前支付订单;对 worktask 不取消 worktask,对 product 按 product license cancel 逻辑处理。/api/work_tasks/paying_order: 查询当前 worktask 是否有 paying order。不新增以下接口作为当前阶段目标:
不新增持久化 PaymentIntent 层,但需要抽出支付网关服务,收敛当前分散逻辑。
建议新增:
职责:
示例方法:
职责:
示例方法:
职责:
继续使用业务 error code,不返回裸 409。
建议新增或保留:
语义:
PaymentProcessing: 支付渠道处理中,用户应等待,不允许取消或重建。PaymentSessionConflict: 多个 active provider session 或 late success 冲突。PaymentChannelNotAllowed: 当前币种或业务对象不支持该渠道。PaymentAlreadySucceeded: 订单已支付,前端应刷新业务状态。WorkTaskPaymentActionConflict: stage/full/price_change 互斥冲突。PaymentConflictRequiresManualReview: 需要人工退款/人工处理。PaymentSessionResolver。orders/continue 改为通过 resolver 决定当前渠道。验收:
PaymentProcessing。out_trade_no。WorkTaskPaymentGuard。/api/work_tasks/paying_order 基于 paying order 和 active session 返回。验收:
/api/orders/cancel 保持为取消当前支付订单。验收:
wait_pay。PaymentProcessing。ProductLicenseService::continuePayment 改为复用统一 continue 服务。验收:
验收:
ExpirePaymentSessions 不再因为 session 过期取消 order。验收:
chooseAndCreateWorkTask 增加数据库锁。验收:
wait_pay。建议新增日志和指标:
建议增加后台或内部查询能力:
payment_intents 表。payment_attempts 表。Order 作为轻量支付意图。wait_pay。wait_pay 状态下通过专门的 worktask 取消接口取消。out_trade_no;不复用旧的 Alipay out_trade_no,也不因为 session 过期创建新的业务 Order。只有当后续需要以下能力时,再考虑引入独立 payment_intents/payment_attempts 表: