feat:记录上游返回订单交易金额

This commit is contained in:
wolter 2026-02-25 11:18:32 +08:00
parent a829be47d5
commit e043564e96
7 changed files with 117 additions and 14 deletions

View File

@ -87,7 +87,7 @@ func closeOrder() {
} }
orderIds = append(orderIds, orderInfo.Id) orderIds = append(orderIds, orderInfo.Id)
// 回调通知下游 // 回调通知下游
notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, response.Code, common.ORDER_STATUS_CLOSE, 0, "长时间未支付关闭订单") notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, response.Code, common.ORDER_STATUS_CLOSE, 0, 0, "长时间未支付关闭订单")
//utils.Log(nil, "主动查询订单支付状态,回调下游", notifyResult) //utils.Log(nil, "主动查询订单支付状态,回调下游", notifyResult)
if notifyResult.ErrCode != errorcode.Success { if notifyResult.ErrCode != errorcode.Success {
utils.Log(nil, "关闭订单,回调下游失败", fmt.Sprintf("%#v", notifyResult)) utils.Log(nil, "关闭订单,回调下游失败", fmt.Sprintf("%#v", notifyResult))
@ -305,7 +305,7 @@ func queryRefundOrder() {
msg = "退款失败" msg = "退款失败"
} }
// 回调通知下游 todo // 回调通知下游 todo
notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, result.Code, status, int(result.Result.RefundFee), msg) notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, result.Code, status, int(result.Result.RefundFee), int(result.Result.RefundFee), msg)
//utils.Log(nil, "主动查询退款订单状态,回调下游", notifyResult) //utils.Log(nil, "主动查询退款订单状态,回调下游", notifyResult)
if notifyResult.ErrCode != errorcode.Success { if notifyResult.ErrCode != errorcode.Success {
utils.Log(nil, "查询退款订单状态,回调下游失败", notifyResult) utils.Log(nil, "查询退款订单状态,回调下游失败", notifyResult)

View File

@ -21,6 +21,7 @@ type Orders struct {
OrderType int `xorm:"'order_type' TINYINT"` OrderType int `xorm:"'order_type' TINYINT"`
RefundOrderId int64 `xorm:"'refund_order_id' bigint(20)"` RefundOrderId int64 `xorm:"'refund_order_id' bigint(20)"`
Amount int `xorm:"'amount' int(11)"` Amount int `xorm:"'amount' int(11)"`
ActualAmount int `xorm:"'actual_amount' int(11)"`
PayerTotal int `xorm:"'payer_total' int(11)"` PayerTotal int `xorm:"'payer_total' int(11)"`
ExtJson string `xorm:"'ext_json' varchar(1024)"` ExtJson string `xorm:"'ext_json' varchar(1024)"`
Desc string `xorm:"'desc' varchar(100)"` Desc string `xorm:"'desc' varchar(100)"`

View File

@ -73,7 +73,7 @@ func OrderQueryAndNotify(ctx context.Context, orderInfo *ordersmodel.OrdersLeftP
msg = "订单关闭" msg = "订单关闭"
} }
// 回调通知下游 // 回调通知下游
notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, result.Code, status, int(result.Result.PayerTotal), msg) notifyResult := thirdpay_notify.NewOrderNotifyWithHandle(orderInfo.Id, result.Code, status, int(result.Result.AmountTotal), int(result.Result.PayerTotal), msg)
//utils.Log(nil, "主动查询订单支付状态,回调下游", notifyResult) //utils.Log(nil, "主动查询订单支付状态,回调下游", notifyResult)
if notifyResult.ErrCode != errorcode.Success { if notifyResult.ErrCode != errorcode.Success {
utils.Log(nil, "主动查询订单支付状态,回调下游失败", fmt.Sprintf("%+v", notifyResult)) utils.Log(nil, "主动查询订单支付状态,回调下游失败", fmt.Sprintf("%+v", notifyResult))

View File

@ -23,7 +23,8 @@ type OrderNotify struct {
OrderId int64 OrderId int64
Status int //订单状态 Status int //订单状态
ActualAmount int ActualAmount int // 支付上游返回的订单金额,单位为分。该参数的值为支付时传入的
PayerTotal int // 用户实际支付金额,单位为分
Msg string Msg string
CompleteTime time.Time CompleteTime time.Time
} }
@ -51,13 +52,16 @@ type OrderNotifySendContent struct {
PayerTotal int `json:"payer_total"` PayerTotal int `json:"payer_total"`
} }
func NewOrderNotifyWithHandle(orderId int64, code int, Status int, actualAmount int, msg string) *OrderNotifyResp { // actualAmount 订单支付总金额,支付时传入
// payerTotal 用户实际支付金额有优惠券的情况下payerTotal = actualAmount - 优惠金额)
func NewOrderNotifyWithHandle(orderId int64, code int, Status int, actualAmount int, payerTotal int, msg string) *OrderNotifyResp {
orderNotify := &OrderNotify{ orderNotify := &OrderNotify{
OrderId: orderId, OrderId: orderId,
Status: Status, Status: Status,
ActualAmount: actualAmount, ActualAmount: actualAmount,
Msg: msg, Msg: msg,
Code: code, Code: code,
PayerTotal: payerTotal,
} }
return orderNotify.Handle() return orderNotify.Handle()
} }
@ -164,7 +168,7 @@ func (o *OrderNotify) setBody() *OrderNotifySendContent {
AppId: o.order.AppId, AppId: o.order.AppId,
ChannelId: o.order.PayChannelId, ChannelId: o.order.PayChannelId,
//MerchantId: o.order.MerchantId, //MerchantId: o.order.MerchantId,
Amount: o.order.Amount, Amount: o.order.ActualAmount, // 订单支付总金额,支付时传入
PayerTotal: o.order.PayerTotal, PayerTotal: o.order.PayerTotal,
} }
} }
@ -175,8 +179,13 @@ func (o *OrderNotify) updateOrder() {
o.Code = errorcode.OrderStatusErr o.Code = errorcode.OrderStatusErr
return return
} }
// 支付金额和上游支付金额不一致,记录日志
if o.order.Amount != o.ActualAmount {
utils.Log(nil, "支付金额和上游支付金额不一致", o.order.Id, o.order.Amount, o.ActualAmount)
}
o.order.Status = o.Status o.order.Status = o.Status
o.order.PayerTotal = o.ActualAmount o.order.ActualAmount = o.ActualAmount
o.order.PayerTotal = o.PayerTotal
o.Code = services.OrderUpdate(o.order, "status") o.Code = services.OrderUpdate(o.order, "status")
return return
} }

