PaymentCenter/app/http/controllers/front/payment_controller.go

164 lines
5.4 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package front
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/third/paymentService"
"bytes"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"github.com/go-pay/gopay/wechat/v3"
"github.com/qit-team/snow-core/log/logger"
"io"
"strconv"
"net/http"
)
// WxCallback 微信支付回调
func WxCallback(c *gin.Context) {
saveLogger(c, "wx")
payChannelId := c.Param("payChannelId")
logger.Info(c, "WxCallback-回调数据payChannelId", payChannelId)
if payChannelId == "" {
c.String(http.StatusBadRequest, "%s", "fail")
return
}
// 查询应用下的支付配置
var payChannelModel paychannelmodel.PayChannel
payChannelIdInt, _ := strconv.Atoi(payChannelId)
payChannelModel.Id = int64(payChannelIdInt)
code := services.PayChannelGet(&payChannelModel)
if code == errorcode.PayChannelNotFound {
logger.Error(c, "AliCallback-回调数据未获取到支付配置404")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
if payChannelModel.ChannelType != common.PAY_CHANNEL_WECHAT_H5 {
logger.Error(c, "WxCallback-回调数据解析支付配置错误,查询的数据不是当前渠道")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
var wxConfig paymentService.WxPay
err := json.Unmarshal([]byte(payChannelModel.ExtJson), &wxConfig)
if err != nil {
logger.Error(c, "WxCallback-回调数据解析支付配置错误", fmt.Sprintf("错误原因:%s", err.Error()))
c.String(http.StatusBadRequest, "%s", "fail")
return
}
if wxConfig.ApiV3Key == "" || wxConfig.MchId == "" || wxConfig.PrivateKey == "" || wxConfig.SerialNo == "" {
logger.Error(c, "WxCallback-回调数据解析支付配置错误,解析出来的信息为空")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
wxConfig.AppId = payChannelModel.AppId
notifyReq, err := wechat.V3ParseNotify(c.Request)
if err != nil {
logger.Error(c, "WxCallback-回调数据验签失败", err.Error())
c.String(http.StatusBadRequest, "%s", "fail")
return
}
notifyReqJson, _ := json.Marshal(notifyReq)
logger.Info(c, "WxCallback-解析微信回调请求的参数到 V3NotifyReq 结构体", string(notifyReqJson))
err = paymentService.WxPayCallBack(notifyReq, wxConfig)
if err != nil {
logger.Error(c, "WxCallback-回调执行失败,失败原因:", err.Error())
c.String(http.StatusBadRequest, "%s", "fail")
return
}
c.JSON(http.StatusOK, &wechat.V3NotifyRsp{Code: gopay.SUCCESS, Message: "成功"})
return
}
// AliCallback 支付宝支付回调
func AliCallback(c *gin.Context) {
saveLogger(c, "ALI")
payChannelId := c.Param("payChannelId")
logger.Info(c, "AliCallback-回调数据APPID", payChannelId)
if payChannelId == "" {
c.String(http.StatusBadRequest, "%s", "fail")
return
}
// 查询应用下的支付配置
var payChannelModel paychannelmodel.PayChannel
payChannelIdInt, _ := strconv.Atoi(payChannelId)
payChannelModel.Id = int64(payChannelIdInt)
code := services.PayChannelGet(&payChannelModel)
if code == errorcode.PayChannelNotFound {
logger.Error(c, "AliCallback-回调数据未获取到支付配置404")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
if payChannelModel.ChannelType != common.PAY_CHANNEL_ALIPAY_WEB {
logger.Error(c, "AliCallback-回调数据解析支付配置错误,查询的数据不是当前渠道")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
var aliConfig paymentService.AliPay
err := json.Unmarshal([]byte(payChannelModel.ExtJson), &aliConfig)
if err != nil {
logger.Error(c, "AliCallback-回调数据解析支付配置错误", fmt.Sprintf("错误原因:%s", err.Error()))
c.String(http.StatusBadRequest, "%s", "fail")
return
}
if aliConfig.AlipayPublicCert == "" || aliConfig.PrivateKey == "" || aliConfig.AppPublicCert == "" || aliConfig.AlipayRootCert == "" {
logger.Error(c, "AliCallback-回调数据解析支付配置错误,解析出来的信息为空")
c.String(http.StatusBadRequest, "%s", "fail")
return
}
aliConfig.AppId = payChannelModel.AppId
notifyReq, err := alipay.ParseNotifyToBodyMap(c.Request) // c.Request 是 gin 框架的写法
if err != nil {
c.String(http.StatusBadRequest, "%s", "fail")
return
}
notifyReqJson, _ := json.Marshal(notifyReq)
logger.Info(c, "AliCallback-解析支付宝支付异步通知的参数到BodyMap", string(notifyReqJson))
err = paymentService.ALiCallBack(notifyReq, aliConfig)
if err != nil {
logger.Error(c, "AliCallback-回调执行失败,失败原因:", err.Error())
c.String(http.StatusBadRequest, "%s", "fail")
return
}
c.String(http.StatusOK, "%s", "success")
return
}
func saveLogger(c *gin.Context, payType string) {
// 保存请求的方法和URL
method := c.Request.Method
url := c.Request.URL.String()
// 保存请求头
headers := make(map[string]string)
for k, v := range c.Request.Header {
headers[k] = v[0]
}
// 保存请求体
var bodyBytes []byte
if c.Request.Body != nil {
bodyBytes, _ = io.ReadAll(c.Request.Body)
}
// 由于 io.ReadAll 会将 body 读完,所以需要重新赋值
c.Request.Body = io.NopCloser(bytes.NewBuffer(bodyBytes))
// 使用 logger 记录请求信息
logger.Info(c, "支付回调"+payType, fmt.Sprintf("接受的参数method: %s , url: %s , headers: %s , body: %s", method, url, headers, string(bodyBytes)))
c.Next()
}