feat: 微信支付

This commit is contained in:
wolter 2024-12-06 15:23:57 +08:00
parent a03d0947a5
commit de1f1d01fc
10 changed files with 56 additions and 14 deletions

View File

@ -96,6 +96,9 @@ const (
// 退款
RefundOutTradeNoSame = 1801
// 微信授权
WechatAuthFail = 1901
)
var MsgEN = map[int]string{
@ -178,6 +181,8 @@ var MsgZH = map[int]string{
CloseOrderPayed: "订单已支付成功,无法关闭",
ThirdRefundFail: "第三方退款失败",
WechatAuthFail: "微信授权失败",
}
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -208,6 +208,6 @@ func GetWxAuthUrl(c *gin.Context) {
// 通过code获取授权openid
func GetWxAuth(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
code := services.GetWxAuth(*req)
controllers.HandCodeRes(c, code, code)
rsp, code := services.GetWxAuth(*req)
controllers.HandCodeRes(c, rsp, code)
}

View File

@ -19,6 +19,7 @@ type PayCommonReqBody struct {
ExtJson string `json:"ext_json" label:"扩展参数"`
Desc string `json:"desc" validate:"max=100" label:"商品描述"`
ReturnUrl string `json:"return_url" validate:"max=1024" label:"支付成功后跳转的地址"`
OpenId string `json:"open_id" label:"用户openid"`
}
type PayReqs struct {

View File

@ -5,7 +5,17 @@ type GetWxAuthUrlRequest struct {
}
type GetWxAuthRequest struct {
Code string `json:"code" form:"code" `
State string `json:"state" form:"state"`
PayChannelId string `json:"pay_channel_id" form:"pay_channel_id"`
Code string `json:"code" form:"code" `
State string `json:"state" form:"state"`
}
// 获取微信用户信息
type GetWxAuthResponse struct {
AccessToken string `json:"access_token"` //网页授权接口调用凭证,注意此access_token与基础支持的access_token不同
ExpiresIn int `json:"expires_in"` //access_token接口调用凭证超时时间单位
RefreshToken string `json:"refresh_token"` //用户刷新access_token
Openid string `json:"openid"` //用户唯一标识请注意在未关注公众号时用户访问公众号的网页也会产生一个用户和公众号唯一的OpenID
Scope string `json:"scope"` //用户授权的作用域,使用逗号(,)分隔
IsSnapshotuser int `json:"is_snapshotuser"`
Unionid string `json:"unionid"` // 用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的只有当scope为"snsapi_userinfo"时返回
}

View File

@ -25,6 +25,7 @@ type PayParam struct {
Desc string
ClientIp string
ReturnUrl string
OpenId string
}
type Pay struct {
@ -50,6 +51,7 @@ func NewPayWithPayCheck(paycheck *PayCheck) *Pay {
Desc: paycheck.Reqs.Desc,
ClientIp: paycheck.AppCheck.Ip,
ReturnUrl: paycheck.Reqs.ReturnUrl,
OpenId: paycheck.Reqs.OpenId,
},
RelationOrder: paycheck.OldOrder,
PayCode: errorcode.Success,
@ -106,7 +108,9 @@ func (w *Pay) PayUrl() (url string) {
Amount: w.Order.Amount,
PayerClientIp: w.PayParam.ClientIp,
ReturnUrl: w.PayParam.ReturnUrl,
OpenId: w.PayParam.OpenId,
}
// 判断是否是支持的支付渠道,找到对应的配置
if payFunc, ok = PayWayList[w.PayParam.Channel.ChannelType]; !ok {
w.PayCode = errorcode.PayChannelNotBuild
return

View File

@ -7,9 +7,11 @@ import (
"github.com/bytedance/sonic"
)
// 支持的支付方式
var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error{
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
common.PAY_CHANNEL_WECHAT_H5: WechatH5,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPI,
}
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
@ -29,3 +31,11 @@ func AlipayWeb(commonPayInfo *paymentService.PayOrderRequest, channel *paychanne
commonPayInfo.Ali.AppId = channel.AppId
return nil
}
func WechatJSAPI(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
err := sonic.Unmarshal([]byte(channel.ExtJson), &commonPayInfo.Wx)
if err != nil {
return err
}
commonPayInfo.Wx.AppId = channel.AppId
return nil
}

View File

@ -50,11 +50,11 @@ func GetWxAuthUrl(param front.GetWxAuthUrlRequest) (targetUrl string, code int)
return
}
// // 通过code换取网页授权access_token
func GetWxAuth(param front.GetWxAuthRequest) (code int) {
// // 通过code换取网页授权access_tokenopenid
func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) {
// 获取支付渠道的配置
id, err := strconv.Atoi(param.PayChannelId)
id, err := strconv.Atoi(param.State)
if err != nil {
code = handErr(err)
return
@ -65,7 +65,7 @@ func GetWxAuth(param front.GetWxAuthRequest) (code int) {
return
}
//// 配置解析
//// 配置支付的解析
wxConfig := make(map[string]interface{})
err = json.Unmarshal([]byte(payChannel.ExtJson), &wxConfig)
if err != nil {
@ -95,5 +95,16 @@ func GetWxAuth(param front.GetWxAuthRequest) (code int) {
}
utils.Log(nil, "获取微信授权信息", string(response), targetUrl)
// 解析返回数据
err = json.Unmarshal(response, &rsp)
if err != nil {
code = handErr(err)
return
}
if rsp.Openid == "" {
code = errorcode.WechatAuthFail
return
}
code = handErr(err)
return
}

View File

@ -30,6 +30,7 @@ type WxPay struct {
SerialNo string `json:"serial_no"` // 商户证书的证书序列号
ApiV3Key string `json:"api_v_3_key"` // apiV3Key商户平台获取
PrivateKey string `json:"private_key"` // 私钥 apiclient_key.pem 读取后的内容
Secret string `json:"secret"` // 商户私钥,读取后的内容
}
type AliPay struct {

View File

@ -97,6 +97,9 @@ func WxH5PayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, er
// 微信JSAPI支付
func WxJsApiPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) {
if payOrderRequest.OpenId == "" {
return "", errors.New("jsapi方式openId不能为空")
}
// 初始化微信客户端
wxClient, err := InitClient(payOrderRequest.Wx)
if err != nil {

View File

@ -2,8 +2,6 @@ package httpclient
import (
"PaymentCenter/app/utils"
"fmt"
"github.com/valyala/fasthttp"
"time"
)
@ -83,7 +81,6 @@ func FastHttpGet(url string, header map[string]string, body map[string]string, t
}
url = url[0 : len(url)-1]
}
fmt.Println(url)
req.SetRequestURI(url)
resp := fasthttp.AcquireResponse()
defer fasthttp.ReleaseResponse(resp) // 用完需要释放资源