From 38520a86e783a940f93e0fce3bca42d91a8150be Mon Sep 17 00:00:00 2001 From: guzeng Date: Wed, 9 Aug 2023 18:21:51 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=91=E9=80=81=E6=A8=A1?= =?UTF-8?q?=E6=9D=BF=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- common.go | 27 +++++++++++++++++++++++- micropay.go | 20 ++++++++---------- mp.go | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++ mp_test.go | 46 ++++++++++++++++++++++++++++++++++++++++ url.go | 19 ++++++++++------- 5 files changed, 152 insertions(+), 20 deletions(-) create mode 100644 mp.go create mode 100644 mp_test.go diff --git a/common.go b/common.go index 75fc2dd..bd6c3ba 100644 --- a/common.go +++ b/common.go @@ -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 "" +} diff --git a/micropay.go b/micropay.go index 055b784..829befc 100644 --- a/micropay.go +++ b/micropay.go @@ -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) diff --git a/mp.go b/mp.go new file mode 100644 index 0000000..ec9d42a --- /dev/null +++ b/mp.go @@ -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 +} diff --git a/mp_test.go b/mp_test.go new file mode 100644 index 0000000..a99d4f0 --- /dev/null +++ b/mp_test.go @@ -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) +} diff --git a/url.go b/url.go index c2bcb94..b9886e6 100644 --- a/url.go +++ b/url.go @@ -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"