View File

@ -155,7 +155,7 @@ func ALiCallBack(notifyReq gopay.BodyMap, aliConfig AliPay) error {
// 拼装数据触发下游回调,触发下游回调 // 拼装数据触发下游回调,触发下游回调
orderId, _ := strconv.Atoi(notifyReq.Get("out_trade_no")) orderId, _ := strconv.Atoi(notifyReq.Get("out_trade_no"))
buyerPayAmount := notifyReq.Get("buyer_pay_amount") // 单位为元 buyerPayAmount := notifyReq.Get("buyer_pay_amount") // 单位为元 //buyer_pay_amount 用户在交易中支付的金额。
// 将字符串转换为浮点数,转为分 // 将字符串转换为浮点数,转为分
buyerPayAmountFloat, err := strconv.ParseFloat(buyerPayAmount, 64) buyerPayAmountFloat, err := strconv.ParseFloat(buyerPayAmount, 64)
if err != nil { if err != nil {
@ -164,6 +164,15 @@ func ALiCallBack(notifyReq gopay.BodyMap, aliConfig AliPay) error {
} }
payerTotal := int(buyerPayAmountFloat * 100) payerTotal := int(buyerPayAmountFloat * 100)
totalAmount := notifyReq.Get("total_amount") // 单位为元 //total_amount 本次交易支付的订单金额,单位为人民币(元)
// 将字符串转换为浮点数,转为分
amountTotalFloat, err := strconv.ParseFloat(totalAmount, 64)
if err != nil {
logger.Error(context.Background(), "ALiCallBack 发生错误", fmt.Sprintf("回调时,金额转换失败,失败原因:%s", err.Error()))
return err
}
amountTotal := int(amountTotalFloat * 100)
// 订单状态 // 订单状态
tradeStatus := notifyReq.Get("trade_status") tradeStatus := notifyReq.Get("trade_status")
errCode := 0 errCode := 0
@ -187,7 +196,7 @@ func ALiCallBack(notifyReq gopay.BodyMap, aliConfig AliPay) error {
return errors.New("订单状态异常,无法进行后续回调") return errors.New("订单状态异常,无法进行后续回调")
} }
res := thirdpay_notify.NewOrderNotifyWithHandle(int64(orderId), errCode, orderStatus, payerTotal, msg) res := thirdpay_notify.NewOrderNotifyWithHandle(int64(orderId), errCode, orderStatus, amountTotal, payerTotal, msg)
merchantCallback, _ := json.Marshal(res) merchantCallback, _ := json.Marshal(res)
// 记录日志 // 记录日志
go func() { go func() {
@ -249,8 +258,8 @@ func ALiOrderQuery(ctx context.Context, aliConfig AliPay, OrderNo string) (PayOr
tradeStateDesc = "未付款交易超时关闭,或支付完成后全额退款" tradeStateDesc = "未付款交易超时关闭,或支付完成后全额退款"
} }
amountTotal, _ := strconv.ParseFloat(aliRsp.Response.TotalAmount, 64) amountTotal, _ := strconv.ParseFloat(aliRsp.Response.TotalAmount, 64) // total_amount 本次交易支付的订单金额,单位为人民币(元)
payerTotal, _ := strconv.ParseFloat(aliRsp.Response.BuyerPayAmount, 64) payerTotal, _ := strconv.ParseFloat(aliRsp.Response.BuyerPayAmount, 64) //buyer_pay_amount 用户在交易中支付的金额。
// 构建数据 // 构建数据
outTradeNo, _ := strconv.Atoi(aliRsp.Response.OutTradeNo) outTradeNo, _ := strconv.Atoi(aliRsp.Response.OutTradeNo)
return PayOrderQueryInfo{ return PayOrderQueryInfo{

View File

@ -468,3 +468,87 @@ func TestWechatJSAPIPaymentService(t *testing.T) {
//t.Log(closeResutl) //t.Log(closeResutl)
} }
// 微信 小程序支付
func TestWechatMiniPaymentService(t *testing.T) {
var err error
c := context.Background()
//解析启动命令
opts := config.GetOptions()
if opts.ShowVersion {
fmt.Printf("%s\ncommit %s\nbuilt on %s\n", server.Version, server.BuildCommit, server.BuildDate)
os.Exit(0)
}
//加载配置
opts.ConfFile = "../../../.env"
_, err = config.Load(opts.ConfFile)
if err != nil {
return
}
////引导程序
//err = bootstrap.Bootstrap(conf)
//if err != nil {
// return
//}
data := `{"api_v_3_key": "", "mch_id": "" `
wechat := backend.WechatPayChannel{}
err = json.Unmarshal([]byte(data), &wechat)
if err != nil {
fmt.Println(err)
return
}
request := PayOrderRequest{
PayChannelId: 189140128377123531,
OrderId: 345812382113322,
ChannelType: payCommon.PAY_CHANNEL_WECHAT_MINI,
Description: "测试商品",
Amount: 1,
PayerClientIp: "192.168.110.235",
//Wx: WxPay{
// AppId: "wx0a9d03516e77308c",
// MchId: "1647084265",
// SerialNo: "318457037183AFED5B9A55C129007D9EFE737B18",
// ApiV3Key: "lsxdtvR2vOgGBu03u6wA0j9RnX5IP1Yq",
// //PrivateKey: "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC7TG44IkSH7c/c\nFJ0+dTvcA9uYPdyIRFGRmtRBVEMP0S9q9MoVAuEeQ0/yxLmTmKb7/kAwShqNbwDU\niIm0y9b1jMpl1NM3lvEG5+LL1xMYKIRh2iOInoZSYpX46l5ME7FQwUq4GyoTg+5o\naIUKHXtzldzUR8/MXnpljYKL1oKb04vA627EMiUNm+Hajt4elhm3UXmOva1ohir7\nb69NEeleM4wjCxG+7ueuFIXlWqeAmXjYKb36C6xOeLbdlQeNg3BSEXmGFI5mDxM4\nlGf+zVWc5KcH9YVsq5D0UIziVHMUC91Za48fUgYjFb3Dho00IEjUqQwKuzCbZtkq\nD9mJ/0FRAgMBAAECggEAc4FO948qdClUZoTP9BSYNbarVdfQiLiZFRJGk4NDWB3J\nAEy10v9TlTYtt6laSIt7byv8qcsJVO9/s5IAWl7a0dNhfishlsafHYMjelHIlL1n\n5nCAOWCJtYTWuArQ3FnIn+SUD7Ww3RgfjoPmh7Zmy4FADim7HG2nTblXKKXBJhbg\nHI6X+7ltmZqMwG6Qb1Phq3WHPm4/Z0z+C3xs/2npikTMb8kY51GX54qJNamBO9G1\nY1pFsxwQ9Ep0V3BwX2Q+YJJFdBHeDVD0UvbO2GekArMgN48+OvkHBqajWFn1xOEB\n6Wp+j8qUue6fMcDFkq7ZY7hfEoBlZ+ZbCJNslYNiAQKBgQDzj/4q8+ChIWkLg5BZ\npaMaMV/goVrCH7HaF3DLxKTYKPWuRBpvW9xgx4tDDERhEZhDGgDoT+xSXdCTtYML\nWMBcvQnSn7JHSHa7CoAu/OwLMtKXSKtU3GO6nQeaifXL+Qi2U3JbIvwN34b7pzW0\n16a95qWVyXKlKM6dh0RKpit2lQKBgQDE3OtPgSiDMauZ+Cn9Sk1+aZ9jfizQZIUH\nkFGifsEgr/txTN2Gt4dIT+up0HSVpwfKLsHPS9wIJs38bivhWblchVEw5J1ZXPFQ\n27cs88B6LySw0dbsMRIceXQOhpm/118hr/QV0h4za99FP/1kGHGPrT4FsSw4FrNg\nBqF3hhUczQKBgBsspZ8FNrrDj4TJWQGniVsSxy+40Pd3sdAzbVJOzlWPvFmFH63t\nAdmKae9BHx/1ZpeV/yPsRuGptevFBKnvbQbr0Hy/dJSfcR/NPCAB+BQHx5c5dGQz\ncq0PeBm16sanMmGlTcz9SkIB/n11Wnii1ue5JCBiKXhj5SmOPgBWKeNBAoGARVZ2\nfwND7KmTAmEZEQCZuNuk6xsm16OAA4D+b9hrV4MEcgybvfZobLzRiXdFiOxS3xCG\n7OeQMULRrIZ1aCL9GaxPQ4RSM4Z77Hnm06tq8N4n8yuFop1J/sN8cB1Si/JkrG3X\n79OZFY16D18Rda7yWKOxQ7n6lCrStRDA0GNmjkUCgYEAnCd1PVJJ+VX7CXJ6gz7H\n0VXLAD+GUQzlnSzv6mgGWzn0acpVz9Q+o1qpxgNL/ehLTz+v3Nr7hexl77pUDVfJ\nS1zBopXaKx330eAJm4d0bKgKndHyfr7VJ6f5H/WezX7Q5jkm32D9/GPhJCfqBp3q\nWA/g+9g+fwkc78QKuQl7M68=\n-----END PRIVATE KEY-----\n",
//},
Wx: WxPay{
AppId: "wx1bb10834390b170e",
MchId: wechat.MchId,
SerialNo: wechat.SerialNo,
ApiV3Key: wechat.ApiV3Key,
PrivateKey: wechat.PrivateKey,
},
OpenId: "oxsH-6wPlbshEOvXo0FvbPqA0l3Y",
}
// 支付
orderResult := PaymentService(c, request)
t.Log(orderResult)
//// 查询订单
//qreq := PayOrderQueryRequest{
// OrderId: request.OrderId,
// PayChannel: 1,
// Wx: request.Wx,
// //Ali: request.Ali,
//}
//queryResult := PayOrderQuery(c, qreq)
//t.Log(queryResult)
// 退款
//refundResult := OrderRefund(c, request)
//// 关闭订单
//closeOrder := OrderCloseRequest{
// OrderId: request.OrderId,
// PayChannel: 2,
// Wx: WxPay{},
// Ali: request.Ali,
//}
//closeResutl := OrderClose(c, closeOrder)
//t.Log(closeResutl)
}

View File

@ -180,8 +180,8 @@ func WxPayCallBack(notifyReq *wechat.V3NotifyReq, wxConfig WxPay) error {
TradeStateDesc string `json:"trade_state_desc"` // 交易状态描述 TradeStateDesc string `json:"trade_state_desc"` // 交易状态描述
SuccessTime string `json:"success_time"` // 支付完成时间 SuccessTime string `json:"success_time"` // 支付完成时间
Amount struct { Amount struct {
Total int64 `json:"total"` Total int64 `json:"total"` // 【总金额】 订单总金额,单位为分,整型。
PayerTotal int64 `json:"payer_total"` PayerTotal int64 `json:"payer_total"` //用户支付金额】用户实际支付金额,整型,单位为分,用户支付金额=总金额-优惠券金额
} `json:"amount"` } `json:"amount"`
} }
// 通用通知解密(推荐此方法) // 通用通知解密(推荐此方法)
@ -214,7 +214,7 @@ func WxPayCallBack(notifyReq *wechat.V3NotifyReq, wxConfig WxPay) error {
// 触发下游回调的格式 // 触发下游回调的格式
orderId, _ := strconv.Atoi(CallBackInfo.OutTradeNo) orderId, _ := strconv.Atoi(CallBackInfo.OutTradeNo)
res := thirdpay_notify.NewOrderNotifyWithHandle(int64(orderId), errCode, orderStatus, int(CallBackInfo.Amount.PayerTotal), msg) res := thirdpay_notify.NewOrderNotifyWithHandle(int64(orderId), errCode, orderStatus, int(CallBackInfo.Amount.Total), int(CallBackInfo.Amount.PayerTotal), msg)
merchantCallback, _ := json.Marshal(res) merchantCallback, _ := json.Marshal(res)
// 记录日志 // 记录日志
go func() { go func() {