fix(v2): stripe sessionToEvent 回填 SubscriptionRef(订阅首期激活主链路生产可用)
checkout.session.completed 的 sessionToEvent 从不读 sess.Subscription,导致真实 Stripe 路径下 PaidEvent.SubscriptionRef 恒为空,settle.go 的激活门(SubscriptionRef != "")恒 false,订阅创建→首付→激活链路在生产环境整体不工作。fake provider 测试 直塞 SubscriptionRef,掩盖了这个接缝。 补 sess.Subscription != nil 时回填 ID(与既有 inv.Subscription 同套路);Kind 保持 零值 EventPayment——分派门只看 SubscriptionRef,不看 Kind。新增 adapter 测试先红 后绿,验证 VerifyCallback 真实路径产出正确 SubscriptionRef。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
@@ -315,11 +315,20 @@ func sessionToEvent(sess *gostripe.CheckoutSession, raw []byte) *provider.PaidEv
|
||||
case gostripe.CheckoutSessionPaymentStatusUnpaid:
|
||||
status = provider.PaidPending
|
||||
}
|
||||
return &provider.PaidEvent{
|
||||
ev := &provider.PaidEvent{
|
||||
ProviderRef: sess.ID,
|
||||
Status: status,
|
||||
PaidAmountMinor: sess.AmountTotal, // cent
|
||||
PaidCurrency: strings.ToUpper(string(sess.Currency)),
|
||||
Raw: string(raw),
|
||||
}
|
||||
// mode=subscription 的 Checkout 完成时,sess.Subscription 必被 Stripe 填充
|
||||
// (*Subscription;字符串 id 会 unmarshal 成 &Subscription{ID:...})。一次性单
|
||||
// (mode=payment)天然为 nil,不影响既有语义。Kind 保持零值 EventPayment——本仓
|
||||
// 分派门(settle.go)靠 SubscriptionRef != "" 而非 Kind 判断是否触发订阅激活,
|
||||
// 见 internal/gateway/settle.go 的 onSubscriptionActivated 调用点。
|
||||
if sess.Subscription != nil {
|
||||
ev.SubscriptionRef = sess.Subscription.ID
|
||||
}
|
||||
return ev
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user