feat(v2): 支付宝 adapter 落地 RefundingProvider(TradeRefund 同步退款,out_request_no=refund_id 幂等)

This commit is contained in:
wangjia
2026-07-10 17:29:59 +08:00
parent 2016c5d16e
commit cc6f8fb972
2 changed files with 170 additions and 1 deletions
+25 -1
View File
@@ -31,12 +31,36 @@ func (p *Provider) Method() string { return "alipay" }
func (p *Provider) Capabilities() provider.Capabilities {
return provider.Capabilities{
RenderTypes: []provider.RenderType{provider.RenderRedirect},
SupportsRefund: false, // 退款 P4
SupportsRefund: true, // P4:alipay.trade.refund 同步退款
SettleCurrencies: []string{"CNY"},
Regions: []string{"cn"},
}
}
// Refund 调 alipay.trade.refund(同步接口)。providerRef=out_trade_no(alipay 归位键),
// refundID 作 out_request_no(部分退款必传且须唯一稳定 → 幂等)。IsFailure()==false 即成功
// (FundChange=N 表重复退款已幂等,仍算成功)。
func (p *Provider) Refund(ctx context.Context, providerRef, refundID string, amountMinor int64, reason string) (string, provider.PaidStatus, error) {
amt, err := money.Format(amountMinor, "CNY")
if err != nil {
return "", provider.PaidFailed, err
}
rsp, err := p.client.TradeRefund(ctx, sw.TradeRefund{
OutTradeNo: providerRef,
RefundAmount: amt,
RefundReason: reason,
OutRequestNo: refundID,
})
if err != nil {
return "", provider.PaidFailed, fmt.Errorf("alipay: 退款请求失败: %w", err)
}
if rsp.IsFailure() {
return "", provider.PaidFailed, fmt.Errorf("alipay: 退款被拒: %w", rsp.Error)
}
// 退款在支付宝侧以 out_request_no 定位;refundRef 回传我方退款单号(= out_request_no)。
return refundID, provider.PaidSucceeded, nil
}
func (p *Provider) Create(_ context.Context, req provider.CreateRequest) (*provider.Session, error) {
if req.Currency != "CNY" {
return nil, fmt.Errorf("alipay: 仅支持 CNY, got %s", req.Currency)