feat: wxmini

This commit is contained in:
wolter 2025-04-21 14:08:48 +08:00
parent 3f26ffa8cb
commit 8ce5ead203
16 changed files with 453 additions and 26 deletions

View File

@ -104,6 +104,7 @@ const (
// 微信授权 // 微信授权
WechatAuthFail = 1901 WechatAuthFail = 1901
WechatAuthSignFail = 1902 WechatAuthSignFail = 1902
WechatPayError = 1903
ClientEnvErr = 2000 ClientEnvErr = 2000
) )
@ -194,6 +195,7 @@ var MsgZH = map[int]string{
WechatAuthSignFail: "微信签名失败", WechatAuthSignFail: "微信签名失败",
ClientEnvErr: "支付环境错误", ClientEnvErr: "支付环境错误",
OrderPayRequestAcquireLock: "系统繁忙,请稍后再试", OrderPayRequestAcquireLock: "系统繁忙,请稍后再试",
WechatPayError: "微信支付配置错误",
} }
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH} var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}

View File

@ -201,7 +201,7 @@ func GetWxAuthUrl(c *gin.Context) {
controllers.HandCodeRes(c, url, code) controllers.HandCodeRes(c, url, code)
} }
// 通过code获取授权openid // 通过code获取授权openid, 微信公众号 使用
func GetWxAuth(c *gin.Context) { func GetWxAuth(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest) req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
rsp, code := thirdpay.GetWxAuth(*req) rsp, code := thirdpay.GetWxAuth(*req)
@ -259,3 +259,30 @@ func WxJsApiPay(c *gin.Context) {
}) })
} }
} }
// 微信小程序 通过code获取openId
func GetWxAuthMini(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
rsp, code := thirdpay.GetWxAuthMini(*req)
controllers.HandCodeRes(c, rsp, code)
}
// 小程序 获取加密scheme码
func GetWxMiniScheme(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.GetWxMiniSchemeRequest)
rsp, code := thirdpay.GetWxMiniSchemeService(*req)
controllers.HandCodeRes(c, rsp, code)
}
// 微信小程序支付,返回支付参数给前端
func WxMiniPay(c *gin.Context) {
req, _ := controllers.GetRequest(c).(*front.WxMiniPayRequest)
request := front.WxJsApiPayRequest{
Code: req.Code,
State: req.OrderId,
ClientIp: c.ClientIP(),
}
rsp, code := thirdpay.WxMiniPay(request)
controllers.HandCodeRes(c, rsp, code)
}

View File

