Checkout 一次性支付 + 订阅续费怎么配
想省事又稳,直接用 Stripe Checkout。一次性收款就把 Session 的 mode 设成 payment;订阅续费把 mode 设成 subscription,line_items 里放你在后台建好的 Price(一个是单次 Price,一个是 recurring Price,别混用)。
实操里我建议你把 order_id / user_id 写进 metadata。比如用户买 49 美元课程(一次性)或 19 美元/月会员(订阅),支付页跳转成功不算“订单完成”,真正的落库以 Webhook 为准,避免用户关页、网络抖动导致漏单。
Webhook 回调:收款、续费、退款、拒付都靠它闭环
Stripe 的 Webhook 是“至少送达一次”,同一事件会重试。你要做两件事:验签 + 幂等。
- 验签:用端点的 webhook secret 校验 Stripe-Signature,校验不过就直接 400。
- 幂等:把 event.id 存库并加唯一约束,已处理过就返回 200,别重复发货/开通会员。
事件建议至少覆盖这些:payment_intent.succeeded(一次性支付成功)、invoice.paid / invoice.payment_succeeded(订阅续费成功)、customer.subscription.updated(升降级/到期状态变化)、charge.refunded(退款完成)、charge.dispute.created(拒付/争议创建)。Stripe 端点失败会持续重试,常见最长可到 72 小时,所以你的处理逻辑要“快进快出”,耗时任务丢队列。
对账报表导出:别等财务来追你
日常对账别只看 Dashboard 的余额变化,建议固定导出两类数据做核对:Payout(打款批次)+ Balance transactions(每笔费用/退款/争议的明细)。你可以在后台手动导出 CSV,也可以用 API 拉取后进你的 BI。
一个很实用的做法:你的订单表存 payment_intent、订阅表存 subscription、发票表存 invoice。财务对账时用这些 ID 一一映射,能把“少记一笔手续费”这种坑直接抹平。
退款/拒付处理 + 风控设置:把损失压到可控
退款用 Dashboard 点也行,但系统化一定要吃 charge.refunded:收到事件就把订单改成已退款,并回收权益(会员到期时间回滚、课程权限关闭)。
拒付要更敏感。行业里常用红线是 1% 的拒付率会被视为高风险,部分卡组织在 1.5% 会进入监控并可能罚款。你可以在 2026 年的策略里这样配:
- 启用 Radar 基础规则,叠加你自己的黑名单(高风险国家/邮箱域名/异常 IP)。
- 对高客单(比如 ≥ 200 美元)打开更强的 3DS 策略,减少“未授权”拒付。
- 账单描述符写清楚:让用户在账单上能一眼认出你,能少掉一大批“我不认识这笔扣款”的友好欺诈。
可执行建议:今天就做三件事——把 order_id 写进 metadata、Webhook 端做 event.id 幂等表、把 dispute.created 加到告警(邮件/工单都行)。这三步落地后,一次性支付、订阅续费、退款和拒付基本就能自动闭环了。