f
This commit is contained in:
@@ -7,6 +7,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"os"
|
||||
"strings"
|
||||
"time"
|
||||
"tyc-server/app/main/api/internal/svc"
|
||||
"tyc-server/app/main/api/internal/types"
|
||||
@@ -35,6 +36,21 @@ type PaymentTypeResp struct {
|
||||
payMerchantID string
|
||||
}
|
||||
|
||||
// prepayDataMissing 判断第三方支付预创建是否未返回可用参数(含 interface 包了一层 nil 的情况)
|
||||
func prepayDataMissing(v interface{}) bool {
|
||||
if v == nil {
|
||||
return true
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return t == ""
|
||||
case map[string]string:
|
||||
return len(t) == 0
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLogic {
|
||||
return &PaymentLogic{
|
||||
Logger: logx.WithContext(ctx),
|
||||
@@ -44,6 +60,10 @@ func NewPaymentLogic(ctx context.Context, svcCtx *svc.ServiceContext) *PaymentLo
|
||||
}
|
||||
|
||||
func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp, err error) {
|
||||
req.PayMethod = strings.TrimSpace(req.PayMethod)
|
||||
req.PayType = strings.TrimSpace(req.PayType)
|
||||
req.Id = strings.TrimSpace(req.Id)
|
||||
|
||||
var paymentTypeResp *PaymentTypeResp
|
||||
var prepayData interface{}
|
||||
l.svcCtx.OrderModel.Trans(l.ctx, func(ctx context.Context, session sqlx.Session) error {
|
||||
@@ -90,6 +110,21 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
if createOrderErr != nil {
|
||||
return errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "生成订单, 创建支付订单失败: %+v", createOrderErr)
|
||||
}
|
||||
// 在事务内校验并失败则回滚,避免订单已落库却无 prepay(此前仅事务外校验会产生脏订单)
|
||||
if req.PayMethod == "wechat" || req.PayMethod == "alipay" {
|
||||
if prepayDataMissing(prepayData) {
|
||||
platformVal := l.ctx.Value("platform")
|
||||
logx.WithContext(l.ctx).Errorf(
|
||||
"[Payment] 事务内 prepay 为空将回滚: pay_method=%q pay_type=%q order_no=%s platform=%v prepayData_type=%T",
|
||||
req.PayMethod, req.PayType, paymentTypeResp.outTradeNo, platformVal, prepayData,
|
||||
)
|
||||
return errors.Wrapf(
|
||||
xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, "获取支付参数失败,请确认在微信内打开且已完成网页授权后重试"),
|
||||
"创建支付失败: prepay 为空 platform=%v",
|
||||
platformVal,
|
||||
)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
@@ -97,8 +132,13 @@ func (l *PaymentLogic) Payment(req *types.PaymentReq) (resp *types.PaymentResp,
|
||||
}
|
||||
|
||||
if req.PayMethod == "wechat" || req.PayMethod == "alipay" {
|
||||
if prepayData == nil {
|
||||
return nil, errors.Wrapf(xerr.NewErrCode(xerr.SERVER_COMMON_ERROR), "创建支付失败: 未生成支付参数")
|
||||
if prepayDataMissing(prepayData) {
|
||||
logx.WithContext(l.ctx).Errorf("[Payment] 事务提交后 prepay 仍为空(不应出现): pay_method=%q id=%q platform=%v",
|
||||
req.PayMethod, req.Id, l.ctx.Value("platform"))
|
||||
return nil, errors.Wrapf(
|
||||
xerr.NewErrCodeMsg(xerr.SERVER_COMMON_ERROR, "获取支付参数失败,请稍后重试"),
|
||||
"创建支付失败: 未生成支付参数",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package middleware
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
const (
|
||||
@@ -12,7 +13,7 @@ const (
|
||||
func GlobalSourceInterceptor(next http.HandlerFunc) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
// 获取请求头 X-Platform 的值
|
||||
platform := r.Header.Get(PlatformKey)
|
||||
platform := strings.TrimSpace(r.Header.Get(PlatformKey))
|
||||
|
||||
// 将值放入新的 context 中
|
||||
ctx := r.Context()
|
||||
|
||||
@@ -5,6 +5,7 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
"tyc-server/app/main/api/internal/config"
|
||||
"tyc-server/app/main/model"
|
||||
@@ -273,10 +274,14 @@ func (w *WechatPayService) CreateWechatH5Order(ctx context.Context, amount float
|
||||
func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64, description string, outTradeNo string) (interface{}, error) {
|
||||
platformVal := ctx.Value("platform")
|
||||
platform, ok := platformVal.(string)
|
||||
platform = strings.TrimSpace(platform)
|
||||
if !ok || platform == "" {
|
||||
logx.WithContext(ctx).Errorf("[WechatPay] CreateWechatOrder 缺少 X-Platform")
|
||||
return "", fmt.Errorf("缺少 X-Platform 请求头(微信内请传 wxh5)")
|
||||
}
|
||||
|
||||
logx.WithContext(ctx).Infof("[WechatPay] CreateWechatOrder platform=%q out_trade_no=%s", platform, outTradeNo)
|
||||
|
||||
var prepayData interface{}
|
||||
var err error
|
||||
|
||||
@@ -319,6 +324,10 @@ func (w *WechatPayService) CreateWechatOrder(ctx context.Context, amount float64
|
||||
return "", fmt.Errorf("支付订单创建失败: %v", err)
|
||||
}
|
||||
|
||||
if prepayData == nil {
|
||||
logx.WithContext(ctx).Errorf("[WechatPay] CreateWechatOrder 返回 prepayData 为 nil platform=%q", platform)
|
||||
}
|
||||
|
||||
// 返回预支付ID
|
||||
return prepayData, nil
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user