feat(v2): Stripe adapter 落地 RefundingProvider(session→payment_intent→Refunds.New,refund_id 作幂等键)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user