fix(v2): P4 终审波——歧义渠道错误留 processing(ErrRefundRejected 哨兵)/ 拒绝fixture签名 / 错误映射测试 / GetRefund 日志

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013nMthbVEmQquxBRKb9Fj8u
This commit is contained in:
wangjia
2026-07-10 17:58:42 +08:00
parent 346004adf3
commit e26f995d7f
8 changed files with 277 additions and 6 deletions
+6 -1
View File
@@ -6,6 +6,7 @@ package alipay
import (
"context"
"errors"
"fmt"
"net/url"
"time"
@@ -55,7 +56,11 @@ func (p *Provider) Refund(ctx context.Context, providerRef, refundID string, amo
return "", provider.PaidFailed, fmt.Errorf("alipay: 退款请求失败: %w", err)
}
if rsp.IsFailure() {
return "", provider.PaidFailed, fmt.Errorf("alipay: 退款被拒: %w", rsp.Error)
// 渠道明确拒绝(如 code=40004 ACQ.TRADE_HAS_FINISHED):钱确定没退成,
// wrap ErrRefundRejected 让 gateway.Refund 能安全标 failed 释放预留额度。
// 与之相对,前面 TradeRefund 调用本身失败(超时/网络错误)不 wrap 此哨兵——
// 那种情况渠道侧是否已实际退款不确定,不能标 failed(见 item 1)。
return "", provider.PaidFailed, fmt.Errorf("alipay: 退款被拒: %w", errors.Join(provider.ErrRefundRejected, rsp.Error))
}
// 退款在支付宝侧以 out_request_no 定位;refundRef 回传我方退款单号(= out_request_no)。
return refundID, provider.PaidSucceeded, nil