feat(v2): Stripe adapter 落地 RefundingProvider(session→payment_intent→Refunds.New,refund_id 作幂等键)

This commit is contained in:
wangjia
2026-07-10 17:32:58 +08:00
parent cc6f8fb972
commit 12c1a747db
2 changed files with 89 additions and 1 deletions
+34 -1
View File
@@ -42,12 +42,45 @@ func (p *Provider) Method() string { return "stripe" }
func (p *Provider) Capabilities() provider.Capabilities {
return provider.Capabilities{
RenderTypes: []provider.RenderType{provider.RenderRedirect},
SupportsRefund: false, // P4
SupportsRefund: true, // P4:/v1/refunds
SettleCurrencies: []string{supportedCurrency},
Regions: []string{"global"},
}
}
// Refund 经 Checkout Session 取 PaymentIntent 再退款。refundID 作 Idempotency-Key。
// 不传 Stripe Reason(仅收枚举);业务文案只落 pay 本地。
func (p *Provider) Refund(_ context.Context, providerRef, refundID string, amountMinor int64, _ string) (string, provider.PaidStatus, error) {
sess, err := p.sc.CheckoutSessions.Get(providerRef, nil)
if err != nil {
return "", provider.PaidFailed, fmt.Errorf("stripe: 取 session 失败: %w", err)
}
if sess.PaymentIntent == nil || sess.PaymentIntent.ID == "" {
return "", provider.PaidFailed, fmt.Errorf("stripe: session %s 无 payment_intent,无法退款", providerRef)
}
params := &gostripe.RefundParams{
PaymentIntent: gostripe.String(sess.PaymentIntent.ID),
Amount: gostripe.Int64(amountMinor), // cent = USD minor,直传
}
params.SetIdempotencyKey(refundID)
rf, err := p.sc.Refunds.New(params)
if err != nil {
return "", provider.PaidFailed, fmt.Errorf("stripe: 退款请求失败: %w", err)
}
return rf.ID, mapRefundStatus(rf.Status), nil
}
func mapRefundStatus(s gostripe.RefundStatus) provider.PaidStatus {
switch s {
case gostripe.RefundStatusSucceeded:
return provider.PaidSucceeded
case gostripe.RefundStatusFailed, gostripe.RefundStatusCanceled:
return provider.PaidFailed
default: // pending / requires_action → 异步,交上层保持 processing
return provider.PaidPending
}
}
func (p *Provider) Create(_ context.Context, req provider.CreateRequest) (*provider.Session, error) {
if req.Currency != supportedCurrency {
return nil, fmt.Errorf("stripe: 仅支持 %s, got %s", supportedCurrency, req.Currency)