fix(v2): 订阅激活门改按结算结果(unpaid session 不再无付款激活)

HandleCallback 原门 serr==nil && SubscriptionRef!="" 挡不住 Settle() 对非
PaidSucceeded 事件返回 (SettleIgnored, nil) 的情况(如 Stripe
checkout.session.completed 异步支付 payment_status=unpaid),导致
onSubscriptionActivated 无确认付款先激活订阅。改为按结算结果开门
(SettleProcessed/SettleDuplicate),并在 onSubscriptionActivated 内加
o.Status.Settled() 纵深防御。
This commit is contained in:
wangjia
2026-07-10 18:09:56 +08:00
parent c677d64529
commit b8bdb2c193
3 changed files with 55 additions and 1 deletions
+7
View File
@@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"log"
"time"
"github.com/wangjia/pay/internal/model"
@@ -107,6 +108,12 @@ func (g *Gateway) onSubscriptionActivated(ctx context.Context, ev *provider.Paid
if err != nil {
return err
}
if !o.Status.Settled() {
// 纵深防御:HandleCallback 的门(res==Processed/Duplicate)已挡住未结算订单,
// 这里再核一遍订单状态,防止未来调用点绕过门直接调用本函数。
log.Printf("[subscription] onSubscriptionActivated 订单未结算 out_trade_no=%s status=%s,拒绝激活", o.OutTradeNo, o.Status)
return nil
}
subID := "SUB-" + att.OutTradeNo // 与 CreateSubscription 同式派生 → 重投算出同一 SubID,Create 幂等
created, err := g.subs.Create(&model.Subscription{
SubID: subID, OutTradeNo: o.OutTradeNo, BizSystem: o.BizSystem, BizRef: o.BizRef, BizCode: o.BizCode,