fix: 延期订单超时不关闭、无法继续支付、不能作废
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
Some checks failed
构建并部署到测试环境(无 SSH) / build-and-deploy (push) Has been cancelled
- 支付宝查单把 ACQ.TRADE_NOT_EXIST 当成查单失败,恢复任务永远判为未知,订单停在待支付; 同一套餐再下单时旧单也关不掉,新单无法创建。改为按"渠道无此订单"处理,过支付截止后关闭 - 延期订单详情对未过期的待支付订单返回 qr_content,后台可展示二维码、H5 可继续支付 - 新增作废待支付订单:后台 POST /orders/:id/close、H5 POST /orders/:id/cancel;作废前先查单,已支付则按支付成功办理
This commit is contained in:
@@ -0,0 +1,31 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"testing"
|
||||
|
||||
sdkalipay "github.com/smartwalle/alipay/v3"
|
||||
)
|
||||
|
||||
func TestAlipayTradeNotExist(t *testing.T) {
|
||||
notExist := sdkalipay.Error{Code: sdkalipay.Code("40004"), SubCode: alipayTradeNotExistCode}
|
||||
tests := []struct {
|
||||
name string
|
||||
response *sdkalipay.TradeQueryRsp
|
||||
err error
|
||||
want bool
|
||||
}{
|
||||
{name: "失败响应且交易不存在", response: &sdkalipay.TradeQueryRsp{Error: notExist}, want: true},
|
||||
{name: "SDK 以错误返回交易不存在", err: fmt.Errorf("wrap: %w", ¬Exist), want: true},
|
||||
{name: "其他业务失败", response: &sdkalipay.TradeQueryRsp{Error: sdkalipay.Error{Code: sdkalipay.Code("40004"), SubCode: "ACQ.SYSTEM_ERROR"}}, want: false},
|
||||
{name: "成功响应", response: &sdkalipay.TradeQueryRsp{Error: sdkalipay.Error{Code: sdkalipay.CodeSuccess}, TradeStatus: sdkalipay.TradeStatusWaitBuyerPay}, want: false},
|
||||
{name: "网络错误", err: fmt.Errorf("dial tcp: timeout"), want: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if got := alipayTradeNotExist(tt.response, tt.err); got != tt.want {
|
||||
t.Fatalf("alipayTradeNotExist() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,7 @@ package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
stderrors "errors"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
@@ -54,6 +55,18 @@ func (a *AlipayWapAdapter) Query(ctx context.Context, request agentrecharge.Onli
|
||||
}
|
||||
startedAt := time.Now()
|
||||
response, callErr := client.TradeQuery(ctx, sdkalipay.TradeQuery{OutTradeNo: request.PaymentNo})
|
||||
// 客户没打开过支付链接时支付宝侧没有这笔交易(ACQ.TRADE_NOT_EXIST):按"渠道没有这笔订单"返回,
|
||||
// 恢复任务在过支付截止后据此关闭订单;不能当成查单失败,否则订单永远停在待支付。
|
||||
if alipayTradeNotExist(response, callErr) {
|
||||
if _, err = a.integration.Complete(ctx, attempt.IntegrationID, integrationlog.Completion{
|
||||
Result: constants.IntegrationResultSuccess, ProviderCode: alipayTradeNotExistCode,
|
||||
ResponseSummary: map[string]any{"state": agentrecharge.OnlinePaymentStateNotFound},
|
||||
DurationMS: time.Since(startedAt).Milliseconds(),
|
||||
}); err != nil {
|
||||
return agentrecharge.OnlinePaymentQueryResult{}, err
|
||||
}
|
||||
return agentrecharge.OnlinePaymentQueryResult{State: agentrecharge.OnlinePaymentStateNotFound}, nil
|
||||
}
|
||||
if callErr != nil {
|
||||
return agentrecharge.OnlinePaymentQueryResult{}, a.completeUnknown(ctx, attempt.IntegrationID, startedAt, callErr)
|
||||
}
|
||||
@@ -128,6 +141,18 @@ func (a *AlipayWapAdapter) completeUnknown(ctx context.Context, integrationID st
|
||||
return apperrors.Wrap(apperrors.CodeTimeout, cause, "支付宝支付请求结果未知")
|
||||
}
|
||||
|
||||
// alipayTradeNotExistCode 是支付宝查单"交易不存在"的业务子码。
|
||||
const alipayTradeNotExistCode = "ACQ.TRADE_NOT_EXIST"
|
||||
|
||||
// alipayTradeNotExist 判断查单结果是否为"交易不存在":SDK 可能以失败响应返回,也可能以 *Error 返回。
|
||||
func alipayTradeNotExist(response *sdkalipay.TradeQueryRsp, callErr error) bool {
|
||||
if response != nil && response.IsFailure() && response.SubCode == alipayTradeNotExistCode {
|
||||
return true
|
||||
}
|
||||
var sdkErr *sdkalipay.Error
|
||||
return stderrors.As(callErr, &sdkErr) && sdkErr != nil && sdkErr.SubCode == alipayTradeNotExistCode
|
||||
}
|
||||
|
||||
func mapAlipayTradeState(state sdkalipay.TradeStatus) string {
|
||||
switch state {
|
||||
case sdkalipay.TradeStatusSuccess, sdkalipay.TradeStatusFinished:
|
||||
|
||||
Reference in New Issue
Block a user