209 lines
5.4 KiB
Go
209 lines
5.4 KiB
Go
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
|
||
}
|