Browse Source

增加发送模板消息

master v0.5.0
guzeng 1 year ago
parent
commit
38520a86e7
5 changed files with 152 additions and 20 deletions
  1. +26
    -1
      common.go
  2. +9
    -11
      micropay.go
  3. +60
    -0
      mp.go
  4. +46
    -0
      mp_test.go
  5. +11
    -8
      url.go

+ 26
- 1
common.go View File

@ -3,10 +3,11 @@ package wechat
import (
"crypto/md5"
"encoding/hex"
"net"
"strings"
)
//密码加密
// 密码加密
func Md5Str(str ...string) string {
var build strings.Builder
@ -24,3 +25,27 @@ func Md5Str(str ...string) string {
sMd5 := hex.EncodeToString(cipher2Str) // 输出加密结果
return sMd5
}
/**
* 取本地IP
*/
func GetLocalIp() string {
addrs, err := net.InterfaceAddrs()
if err != nil {
return ""
}
for _, address := range addrs {
// 检查ip地址判断是否回环地址
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil && !ipnet.IP.IsLinkLocalUnicast() {
return ipnet.IP.String()
}
}
}
return ""
}

+ 9
- 11
micropay.go View File

@ -8,12 +8,10 @@ import (
"reflect"
"strings"
"git.tetele.net/tgo/network"
"git.tetele.net/tgo/helper"
)
//请求支付
// 请求支付
type PayXml struct {
XMLName xml.Name `xml:"xml"`
Appid string `xml:"appid"`
@ -28,7 +26,7 @@ type PayXml struct {
AuthCode string `xml:"auth_code"`
}
//支付结果
// 支付结果
type PayReturnXml struct {
ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
@ -57,7 +55,7 @@ type PayReturnXml struct {
PromotionDetail string `xml:"promotion_detail"`
}
//查询支付
// 查询支付
type QueryXml struct {
XMLName xml.Name `xml:"xml"`
Appid string `xml:"appid"`
@ -67,7 +65,7 @@ type QueryXml struct {
Sign string `xml:"sign"`
}
//查询结果
// 查询结果
type QueryReturnXml struct {
ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
@ -108,7 +106,7 @@ type ReverseXml struct {
Sign string `xml:"sign"`
}
//撤消结果
// 撤消结果
type ReverseReturnXml struct {
ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
@ -147,7 +145,7 @@ func MicroPay(appid, mchid, mch_key, device_info, body, out_trade_no, auth_code,
requestxml.Body = body
requestxml.OutTradeNo = out_trade_no
requestxml.TotalFee = helper.ToInt(helper.FloatMul(total_fee, 100))
requestxml.SpbillCreateIp = network.GetLocalIp()
requestxml.SpbillCreateIp = GetLocalIp()
requestxml.AuthCode = auth_code
signStr := helper.StringJoin("appid=", requestxml.Appid, "&auth_code=", requestxml.AuthCode,
@ -165,7 +163,7 @@ func MicroPay(appid, mchid, mch_key, device_info, body, out_trade_no, auth_code,
log.Println(requestxml, string(reqXmlJson), err)
url := "https://api.mch.weixin.qq.com/pay/micropay"
ret, err := network.SendXml("POST", url, requestxml)
ret, err := SendXml("POST", url, requestxml)
log.Println("wechat micropay pay result:", string(ret), err)
@ -222,7 +220,7 @@ func MicroPayQuery(appid, mchid, out_trade_no, mch_key string) (QueryReturnXml,
requestxml.Sign = strings.ToUpper(signMd5)
url := "https://api.mch.weixin.qq.com/pay/orderquery"
ret, err := network.SendXml("POST", url, requestxml)
ret, err := SendXml("POST", url, requestxml)
if err != nil {
log.Println("Err:", err)
@ -280,7 +278,7 @@ func MicroPayReverse(appid, mchid, out_trade_no, mch_key string) (ReverseReturnX
requestxml.Sign = strings.ToUpper(signMd5)
url := "https://api.mch.weixin.qq.com/secapi/pay/reverse"
ret, err := network.SendXml("POST", url, requestxml)
ret, err := SendXml("POST", url, requestxml)
if err != nil {
log.Println("Err:", err)


+ 60
- 0
mp.go View File

@ -0,0 +1,60 @@
package wechat
import (
"errors"
"fmt"
)
type wx_template_msg_res struct {
Errcode int `json:"errcode"`
Errmsg string `json:"errmsg"`
msgid int `json:"msgid"`
}
func SendTemplateMessage(access_token string, touser, template_id, url string, data map[string]interface{}, client_msg_id, miniapp_appid, miniapp_pagepath string) (wx_template_msg_res, error) {
var res wx_template_msg_res
if touser == "" {
return res, errors.New("缺少用户openid")
}
if template_id == "" {
return res, errors.New("缺少消息模板")
}
if access_token == "" {
return res, errors.New("缺少access token")
}
api_url := fmt.Sprintf(MP_TEMPLATE_MESSAGE_API, access_token)
msg := map[string]interface{}{
"touser": touser,
"template_id": template_id,
"url": url,
"data": data,
}
if client_msg_id != "" {
msg["client_msg_id"] = client_msg_id
}
if miniapp_appid != "" {
msg["miniprogram"] = map[string]string{
"appid": miniapp_appid,
"pagepath": miniapp_pagepath,
}
}
msg_json, err := json.Marshal(msg)
if err != nil {
return res, err
}
data_byte, err := PostJson(api_url, msg_json)
if err == nil {
err = json.Unmarshal(data_byte, &res)
}
return res, err
}

+ 46
- 0
mp_test.go View File

@ -0,0 +1,46 @@
package wechat
import (
"testing"
)
func Test_SendTemplateMessage(t *testing.T) {
// appid := "wxedaca3ab498ec6c0"
// appsecret := "6c7e567181dba2fe23692339d19ee16a"
touser := "o4AH1jm_rnjDV4-4nsFhGhk4wIEQ"
template_id := "avBk4QTEoA17c4G72XHet9gpGQtonW0ck2ewQWSsUwU"
url := "https://shopv2.tetele.net"
data := map[string]interface{}{
"first": map[string]interface{}{
"value": "已预约成功",
},
"keyword1": map[string]interface{}{
"value": "巧克力",
},
"keyword2": map[string]interface{}{
"value": "2014年9月22日",
},
"remark": map[string]interface{}{
"value": "请点击详情",
},
}
client_msg_id := ""
miniapp_appid := ""
miniapp_pagepath := ""
// mpAT, err := GetAccessToken(appid, appsecret)
// t.Log("access token:", mpAT)
// if err==nil{
// access_token = mpAT..AccessToken
// }
// if err != nil {
// t.Error("access token error:", err)
// }
access_token := "71_sgGezbuBtu94tgRuhzSJHiDvgoOI2mS5kpYyeaynnvILmpPPHEclUmhKq74fj0M3HRjZk7hcNfB54tAJvNZPOrZleXQX2dyWZm_8tyu5m1YpAb8qLrwRnUNRdowMJXhAIAVSG"
ret, err := SendTemplateMessage(access_token, touser, template_id, url, data, client_msg_id, miniapp_appid, miniapp_pagepath)
t.Log(ret)
t.Log(err)
}

+ 11
- 8
url.go View File

@ -6,28 +6,31 @@ import (
var json = jsoniter.ConfigCompatibleWithStandardLibrary
//获取access token
// 获取access token
const ACCESS_TOKEN_API string = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s"
//小程序发送统一服务消息
// 小程序发送统一服务消息
const MINIAPP_UNIFORM_MESSAGE_API string = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=%s"
//小程序获取openid
// 小程序获取openid
const GET_MINIAPP_OPENID_API string = "https://api.weixin.qq.com/sns/jscode2session?appid=%s&secret=%s&js_code=%s&grant_type=authorization_code"
//公众号获取openid
// 公众号获取openid
const GET_MP_OPENID_API string = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
//小程序发送订阅消息
// 小程序发送订阅消息
const MINIAPP_SUBSCRIBE_MESSAGE_SEND_API string = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=%s"
//app获取openid
// app获取openid
const GET_APP_OPENID string = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=%s&secret=%s&code=%s&grant_type=authorization_code"
const GET_MINIAPP_QRCODE string = "https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=%s"
//公众号授权
// 公众号授权
const OFFICAL_ACCOUNT_AUTHORIZATION_URL string = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=%s&redirect_uri=%s&response_type=code&scope=snsapi_userinfo&state=%s#wechat_redirect"
//公众号获取用户信息
// 公众号获取用户信息
const MP_USERINFO_API string = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid=%s&lang=%s"
// 公众号模板消息
const MP_TEMPLATE_MESSAGE_API string = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s"

Loading…
Cancel
Save