@ -9,7 +9,7 @@ type GetWxAuthRequest struct {
PayChannelId string `json:"state" form:"state"` PayChannelId string `json:"state" form:"state"`
} }
// 获取微信用户信息 // 获取微信用户信息, 微信公众号
type GetWxAuthResponse struct { type GetWxAuthResponse struct {
AccessToken string `json:"access_token"` //网页授权接口调用凭证,注意此access_token与基础支持的access_token不同 AccessToken string `json:"access_token"` //网页授权接口调用凭证,注意此access_token与基础支持的access_token不同
ExpiresIn int `json:"expires_in"` //access_token接口调用凭证超时时间单位 ExpiresIn int `json:"expires_in"` //access_token接口调用凭证超时时间单位
@ -20,6 +20,15 @@ type GetWxAuthResponse struct {
Unionid string `json:"unionid"` // 用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的只有当scope为"snsapi_userinfo"时返回 Unionid string `json:"unionid"` // 用户统一标识(针对一个微信开放平台账号下的应用,同一用户的 unionid 是唯一的只有当scope为"snsapi_userinfo"时返回
} }
// 获取微信用户信息, 微信小程序
type GetWxAuthMiniResponse struct {
Openid string `json:"openid"` // 用户唯一标识
SessionKey string `json:"session_key"` //会话密钥
Unionid string `json:"unionid"` //用户在开放平台的唯一标识符,若当前小程序已绑定到微信开放平台帐号下会返回
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
}
// jsapi支付 // jsapi支付
type WxJsApiPayRequest struct { type WxJsApiPayRequest struct {
Code string `json:"code" form:"code" ` Code string `json:"code" form:"code" `
@ -44,3 +53,27 @@ type WxJsApiPayResponse struct {
ThirdMsg string `json:"third_msg"` ThirdMsg string `json:"third_msg"`
ReturnUrl string ReturnUrl string
} }
// 微信小程序支付
type WxMiniPayRequest struct {
Code string `json:"code" form:"code" `
OrderId string `json:"order_id" form:"order_id"` // 支付中心的订单id
ClientIp string `json:"client_ip" form:"client_ip"`
}
// 微信小程序支付 返回
type WxMiniPayResponse struct {
AppId string `json:"appId"`
TimeStamp string `json:"timeStamp"`
NonceStr string `json:"nonceStr"`
Package string `json:"package"`
SignType string `json:"signType"`
PaySign string `json:"paySign"`
ThirdMsg string `json:"third_msg"`
ReturnUrl string `json:"return_url"`
}
type GetWxMiniSchemeRequest struct {
PayChannelId string `json:"pay_channel_id" form:"pay_channel_id" validate:"required"`
GenerateSchemeRequest
}

View File

@ -0,0 +1,13 @@
package front
type GenerateSchemeRequest struct {
JumpWxa JumpWxa `json:"jump_wxa"`
IsExpire bool `json:"is_expire"` //
ExpireType int `json:"expire_type"` // 默认值0到期失效的 scheme 码失效类型失效时间0失效间隔天数1
ExpireInterval int `json:"expire_interval"` //到期失效的 scheme 码的失效间隔天数。生成的到期失效 scheme 码在该间隔时间到达前有效。最长间隔天数为30天。is_expire 为 true 且 expire_type 为 1 时必填
}
type JumpWxa struct {
Path string `json:"path"`
Query string `json:"query"`
EnvVersion string `json:"env_version"`
}

View File

@ -19,15 +19,17 @@ var FrontRequestMap = map[string]func() (validForm interface{}, isSaveLog bool){
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{ var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) }, common.FRONT_V1 + "/pay/url": func() interface{} { return new(front.RequestBody) },
common.FRONT_V2 + "/pay/url": func() interface{} { return new(front.RequestBody) }, common.FRONT_V2 + "/pay/url": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/refund": func() interface{} { return new(front.RequestBody) }, common.FRONT_V1 + "/pay/refund": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/query": func() interface{} { return new(front.RequestBody) }, common.FRONT_V1 + "/pay/query": func() interface{} { return new(front.RequestBody) },
common.FRONT_V1 + "/pay/close": func() interface{} { return new(front.CloseReqs) }, common.FRONT_V1 + "/pay/close": func() interface{} { return new(front.CloseReqs) },
common.FRONT_V1 + "/wx/index": func() interface{} { return new(entities.PageRequest) }, common.FRONT_V1 + "/wx/index": func() interface{} { return new(entities.PageRequest) },
common.FRONT_V1 + "/wx/getWxAuthUrl": func() interface{} { return new(front.GetWxAuthUrlRequest) }, common.FRONT_V1 + "/wx/getWxAuthUrl": func() interface{} { return new(front.GetWxAuthUrlRequest) },
common.FRONT_V1 + "/wx/getWxAuth": func() interface{} { return new(front.GetWxAuthRequest) }, common.FRONT_V1 + "/wx/getWxAuth": func() interface{} { return new(front.GetWxAuthRequest) },
common.FRONT_V1 + "/wx/getCode": func() interface{} { return new(front.GetWxAuthRequest) }, common.FRONT_V1 + "/wx/getWxAuthMini": func() interface{} { return new(front.GetWxAuthRequest) },
common.FRONT_V1 + "/wx/getCode": func() interface{} { return new(front.GetWxAuthRequest) },
common.FRONT_V1 + "/wx/getScheme": func() interface{} { return new(front.GetWxMiniSchemeRequest) },
common.FRONT_V1 + "/payPage/list": func() interface{} { return new(front.PayChannelListRequest) }, common.FRONT_V1 + "/payPage/list": func() interface{} { return new(front.PayChannelListRequest) },
common.FRONT_V1 + "/payPage/submit": func() interface{} { return new(front.GetPayLinkRequest) }, common.FRONT_V1 + "/payPage/submit": func() interface{} { return new(front.GetPayLinkRequest) },

View File

@ -70,9 +70,12 @@ func RegisterRoute(router *gin.Engine) {
router.LoadHTMLGlob("./front/templates/*") router.LoadHTMLGlob("./front/templates/*")
wx := v1.Group("/wx", middlewares.ValidateRequest()) wx := v1.Group("/wx", middlewares.ValidateRequest())
{ {
wx.POST("/getWxAuthUrl", front.GetWxAuthUrl) // 获取授权codeUrl wx.POST("/getWxAuthUrl", front.GetWxAuthUrl) // 获取授权codeUrl
wx.GET("/getWxAuth", front.GetWxAuth) // 获取openId wx.GET("/getWxAuth", front.GetWxAuth) // 获取openId, 公众号授权
wx.GET("/getCode", front.GetWxCode) // 接收微信code wx.GET("/getCode", front.GetWxCode) // 接收微信code
wx.POST("/getScheme", front.GetWxMiniScheme) // 小程序 获取加密scheme码
wx.GET("/getWxAuthMini", front.GetWxAuthMini) // 小程序 获取openId, 授权
wx.POST("/wxMini", front.WxMiniPay) // 小程序 获取支付参数
} }
// 微信jsapi支付链接 // 微信jsapi支付链接

View File

@ -3,6 +3,8 @@ package do
import ( import (
"PaymentCenter/app/constants/common" "PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode" "PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/merchantmodel" "PaymentCenter/app/models/merchantmodel"
"PaymentCenter/app/models/paychannelmodel" "PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/services" "PaymentCenter/app/services"
@ -124,6 +126,8 @@ func (w *Pay) PayUrl() (url string) {
w.PayCode = errorcode.PayChannelExtJsonError w.PayCode = errorcode.PayChannelExtJsonError
return return
} }
// 根据渠道类型,调用对应的支付方式
switch w.PayParam.Channel.ChannelType { switch w.PayParam.Channel.ChannelType {
// 微信公众号支付,返回的是用户授权链接 // 微信公众号支付,返回的是用户授权链接
case common.PAY_CHANNEL_WECHAT_JSAPI: case common.PAY_CHANNEL_WECHAT_JSAPI:
@ -138,13 +142,30 @@ func (w *Pay) PayUrl() (url string) {
if res.Result != "" { if res.Result != "" {
res.Result = config.GetConf().PayService.Host + "/pay/front/api/v1/brokerWechatUrl" + "?url=" + res.Result res.Result = config.GetConf().PayService.Host + "/pay/front/api/v1/brokerWechatUrl" + "?url=" + res.Result
} }
case common.PAY_CHANNEL_WECHAT_MINI:
req := front.GetWxMiniSchemeRequest{
PayChannelId: strconv.Itoa(int(w.PayParam.Channel.Id)),
GenerateSchemeRequest: front.GenerateSchemeRequest{
JumpWxa: front.JumpWxa{Query: "?order_id=" + strconv.Itoa(int(w.Order.Id))},
}}
if config.GetEnv() == config.LocalEnv {
req.GenerateSchemeRequest.JumpWxa.EnvVersion = "develop"
}
// 微信小程序支付返回小程序的scheme todo 拼接订单id参数
wx := NewWxMini().WithPayChannel(w.PayParam.Channel)
url, err = wx.GetWxMiniScheme(req)
res.Result = url
if err != nil {
w.PayCode = errorcode.PayChannelExtJsonError
w.ThirdMsg = err.Error()
return
}
default: default:
w.PayCode = errorcode.PayChannelNotBuild w.PayCode = errorcode.PayChannelNotBuild
return return
} }
//res := paymentService.PaymentService(*w.ctx, *thirdPay)
if res.Code == payCommon.PAY_SUCCESS_CODE { if res.Code == payCommon.PAY_SUCCESS_CODE {
w.Order.Status = common.ORDER_STATUS_PAYING w.Order.Status = common.ORDER_STATUS_PAYING
code := services.OrderUpdate(w.Order, "status") code := services.OrderUpdate(w.Order, "status")

View File

@ -13,6 +13,7 @@ var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, cha
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb, common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
common.PAY_CHANNEL_ALIPAY_PC: AlipayWeb, common.PAY_CHANNEL_ALIPAY_PC: AlipayWeb,
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPI, common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPI,
common.PAY_CHANNEL_WECHAT_MINI: WechatJSAPI,
} }
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error { func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {

View File

@ -10,7 +10,9 @@ import (
var RefundWayList = map[int]func(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error{ var RefundWayList = map[int]func(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error{
common.PAY_CHANNEL_WECHAT_H5: WechatH5Refund, common.PAY_CHANNEL_WECHAT_H5: WechatH5Refund,
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWebRefund, common.PAY_CHANNEL_ALIPAY_WEB: AlipayWebRefund,
common.PAY_CHANNEL_ALIPAY_PC: AlipayWebRefund,
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPIRefund, common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPIRefund,
common.PAY_CHANNEL_WECHAT_MINI: WechatJSAPIRefund,
} }
func WechatH5Refund(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error { func WechatH5Refund(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error {

View File

@ -0,0 +1,208 @@
package do
import (
"PaymentCenter/app/data"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/models/paychannelmodel"
"PaymentCenter/app/third/paymentService"
"PaymentCenter/app/utils"
"PaymentCenter/app/utils/httpclient"
"encoding/json"
"fmt"
"xorm.io/builder"
)
type WxMini struct {
payChannel *paychannelmodel.PayChannel
}
func NewWxMini() *WxMini {
return &WxMini{}
}
func (wm *WxMini) WithPayChannel(payChannel *paychannelmodel.PayChannel) *WxMini {
wm.payChannel = payChannel
return wm
}
// 小程序,获取接口调用凭据
func (wm *WxMini) GetAccessToken(appid, secret string) (accessToken string, err error) {
var (
targetUrl = fmt.Sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s", appid, secret)
header = map[string]string{
"Content-Type": "application/json",
}
rsp = make(map[string]interface{})
)
// 发送请求
response, err := httpclient.FastHttpGet(targetUrl, header, nil, 0)
if err != nil {
err = fmt.Errorf("getAccessToken 获取接口调用凭据 err:%s", err.Error())
return
}
utils.Log(nil, "getAccessToken 获取接口调用凭据 ", "response ="+string(response))
err = json.Unmarshal(response, &rsp)
if err != nil {
err = fmt.Errorf("getAccessToken 获取接口调用凭据 err:%s", err.Error())
return
}
accessToken = rsp["access_token"].(string)
if accessToken == "" {
err = fmt.Errorf("getAccessToken 获取接口调用凭据失败")
}
return
}
// 小程序获取加密scheme码
func (wm *WxMini) generateScheme(accessToken string, param front.GenerateSchemeRequest) (scheme string, err error) {
var (
targetUrl = "https://api.weixin.qq.com/wxa/generatescheme?access_token=" + accessToken
header = map[string]string{
"Content-Type": "application/json",
}
body []byte
)
type SchemeResponse struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
Openlink string `json:"openlink"`
}
body, err = json.Marshal(param)
if err != nil {
return
}
// 发送请求
response, err := httpclient.FastHttpPost(targetUrl, header, body, 0)
if err != nil {
err = fmt.Errorf("GenerateScheme 获取加密scheme码 err:%s", err.Error())
return
}
utils.Log(nil, "GenerateScheme 获取加密scheme码 ", "response ="+string(response))
var rsp SchemeResponse
err = json.Unmarshal(response, &rsp)
if err != nil {
err = fmt.Errorf("GenerateScheme 获取加密scheme码 err:%s", err.Error())
return
} else if rsp.Errcode != 0 {
err = fmt.Errorf("GenerateScheme 获取加密scheme码 code:%d err:%s", rsp.Errcode, rsp.Errmsg)
return
}
return
}
// 小程序 获取sechema 链接 通过 pay_channel_id 获取 微信小程序的appid 和 secret 生成 access_token 然后生成scheme
func (wm *WxMini) GetWxMiniScheme(param front.GetWxMiniSchemeRequest) (url string, err error) {
var (
has bool
repo = data.NewPayChannelRepo(paychannelmodel.GetInstance().GetDb())
payChannel = paychannelmodel.PayChannel{}
payConfig = paymentService.PayOrderRequest{}
)
// 获取支付渠道
if wm.payChannel == nil {
has, err = repo.PayChannelGet(&payChannel, builder.Eq{"id": param.PayChannelId})
if err != nil {
return
} else if !has {
err = fmt.Errorf("获取支付渠道不存在")
return
}
}
// 支付渠道支付配置解析
if configFun, ok := PayWayList[payChannel.ChannelType]; !ok {
err = fmt.Errorf("解析支付方式不存在")
return
} else {
err = configFun(&payConfig, &payChannel)
if err != nil {
return
}
}
if payConfig.Wx.Secret == "" {
err = fmt.Errorf("微信小程序的secret为空")
return
}
// 小程序的配置参数解析, 适配不同小程序配置需求
if param.JumpWxa.Query == "" {
err = json.Unmarshal([]byte(payChannel.ExtJson), &param.GenerateSchemeRequest)
if err != nil {
return
}
}
// 获取access_token
accessToken, err := wm.GetAccessToken(payChannel.AppId, payConfig.Wx.Secret)
if err != nil {
return
}
// 获取scheme
scheme, err := wm.generateScheme(accessToken, param.GenerateSchemeRequest)
return scheme, err
}
// 小程序支付 通过code换取网页授权access_tokenopenid,
func (wm *WxMini) GetWxAuthMini(param front.GetWxAuthRequest) (rsp front.GetWxAuthMiniResponse, err error) {
var (
has bool
payChannel = paychannelmodel.PayChannel{}
repo = data.NewPayChannelRepo(paychannelmodel.GetInstance().GetDb())
)
// 获取支付渠道的配置
has, err = repo.PayChannelGet(&payChannel, builder.Eq{"id": param.PayChannelId})
if err != nil {
return
} else if !has {
err = fmt.Errorf("获取支付渠道不存在")
return
}
// 配置支付的解析
wxConfig := make(map[string]interface{})
err = json.Unmarshal([]byte(payChannel.ExtJson), &wxConfig)
if err != nil {
return
}
sk := wxConfig["secret"].(string)
if sk == "" {
err = fmt.Errorf("微信小程序的secret为空")
return
}
// 小程序
targetUrl := fmt.Sprintf("https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code",
payChannel.AppId,
sk,
param.Code,
)
header := map[string]string{
"Content-Type": "application/json",
}
body := map[string]string{}
response, err := httpclient.FastHttpGet(targetUrl, header, body, 0)
if err != nil {
return
}
utils.Log(nil, "小程序获取微信授权信息", string(response), targetUrl)
// 解析返回数据
err = json.Unmarshal(response, &rsp)
return
}

View File

@ -58,7 +58,7 @@ func GetWxAuthUrl(param front.GetWxAuthUrlRequest) (targetUrl string, code int)
return return
} }
// // 通过code换取网页授权access_tokenopenid // // 通过code换取网页授权access_tokenopenid, 公众号网页支付
func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) { func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) {
// 获取支付渠道的配置 // 获取支付渠道的配置

View File

@ -0,0 +1,120 @@
package thirdpay
import (
"PaymentCenter/app/constants/common"
"PaymentCenter/app/constants/errorcode"
"PaymentCenter/app/http/entities/front"
"PaymentCenter/app/services"
"PaymentCenter/app/services/thirdpay/do"
"PaymentCenter/app/third/paymentService"
"PaymentCenter/app/third/paymentService/payCommon"
"PaymentCenter/app/utils"
"context"
"strconv"
"time"
)
// 小程序支付 通过code换取网页授权access_tokenopenid,
func GetWxAuthMini(param front.GetWxAuthRequest) (rsp front.GetWxAuthMiniResponse, code int) {
wx := do.NewWxMini()
rsp, err := wx.GetWxAuthMini(param)
code = handErr(err)
return
}
// 小程序 获取sechema 链接
func GetWxMiniSchemeService(param front.GetWxMiniSchemeRequest) (scheme string, code int) {
var err error
wx := do.NewWxMini()
scheme, err = wx.GetWxMiniScheme(param)
if err != nil {
code = handErr(err)
}
return scheme, code
}
// 微信小程序支付
func WxMiniPay(param front.WxJsApiPayRequest) (response front.WxMiniPayResponse, code int) {
var ctx = context.Background()
task := newWxJsapiPay(param)
// 1 获取订单
task.getOrder()
if task.code != errorcode.Success {
return response, task.code
}
// 获取支付渠道配置
task.getPayChannel()
if task.code != errorcode.Success {
return response, task.code
}
// 获取下单的请求参数
task.getOrderRequestLogs()
if task.code != errorcode.Success {
return response, task.code
}
// 2 通过code获取openid
rsp, code := GetWxAuthMini(front.GetWxAuthRequest{
Code: param.Code,
PayChannelId: strconv.Itoa(int(task.order.PayChannelId)),
})
if code != errorcode.Success {
response.ThirdMsg = rsp.Errmsg
return
}
task.openId = rsp.Openid
task.wxConfig.AppId = task.payChannel.AppId
order := task.order
// 通过openid订单数据请求微信下单, 获取prepay_id
orderRequest := paymentService.PayOrderRequest{
PayChannelId: order.PayChannelId,
OrderId: order.Id,
ChannelType: task.payChannel.ChannelType,
Description: order.Desc,
Amount: order.Amount,
PayerClientIp: param.ClientIp,
ReturnUrl: task.orderPayRequest.ReturnUrl,
Wx: task.wxConfig,
OpenId: task.openId,
}
res := paymentService.PaymentService(ctx, orderRequest)
// 下单失败
if res.Code != payCommon.PAY_SUCCESS_CODE {
task.code = errorcode.PrePayFail
response.ThirdMsg = res.ErrorMsg
return response, task.code
}
// 更新订单状态
order.Status = common.ORDER_STATUS_PAYING
task.code = services.OrderUpdate(order, "status")
if task.code != errorcode.Success {
utils.Log(nil, "成功下单,更新订单状态失败", order)
}
// 3 组装返回数据
response = front.WxMiniPayResponse{
AppId: task.payChannel.AppId,
TimeStamp: strconv.Itoa(int(time.Now().Unix())),
NonceStr: strconv.Itoa(int(time.Now().Unix())),
Package: "prepay_id=" + res.Result,
SignType: "RSA",
PaySign: "",
ThirdMsg: "",
}
// 4 签名
signValue, err := task.Sign(response.AppId, response.TimeStamp, response.NonceStr, response.Package)
if err != nil {
utils.Log(nil, "签名失败", err)
return response, errorcode.WechatAuthFail
}
response.PaySign = signValue
response.ReturnUrl = task.orderPayRequest.ReturnUrl
return response, task.code
}

View File

@ -47,7 +47,7 @@ type PayOrderResponse struct {
Result string `json:"result"` Result string `json:"result"`
} }
// PaymentService 统一发起支付 // 统一发起支付
func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrderResponse { func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrderResponse {
//logger.Info(c, "PaymentService 收到支付请求", payOrderRequest) //logger.Info(c, "PaymentService 收到支付请求", payOrderRequest)
var err error var err error
@ -60,8 +60,8 @@ func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrder
case payCommon.PAY_CHANNEL_ALIPAY_WEB: case payCommon.PAY_CHANNEL_ALIPAY_WEB:
// 支付宝H5支付 // 支付宝H5支付
info, err = ALiH5PayInfo(c, payOrderRequest) info, err = ALiH5PayInfo(c, payOrderRequest)
case payCommon.PAY_CHANNEL_WECHAT_JSAPI: case payCommon.PAY_CHANNEL_WECHAT_JSAPI, payCommon.PAY_CHANNEL_WECHAT_MINI:
// 微信JSAPI支付 // 微信JSAPI支付,JSAPI/小程序下单API
info, err = WxJsApiPayInfo(c, payOrderRequest) info, err = WxJsApiPayInfo(c, payOrderRequest)
case payCommon.PAY_CHANNEL_ALIPAY_PC: case payCommon.PAY_CHANNEL_ALIPAY_PC:
// 支付宝PC支付 // 支付宝PC支付

View File

@ -95,7 +95,7 @@ func WxH5PayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, er
return wxRsp.Response.H5Url, nil return wxRsp.Response.H5Url, nil
} }
// 微信JSAPI支付 // 微信JSAPI支付,JSAPI/小程序下单API
func WxJsApiPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) { func WxJsApiPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) {
if payOrderRequest.OpenId == "" { if payOrderRequest.OpenId == "" {
return "", errors.New("jsapi方式openId不能为空") return "", errors.New("jsapi方式openId不能为空")

1
go.mod
View File

@ -30,7 +30,6 @@ require (
github.com/swaggo/swag v1.7.9 github.com/swaggo/swag v1.7.9
github.com/tjfoc/gmsm v1.4.1 github.com/tjfoc/gmsm v1.4.1
github.com/valyala/fasthttp v1.31.0 github.com/valyala/fasthttp v1.31.0
github.com/wechatpay-apiv3/wechatpay-go v0.2.20
google.golang.org/grpc v1.56.3 google.golang.org/grpc v1.56.3
google.golang.org/protobuf v1.30.0 google.golang.org/protobuf v1.30.0
gopkg.in/go-playground/validator.v9 v9.31.0 gopkg.in/go-playground/validator.v9 v9.31.0

4
go.sum
View File

@ -57,8 +57,6 @@ github.com/VividCortex/gohistogram v1.0.0/go.mod h1:Pf5mBqqDxYaXu3hDrrU+w6nw50o/
github.com/ZZMarquis/gm v1.3.2 h1:lFtpzg5zeeVMZ/gKi0gtYcKLBEo9XTqsZDHDz6s3Gow= github.com/ZZMarquis/gm v1.3.2 h1:lFtpzg5zeeVMZ/gKi0gtYcKLBEo9XTqsZDHDz6s3Gow=
github.com/ZZMarquis/gm v1.3.2/go.mod h1:wWbjZYgruQVd7Bb8UkSN8ujU931kx2XUW6nZLCiDE0Q= github.com/ZZMarquis/gm v1.3.2/go.mod h1:wWbjZYgruQVd7Bb8UkSN8ujU931kx2XUW6nZLCiDE0Q=
github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c= github.com/afex/hystrix-go v0.0.0-20180502004556-fa1af6a1f4f5/go.mod h1:SkGFH1ia65gfNATL8TAiHDNxPzPdmEL5uirI2Uyuz6c=
github.com/agiledragon/gomonkey v2.0.2+incompatible h1:eXKi9/piiC3cjJD1658mEE2o3NjkJ5vDLgYjCQu0Xlw=
github.com/agiledragon/gomonkey v2.0.2+incompatible/go.mod h1:2NGfXu1a80LLr2cmWXGBDaHEjb1idR6+FVlX5T3D9hw=
github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs= github.com/agiledragon/gomonkey/v2 v2.3.1 h1:k+UnUY0EMNYUFUAQVETGY9uUTxjMdnUkP0ARyJS1zzs=
github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY= github.com/agiledragon/gomonkey/v2 v2.3.1/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
github.com/ahmetb/go-linq/v3 v3.2.0 h1:BEuMfp+b59io8g5wYzNoFe9pWPalRklhlhbiU3hYZDE= github.com/ahmetb/go-linq/v3 v3.2.0 h1:BEuMfp+b59io8g5wYzNoFe9pWPalRklhlhbiU3hYZDE=
@ -758,8 +756,6 @@ github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPU
github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4= github.com/valyala/fasttemplate v1.2.1 h1:TVEnxayobAdVkhQfrfes2IzOB6o+z4roRkPF52WA1u4=
github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ= github.com/valyala/fasttemplate v1.2.1/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc= github.com/valyala/tcplisten v1.0.0/go.mod h1:T0xQ8SeCZGxckz9qRXTfG43PvQ/mcWh7FwZEA7Ioqkc=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20 h1:gS8oFn1bHGnyapR2Zb4aqTV6l4kJWgbtqjCq6k1L9DQ=
github.com/wechatpay-apiv3/wechatpay-go v0.2.20/go.mod h1:A254AUBVB6R+EqQFo3yTgeh7HtyqRRtN2w9hQSOrd4Q=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=