feat: wxmini
This commit is contained in:
parent
3f26ffa8cb
commit
8ce5ead203
|
@ -104,6 +104,7 @@ const (
|
|||
// 微信授权
|
||||
WechatAuthFail = 1901
|
||||
WechatAuthSignFail = 1902
|
||||
WechatPayError = 1903
|
||||
|
||||
ClientEnvErr = 2000
|
||||
)
|
||||
|
@ -194,6 +195,7 @@ var MsgZH = map[int]string{
|
|||
WechatAuthSignFail: "微信签名失败",
|
||||
ClientEnvErr: "支付环境错误",
|
||||
OrderPayRequestAcquireLock: "系统繁忙,请稍后再试",
|
||||
WechatPayError: "微信支付配置错误",
|
||||
}
|
||||
var MsgMap map[string]map[int]string = map[string]map[int]string{"en": MsgZH}
|
||||
|
||||
|
|
|
@ -201,7 +201,7 @@ func GetWxAuthUrl(c *gin.Context) {
|
|||
controllers.HandCodeRes(c, url, code)
|
||||
}
|
||||
|
||||
// 通过code获取授权,openid
|
||||
// 通过code获取授权,openid, 微信公众号 使用
|
||||
func GetWxAuth(c *gin.Context) {
|
||||
req, _ := controllers.GetRequest(c).(*front.GetWxAuthRequest)
|
||||
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)
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ type GetWxAuthRequest struct {
|
|||
PayChannelId string `json:"state" form:"state"`
|
||||
}
|
||||
|
||||
// 获取微信用户信息
|
||||
// 获取微信用户信息, 微信公众号
|
||||
type GetWxAuthResponse struct {
|
||||
AccessToken string `json:"access_token"` //网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同
|
||||
ExpiresIn int `json:"expires_in"` //access_token接口调用凭证超时时间,单位(秒)
|
||||
|
@ -20,6 +20,15 @@ type GetWxAuthResponse struct {
|
|||
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支付
|
||||
type WxJsApiPayRequest struct {
|
||||
Code string `json:"code" form:"code" `
|
||||
|
@ -44,3 +53,27 @@ type WxJsApiPayResponse struct {
|
|||
ThirdMsg string `json:"third_msg"`
|
||||
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
|
||||
}
|
||||
|
|
|
@ -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"`
|
||||
}
|
|
@ -19,15 +19,17 @@ var FrontRequestMap = map[string]func() (validForm interface{}, isSaveLog bool){
|
|||
|
||||
var FrontRequestMapBeforeDecrypt = map[string]func() interface{}{
|
||||
|
||||
common.FRONT_V1 + "/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/query": func() interface{} { return new(front.RequestBody) },
|
||||
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/getWxAuthUrl": func() interface{} { return new(front.GetWxAuthUrlRequest) },
|
||||
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 + "/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/query": func() interface{} { return new(front.RequestBody) },
|
||||
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/getWxAuthUrl": func() interface{} { return new(front.GetWxAuthUrlRequest) },
|
||||
common.FRONT_V1 + "/wx/getWxAuth": 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/submit": func() interface{} { return new(front.GetPayLinkRequest) },
|
||||
|
|
|
@ -70,9 +70,12 @@ func RegisterRoute(router *gin.Engine) {
|
|||
router.LoadHTMLGlob("./front/templates/*")
|
||||
wx := v1.Group("/wx", middlewares.ValidateRequest())
|
||||
{
|
||||
wx.POST("/getWxAuthUrl", front.GetWxAuthUrl) // 获取授权codeUrl
|
||||
wx.GET("/getWxAuth", front.GetWxAuth) // 获取openId
|
||||
wx.GET("/getCode", front.GetWxCode) // 接收微信code
|
||||
wx.POST("/getWxAuthUrl", front.GetWxAuthUrl) // 获取授权codeUrl
|
||||
wx.GET("/getWxAuth", front.GetWxAuth) // 获取openId, 公众号授权
|
||||
wx.GET("/getCode", front.GetWxCode) // 接收微信code
|
||||
wx.POST("/getScheme", front.GetWxMiniScheme) // 小程序 获取加密scheme码
|
||||
wx.GET("/getWxAuthMini", front.GetWxAuthMini) // 小程序 获取openId, 授权
|
||||
wx.POST("/wxMini", front.WxMiniPay) // 小程序 获取支付参数
|
||||
}
|
||||
|
||||
// 微信jsapi支付链接
|
||||
|
|
|
@ -3,6 +3,8 @@ package do
|
|||
import (
|
||||
"PaymentCenter/app/constants/common"
|
||||
"PaymentCenter/app/constants/errorcode"
|
||||
"PaymentCenter/app/http/entities/front"
|
||||
|
||||
"PaymentCenter/app/models/merchantmodel"
|
||||
"PaymentCenter/app/models/paychannelmodel"
|
||||
"PaymentCenter/app/services"
|
||||
|
@ -124,6 +126,8 @@ func (w *Pay) PayUrl() (url string) {
|
|||
w.PayCode = errorcode.PayChannelExtJsonError
|
||||
return
|
||||
}
|
||||
|
||||
// 根据渠道类型,调用对应的支付方式
|
||||
switch w.PayParam.Channel.ChannelType {
|
||||
// 微信公众号支付,返回的是用户授权链接
|
||||
case common.PAY_CHANNEL_WECHAT_JSAPI:
|
||||
|
@ -138,13 +142,30 @@ func (w *Pay) PayUrl() (url string) {
|
|||
if 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:
|
||||
w.PayCode = errorcode.PayChannelNotBuild
|
||||
return
|
||||
}
|
||||
|
||||
//res := paymentService.PaymentService(*w.ctx, *thirdPay)
|
||||
|
||||
if res.Code == payCommon.PAY_SUCCESS_CODE {
|
||||
w.Order.Status = common.ORDER_STATUS_PAYING
|
||||
code := services.OrderUpdate(w.Order, "status")
|
||||
|
|
|
@ -13,6 +13,7 @@ var PayWayList = map[int]func(commonPayInfo *paymentService.PayOrderRequest, cha
|
|||
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWeb,
|
||||
common.PAY_CHANNEL_ALIPAY_PC: AlipayWeb,
|
||||
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPI,
|
||||
common.PAY_CHANNEL_WECHAT_MINI: WechatJSAPI,
|
||||
}
|
||||
|
||||
func WechatH5(commonPayInfo *paymentService.PayOrderRequest, channel *paychannelmodel.PayChannel) error {
|
||||
|
|
|
@ -10,7 +10,9 @@ import (
|
|||
var RefundWayList = map[int]func(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error{
|
||||
common.PAY_CHANNEL_WECHAT_H5: WechatH5Refund,
|
||||
common.PAY_CHANNEL_ALIPAY_WEB: AlipayWebRefund,
|
||||
common.PAY_CHANNEL_ALIPAY_PC: AlipayWebRefund,
|
||||
common.PAY_CHANNEL_WECHAT_JSAPI: WechatJSAPIRefund,
|
||||
common.PAY_CHANNEL_WECHAT_MINI: WechatJSAPIRefund,
|
||||
}
|
||||
|
||||
func WechatH5Refund(commonRefundInfo *paymentService.OrderRefundRequest, channel *paychannelmodel.PayChannel) error {
|
||||
|
|
|
@ -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), ¶m.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_token,openid,
|
||||
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
|
||||
}
|
|
@ -58,7 +58,7 @@ func GetWxAuthUrl(param front.GetWxAuthUrlRequest) (targetUrl string, code int)
|
|||
return
|
||||
}
|
||||
|
||||
// // 通过code换取网页授权access_token,openid
|
||||
// // 通过code换取网页授权access_token,openid, 公众号网页支付
|
||||
func GetWxAuth(param front.GetWxAuthRequest) (rsp front.GetWxAuthResponse, code int) {
|
||||
|
||||
// 获取支付渠道的配置
|
||||
|
|
|
@ -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_token,openid,
|
||||
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
|
||||
}
|
|
@ -47,7 +47,7 @@ type PayOrderResponse struct {
|
|||
Result string `json:"result"`
|
||||
}
|
||||
|
||||
// PaymentService 统一发起支付
|
||||
// 统一发起支付
|
||||
func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrderResponse {
|
||||
//logger.Info(c, "PaymentService 收到支付请求", payOrderRequest)
|
||||
var err error
|
||||
|
@ -60,8 +60,8 @@ func PaymentService(c context.Context, payOrderRequest PayOrderRequest) PayOrder
|
|||
case payCommon.PAY_CHANNEL_ALIPAY_WEB:
|
||||
// 支付宝H5支付
|
||||
info, err = ALiH5PayInfo(c, payOrderRequest)
|
||||
case payCommon.PAY_CHANNEL_WECHAT_JSAPI:
|
||||
// 微信JSAPI支付
|
||||
case payCommon.PAY_CHANNEL_WECHAT_JSAPI, payCommon.PAY_CHANNEL_WECHAT_MINI:
|
||||
// 微信JSAPI支付,JSAPI/小程序下单API
|
||||
info, err = WxJsApiPayInfo(c, payOrderRequest)
|
||||
case payCommon.PAY_CHANNEL_ALIPAY_PC:
|
||||
// 支付宝PC支付
|
||||
|
|
|
@ -95,7 +95,7 @@ func WxH5PayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, er
|
|||
return wxRsp.Response.H5Url, nil
|
||||
}
|
||||
|
||||
// 微信JSAPI支付
|
||||
// 微信JSAPI支付,JSAPI/小程序下单API
|
||||
func WxJsApiPayInfo(c context.Context, payOrderRequest PayOrderRequest) (string, error) {
|
||||
if payOrderRequest.OpenId == "" {
|
||||
return "", errors.New("jsapi方式openId不能为空")
|
||||
|
|
1
go.mod
1
go.mod
|
@ -30,7 +30,6 @@ require (
|
|||
github.com/swaggo/swag v1.7.9
|
||||
github.com/tjfoc/gmsm v1.4.1
|
||||
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/protobuf v1.30.0
|
||||
gopkg.in/go-playground/validator.v9 v9.31.0
|
||||
|
|
4
go.sum
4
go.sum
|
@ -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/go.mod h1:wWbjZYgruQVd7Bb8UkSN8ujU931kx2XUW6nZLCiDE0Q=
|
||||
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/go.mod h1:ap1AmDzcVOAz1YpeJ3TCzIgstoaWLA6jbbgxfB4w2iY=
|
||||
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/go.mod h1:KHLXt3tVN2HBp8eijSv/kGJopbvo7S+qRAEEKiv+SiQ=
|
||||
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/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
|
|
Loading…
Reference in New Issue