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()) payConfig = paymentService.PayOrderRequest{} ) // 获取支付渠道 if wm.payChannel == nil { payChannel := paychannelmodel.PayChannel{} has, err = repo.PayChannelGet(&payChannel, builder.Eq{"id": param.PayChannelId}) if err != nil { return } else if !has { err = fmt.Errorf("获取支付渠道不存在") return } wm.payChannel = &payChannel } // 支付渠道支付配置解析 if configFun, ok := PayWayList[wm.payChannel.ChannelType]; !ok { err = fmt.Errorf("解析支付方式不存在") return } else { err = configFun(&payConfig, wm.payChannel) if err != nil { return } } if payConfig.Wx.Secret == "" { err = fmt.Errorf("微信小程序的secret为空") return } // 小程序的配置参数解析, 适配不同小程序配置需求 if param.JumpWxa.Query == "" { err = json.Unmarshal([]byte(wm.payChannel.ExtJson), ¶m.GenerateSchemeRequest) if err != nil { return } } // 获取access_token accessToken, err := wm.GetAccessToken(wm.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 } // 小程序 获取加密URLLink func (wm *WxMini) generateUrlLink(accessToken string, param front.GenerateUrlLinkRequest) (url string, err error) { var ( targetUrl = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=" + accessToken header = map[string]string{ "Content-Type": "application/json", } body []byte ) type UrlLinkResponse struct { Errcode int `json:"errcode"` Errmsg string `json:"errmsg"` UrlLink string `json:"url_link"` } body, err = json.Marshal(param) if err != nil { return } // 发送请求 response, err := httpclient.FastHttpPost(targetUrl, header, body, 0) if err != nil { err = fmt.Errorf("GenerateUrlLink 获取加密scheme码 err:%s", err.Error()) return } utils.Log(nil, "GenerateUrlLink 获取加密scheme码 ", "response ="+string(response)) var rsp UrlLinkResponse err = json.Unmarshal(response, &rsp) if err != nil { err = fmt.Errorf("GenerateUrlLink 获取加密scheme码 err:%s", err.Error()) return } else if rsp.Errcode != 0 { err = fmt.Errorf("GenerateUrlLink 获取加密scheme码 code:%d err:%s", rsp.Errcode, rsp.Errmsg) return } return }