|
@@ -1,6 +1,7 @@
|
|
|
package go_pay
|
|
package go_pay
|
|
|
|
|
|
|
|
import (
|
|
import (
|
|
|
|
|
+ "bytes"
|
|
|
"crypto/md5"
|
|
"crypto/md5"
|
|
|
"encoding/hex"
|
|
"encoding/hex"
|
|
|
"fmt"
|
|
"fmt"
|
|
@@ -9,15 +10,25 @@ import (
|
|
|
"strings"
|
|
"strings"
|
|
|
)
|
|
)
|
|
|
|
|
|
|
|
-/*
|
|
|
|
|
- NecessaryParams: 必传参数
|
|
|
|
|
- DeviceInfo: 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
|
|
|
|
|
- Openid: 用户标识: trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
|
|
|
|
|
-*/
|
|
|
|
|
-type WechatParams struct {
|
|
|
|
|
- NecessaryParams WechatParamsNecessary
|
|
|
|
|
- DeviceInfo string `xml:"device_info"`
|
|
|
|
|
- Openid string `xml:"openid"`
|
|
|
|
|
|
|
+type WXReq map[string]string
|
|
|
|
|
+
|
|
|
|
|
+//获取参数
|
|
|
|
|
+func (w WXReq) Get(key string) string {
|
|
|
|
|
+ if w == nil {
|
|
|
|
|
+ return ""
|
|
|
|
|
+ }
|
|
|
|
|
+ ws := w[key]
|
|
|
|
|
+ return ws
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//设置参数
|
|
|
|
|
+func (w WXReq) Set(key string, value string) {
|
|
|
|
|
+ w[key] = value
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//删除参数
|
|
|
|
|
+func (w WXReq) Remove(key string) {
|
|
|
|
|
+ delete(w, key)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -41,9 +52,51 @@ type WechatParamsNecessary struct {
|
|
|
TradeType string `xml:"trade_type"`
|
|
TradeType string `xml:"trade_type"`
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+/*
|
|
|
|
|
+ NecessaryParams: 必传参数
|
|
|
|
|
+ DeviceInfo: 自定义参数,可以为终端设备号(门店号或收银设备ID),PC网页或公众号内支付可以传"WEB"
|
|
|
|
|
+ SignType: 签名类型,默认为MD5,支持HMAC-SHA256和MD5。
|
|
|
|
|
+ Detail: 商品详细描述,对于使用单品优惠的商户,字段必须按照规范上传
|
|
|
|
|
+ Attach: 附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用
|
|
|
|
|
+ FeeType: 符合ISO 4217标准的三位字母代码,默认人民币:CNY
|
|
|
|
|
+ TimeStart: 订单生成时间,格式为yyyyMMddHHmmss,如2009年12月25日9点10分10秒表示为20091225091010
|
|
|
|
|
+ TimeExpire: 订单失效时间,格式为yyyyMMddHHmmss,如2009年12月27日9点10分10秒表示为20091227091010。订单失效时间是针对订单号而言的,由于在请求支付的时候有一个必传参数prepay_id只有两小时的有效期,所以在重入时间超过2小时的时候需要重新请求下单接口获取新的prepay_id
|
|
|
|
|
+ GoodsTag: 订单优惠标记,使用代金券或立减优惠功能时需要的参数
|
|
|
|
|
+ ProductId: trade_type=NATIVE时,此参数必传。此参数为二维码中包含的商品ID,商户自行定义
|
|
|
|
|
+ LimitPay: 上传此参数 no_credit 可限制用户不能使用信用卡支付
|
|
|
|
|
+ Openid: 用户标识: trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
|
|
|
|
|
+ Receipt: Y,传入Y时,支付成功消息和支付详情页将出现开票入口。需要在微信支付商户平台或微信公众平台开通电子发票功能,传此字段才可生效
|
|
|
|
|
+ SceneInfo: 该字段常用于线下活动时的场景信息上报,支持上报实际门店信息,商户也可以按需求自己上报相关信息。该字段为JSON对象数据,对象格式为{"store_info":{"id": "门店ID","name": "名称","area_code": "编码","address": "地址" }}
|
|
|
|
|
+ StoreInfo: SceneInfo 的字段信息
|
|
|
|
|
+*/
|
|
|
|
|
+type WechatParams struct {
|
|
|
|
|
+ NecessaryParams WechatParamsNecessary
|
|
|
|
|
+ DeviceInfo string `xml:"device_info"`
|
|
|
|
|
+ SignType string `xml:"sign_type"`
|
|
|
|
|
+ Detail string `xml:"detail"`
|
|
|
|
|
+ Attach string `xml:"attach"`
|
|
|
|
|
+ FeeType string `xml:"fee_type"`
|
|
|
|
|
+ TimeStart string `xml:"time_start"`
|
|
|
|
|
+ TimeExpire string `xml:"time_expire"`
|
|
|
|
|
+ GoodsTag string `xml:"goods_tag"`
|
|
|
|
|
+ ProductId string `xml:"product_id"`
|
|
|
|
|
+ LimitPay string `xml:"limit_pay"`
|
|
|
|
|
+ Openid string `xml:"openid"`
|
|
|
|
|
+ Receipt string `xml:"receipt"`
|
|
|
|
|
+ SceneInfo string `xml:"scene_info"`
|
|
|
|
|
+ StoreInfo StoreInfo `xml:"-"`
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+//StoreInfo: SceneInfo 的字段信息
|
|
|
|
|
+type StoreInfo struct {
|
|
|
|
|
+ Id string `json:"id"` // 门店唯一标识
|
|
|
|
|
+ Name string `json:"name"` // 门店名称
|
|
|
|
|
+ AreaCode string `json:"area_code"` // 门店所在地行政区划码,详细见《最新县及县以上行政区划代码》
|
|
|
|
|
+ Address string `json:"address"` // 门店详细地址
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
//获取Sign签名
|
|
//获取Sign签名
|
|
|
func getSign(secretKey string, params *WechatParams) string {
|
|
func getSign(secretKey string, params *WechatParams) string {
|
|
|
-
|
|
|
|
|
paramMap := make(map[string]string, 0)
|
|
paramMap := make(map[string]string, 0)
|
|
|
paramMap["appid"] = params.NecessaryParams.Appid
|
|
paramMap["appid"] = params.NecessaryParams.Appid
|
|
|
paramMap["mch_id"] = params.NecessaryParams.MchId
|
|
paramMap["mch_id"] = params.NecessaryParams.MchId
|
|
@@ -77,12 +130,17 @@ func getSignString(secretKey string, paramMap map[string]string) string {
|
|
|
keyList = append(keyList, k)
|
|
keyList = append(keyList, k)
|
|
|
}
|
|
}
|
|
|
sort.Strings(keyList)
|
|
sort.Strings(keyList)
|
|
|
- stringA := ""
|
|
|
|
|
|
|
+ buffer := new(bytes.Buffer)
|
|
|
for _, k := range keyList {
|
|
for _, k := range keyList {
|
|
|
- stringA += k + "=" + paramMap[k] + "&"
|
|
|
|
|
|
|
+ buffer.WriteString(k)
|
|
|
|
|
+ buffer.WriteString("=")
|
|
|
|
|
+ buffer.WriteString(paramMap[k])
|
|
|
|
|
+ buffer.WriteString("&")
|
|
|
}
|
|
}
|
|
|
- stringA += "key=" + secretKey
|
|
|
|
|
- return stringA
|
|
|
|
|
|
|
+ buffer.WriteString("key=")
|
|
|
|
|
+ buffer.WriteString(secretKey)
|
|
|
|
|
+ return buffer.String()
|
|
|
|
|
+
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
func generateXml(m map[string]string) string {
|
|
func generateXml(m map[string]string) string {
|