#DevOps#独立开发

Marketplace 分账与 Payout:平衡分录、退款追索和到账对账

收款成功不代表卖家份额已经可打款,Transfer 成功也不代表银行最终到账。本文冻结分成政策和结算批次,用多方平衡账本、准备金、稳定 Payout 身份与 UNKNOWN 对账阻止超付和重复打款。

本文要点

  • 主题聚焦:DevOps、独立开发
  • 适合人群:独立开发者、全栈工程师、AI 应用开发者
  • 核心价值:快速理解背景、实践路径、常见误区和工程建议
作者 @admin·发布于 2026年4月1日·更新于 2026年7月20日

平台收 100 美元,卖家应得 80。transfer 成功但响应丢失,worker 换 ID 重试后卖家收到 160。Charge、transfer、connected balance 和 payout 各有失败域。

AI 毛利版本化归因负责收入与 COGS,批量客户操作控制面治理批操作。本篇只管分成与打款,不把 provider 余额当总账。

冻结 sharePolicy.v1 与多币种分录

marketplace.sharePolicy.v1 绑定参与方、分成 basis/比例、tax/fee 归属、币种、舍入 owner、退款追索、reserve/hold、minimum payout、cadence、负余额规则、provider API version 与有效期;升级只影响新 allocation。

yaml
schema: marketplace.sharePolicy.v1
policy: creator-market@8
basis: CAPTURED_ITEM_NET_OF_TAX
platformShare: {percentBps: 2000}
sellerShare: {percentBps: 8000}
providerFeeOwner: PLATFORM
reserve: {percentBps: 1000, hold: P14D}
payout: {cadence: WEEKLY, minimumMinor: 5000, currency: USD}
roundingResidualOwner: PLATFORM

订单 ledger 按币种写 buyer cash、seller pending、platform revenue、tax、fee、reserve、refund/dispute 平衡腿。比例用整数最小单位,余数按 policy 分配;币种间不相抵。多币种定价与结算提供金额边界,本账本引用其 charge receipt。

Stripe Connect 可将一次 charge 与多个 transfer 用 transfer group 关联,但退款不自动撤回 transfer。Connected-account payout 再把余额移向银行;自动 payout 模式只导入权威 payout ID,不运行本地 dispatcher。

Allocation、Transfer、Payout 分层

本地 allocation 为 PAYMENT_PENDING -> CAPTURED -> ALLOCATION_READY -> ALLOCATED -> HOLDING -> TRANSFER_ELIGIBLE;退款/争议进入 RESERVE_DEBITED/RECOVERY_DUE/NEGATIVE_BALANCE。ledger 取回权威 charge receipt 后,以 CAS 匹配 order generation、policy 和 amount/currency,原子写稳定 allocation ID、平衡的 marketplaceSettlementReceipt.v1 与各方 pending/reserve 腿。Webhook 不算接受,allocation 也不表示钱已进入 connected account。

transfer batch 按 connected account、currency、cutoff 和 policy generation 固定 manifest;只选已过 hold、无 dispute 且未占用的 allocation leg。每笔使用独立 transferOperationId,走 TRANSFER_PREPARED -> TRANSFER_DISPATCHING -> TRANSFER_ACCEPTED/TRANSFER_FAILED。dispatch CAS 只预留并授权发送;接受时以权威 transfer receipt 匹配 destination、amount/currency、transfer group 和幂等身份,再原子写 connected-balance 腿。超时进入 TRANSFER_UNKNOWN,只能查询该 transfer,不能用 payout 查询、释放腿或换键重发。

Payout 是另一条 lineage。自动模式不建本地 dispatcher,只按权威 payout ID 导入 provider 状态。manual 模式只消费已接受的 connected-balance available leg,以独立 payoutOperationId 走 PAYOUT_PREPARED -> PAYOUT_DISPATCHING -> PAYOUT_ACCEPTED -> PAYOUT_PENDING -> PAYOUT_IN_TRANSIT -> PAYOUT_PAID,并映射 PAYOUT_CANCELED/PAYOUT_FAILED/PAYOUT_RETURNED。只有 dispatch 后查不到可归属 payout object/receipt 才进 PAYOUT_UNKNOWN;已受理但未到账不能伪装 UNKNOWN。transfer/payout 的 ID、幂等键和 receipt 不得复用。

每个 payout 状态只由匹配 account、payout ID、amount/currency 的权威 receipt 接受;UNKNOWN 查询同一 ID。paid 仍须与银行流水对账,canceled、failed 或 returned 原子写 reversal 腿。后到退款/dispute 不改写旧记录:先消费 reserve,不足形成 seller negative balance,新收入再抵扣。预付 Credits 账本强调客户 credits 与卖家应付款不得共用账户。

让收款、Transfer 和到账分别失败

故障矩阵注入 charge 响应丢失、重复 Webhook、allocation 并发、transfer 部分失败/超时、账户禁用、hold/dispute 竞态、manual payout 已接受后长期 pending、in_transit 延迟、canceled、UNKNOWN 回查、paid 后银行退回和自动/manual 同开。断言三条 lineage 独立,已知状态不误归 UNKNOWN,UNKNOWN 不释放余额。

门禁要求 journal 平衡率 100%,无 charge receipt 的 allocation、双 transfer、超付、未关联 operation、UNKNOWN 换键均为 0;balance transaction、allocation、transfer/connected balance、payout/银行流水未解释差额为 0,24 小时对账率至少 99.9%。上线 shadow 两周期后给内部和 5% 小额 cohort 放量,payout 自动/manual 二选一;异常时冻结新 dispatch,已付资金只用 reversal/reserve 补偿。Webhook 订阅正确性保证通知可验证,资金仍以 provider/bank receipt 为准。

Related

相关推荐