feat(v2): 支付宝 adapter 落地 RefundingProvider(TradeRefund 同步退款,out_request_no=refund_id 幂等)
This commit is contained in:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user