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

262 lines
8.0 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/http/controllers"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services"
"PaymentCenter/app/services/thirdpay"
"PaymentCenter/app/third/paymentService"
"PaymentCenter/app/utils"
"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/ioutil"
"strconv"
"net/http"
)
// WxCallback 微信支付回调
func WxCallback(c *gin.Context) {
logger.Info(c, "WxCallback-回调数据", c.Request)
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 || payChannelModel.ChannelType == common.PAY_CHANNEL_WECHAT_JSAPI) {
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) {
logger.Info(c, "AliCallback-回调数据", c.Request)
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 BrokerWechatUrl(c *gin.Context) {
url := c.Query("url")
if url == "" {
c.String(400, "url is empty")
return
}
method := "GET"
client := &http.Client{}
req, err := http.NewRequest(method, url, nil)
if err != nil {
fmt.Println(err)
return
}
req.Header.Add("Referer", "https://cardmallpay.85938.cn")
req.Header.Add("User-Agent", "Apifox/1.0.0 (https://apifox.com)")
req.Header.Add("Accept", "*/*")
req.Header.Add("Host", "wx.tenpay.com")
req.Header.Add("Connection", "keep-alive")
res, err := client.Do(req)
if err != nil {
fmt.Println(err)
return
}
defer res.Body.Close()
// 读取响应体
body, err := ioutil.ReadAll(res.Body)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
// 复制响应头部(可选,根据需要选择需要的头部)
for name, values := range res.Header {
// 注意某些头部如Content-Length在转发时可能需要重新计算
for _, value := range values {
c.Writer.Header().Add(name, value)
}
}
// 设置状态码
c.Writer.WriteHeader(res.StatusCode)
// 写入响应体
_, err = c.Writer.Write(body)
if err != nil {
c.AbortWithError(http.StatusInternalServerError, err)
return
}
}
// 拼接微信授权链接
func GetWxAuthUrl(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthUrlRequest)
url, code := thirdpay.GetWxAuthUrl(*req)
controllers.HandCodeRes(c, url, code)
}
// 通过code获取授权openid
func GetWxAuth(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
rsp, code := thirdpay.GetWxAuth(*req)
controllers.HandCodeRes(c, rsp, code)
}
// 接收code
func GetWxCode(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
//rsp, code := thirdpay.GetWxAuth(*req)
controllers.HandCodeRes(c, req, 200)
}
// 微信JSAPI 支付接口
/*
预支付接口实现如下功能:
1.订单请求参数
2.订单信息存数据
3.返回用户授权地址
wxjsapi接口实现如下功能
4.用户授权后获取codestatu传的是订单号
5.通过code获取openid
6.通过openid请求微信下单返回支付参数
7.支付参数聚合,签名,返回支付参数给前端
*/
func WxJsApiPay(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.WxJsApiPayRequest)
req.ClientIp = c.ClientIP()
rsp, code := thirdpay.WxJsApiPay(*req)
if code == errorcode.Success {
c.HTML(http.StatusOK, "success.html", gin.H{
"appId": rsp.AppId,
"timeStamp": rsp.TimeStamp,
"nonceStr": rsp.NonceStr,
"package": rsp.Package,
"signType": rsp.SignType,
"paySign": rsp.PaySign,
})
} else {
utils.Log(c, "", "WxJsApiPay,支付失败code=", code, "msg=", rsp.ThirdMsg)
errmsg := rsp.ThirdMsg
data := make(map[string]interface{})
_ = json.Unmarshal([]byte(rsp.ThirdMsg), &data)
if message, ok := data["message"]; ok {
errmsg = message.(string)
}
if errmsg == "" {
errmsg = errorcode.GetMsg(code, "")
}
c.HTML(http.StatusOK, "fail.html", gin.H{
"errmsg": errmsg,
})
}
}