Files
full/module/finance/wallet/internal/logic/wechat/wx_callback.go

62 lines
2.0 KiB
Go
Raw Normal View History

package wechat
import (
"context"
"encoding/json"
"bsm/full/module/finance/wallet/internal/config"
2026-09-22 21:15:34 +08:00
"bsm/full/module/finance/wallet/internal/models"
pb "bsm/full/module/finance/wallet/pb"
"git.apinb.com/bsm-sdk/core/errcode"
"git.apinb.com/bsm-sdk/core/printer"
"github.com/go-pay/gopay/wechat/v3"
)
// 微信支付回调
2026-09-22 21:15:34 +08:00
// 完成验签与解密后,按商户订单号反查本地支付单、核对金额,
// 条件更新为支付成功并在同一事务内入账写流水。
func WxCallback(ctx context.Context, in *pb.WxCallBackRequest) (reply *pb.CallBackReply, err error) {
var notifyReq = &wechat.V3NotifyReq{}
data, err := json.Marshal(in)
if err != nil {
return nil, errcode.ErrJsonMarshal
}
err = json.Unmarshal(data, &notifyReq)
if err != nil {
return nil, errcode.ErrJsonUnmarshal
}
2026-09-22 21:15:34 +08:00
wx, err := NewWechat()
if err != nil {
printer.Error(err.Error())
return &pb.CallBackReply{Code: "FAIL", Message: "支付客户端初始化失败"}, nil
}
pubKey := wx.Client.WxPublicKeyMap()
err = notifyReq.VerifySignByPKMap(pubKey)
if err != nil {
printer.Error(err.Error())
return &pb.CallBackReply{Code: "FAIL", Message: "验签失败"}, nil
}
res, err := notifyReq.DecryptPayCipherText(config.Spec.WeChat.APIV3Key)
if err != nil {
printer.Error(err.Error())
2026-09-22 21:15:34 +08:00
return &pb.CallBackReply{Code: "FAIL", Message: "解密失败"}, err
}
// 仅处理支付成功通知,其余状态直接应答,避免渠道重复推送
if res.TradeState != "SUCCESS" {
return &pb.CallBackReply{Code: "SUCCESS", Message: res.TradeState}, nil
}
if res.Amount == nil {
return &pb.CallBackReply{Code: "FAIL", Message: "金额缺失"}, nil
}
// 结算:金额核对 + 条件更新为成功 + 事务内入账写流水(幂等)
if err := models.SettlePaymentSuccess(res.OutTradeNo, res.TransactionId, int64(res.Amount.Total)); err != nil {
printer.Error(err.Error())
return &pb.CallBackReply{Code: "FAIL", Message: "结算失败"}, nil
}
2026-09-22 21:15:34 +08:00
return &pb.CallBackReply{Code: "SUCCESS", Message: "SUCCESS"}, nil
}