Jerry 7 роки тому
коміт
6aeba776d1
10 змінених файлів з 193 додано та 0 видалено
  1. 1 0
      .gitignore
  2. 3 0
      README.md
  3. 5 0
      ali_pay.go
  4. 1 0
      ali_pay_test.go
  5. 10 0
      constant.go
  6. 10 0
      message.go
  7. 21 0
      util.go
  8. 95 0
      wechat_params.go
  9. 20 0
      wechat_pay.go
  10. 27 0
      wechat_pay_test.go

+ 1 - 0
.gitignore

@@ -0,0 +1 @@
+/.idea

+ 3 - 0
README.md

@@ -0,0 +1,3 @@
+# Golang Pay
+
+GO 支付相关SDK

+ 5 - 0
ali_pay.go

@@ -0,0 +1,5 @@
+package go_pay
+
+func AliPay() {
+
+}

+ 1 - 0
ali_pay_test.go

@@ -0,0 +1 @@
+package go_pay

+ 10 - 0
constant.go

@@ -0,0 +1,10 @@
+package go_pay
+
+const (
+	WechatPayUrl         = "https://api.mch.weixin.qq.com/pay/unifiedorder"
+	WechatPayType_Mini   = "JSAPI"
+	WechatPayType_JsApi  = "JSAPI"
+	WechatPayType_App    = "APP"
+	WechatPayType_H5     = "MWEB"
+	WechatPayType_Native = "NATIVE"
+)

+ 10 - 0
message.go

@@ -0,0 +1,10 @@
+package go_pay
+
+type ErrorMessage struct {
+	ErrorCode int    `json:"error_code"`
+	ErrorDesc string `json:"error_desc"`
+}
+
+type SuccessMessage struct {
+	Msg string `json:"msg"`
+}

+ 21 - 0
util.go

@@ -0,0 +1,21 @@
+package go_pay
+
+import (
+	"math/rand"
+	"time"
+)
+
+/*
+	获取随机字符串
+	length:字符串长度
+*/
+func GetRandomString(length int) string {
+	str := "0123456789AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz"
+	bytes := []byte(str)
+	var result []byte
+	r := rand.New(rand.NewSource(time.Now().UnixNano()))
+	for i := 0; i < length; i++ {
+		result = append(result, bytes[r.Intn(len(bytes))])
+	}
+	return string(result)
+}

+ 95 - 0
wechat_params.go

@@ -0,0 +1,95 @@
+package go_pay
+
+import (
+	"crypto/md5"
+	"encoding/hex"
+	"fmt"
+	"sort"
+	"strconv"
+	"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"`
+}
+
+/*
+	NonceStr: 随机字符串,长度要求在32位以内(如不写,go-pay将为你随机生成)
+	Body: 商品简单描述
+	OutTradeNo: 商户系统内部订单号,要求32个字符内,只能是数字、大小写字母_-|*且在同一个商户号下唯一
+	TotalFee: 订单总金额,单位为分
+	SpbillCreateIp: 支持IPV4和IPV6两种格式的IP地址。调用微信支付API的机器IP
+	NotifyUrl: 异步接收微信支付结果通知的回调地址,通知url必须为外网可访问的url,不能携带参数
+	TradeType: 交易类型:(JSAPI--JSAPI支付(或小程序支付)、NATIVE--Native支付、APP--app支付,MWEB--H5支付,不同trade_type决定了调起支付的方式)
+*/
+type WechatParamsNecessary struct {
+	Appid          string `xml:"appid"`
+	MchId          string `xml:"mch_id"`
+	NonceStr       string `xml:"nonce_str"`
+	Body           string `xml:"body"`
+	OutTradeNo     string `xml:"out_trade_no"`
+	TotalFee       int    `xml:"total_fee"`
+	SpbillCreateIp string `xml:"spbill_create_ip"`
+	NotifyUrl      string `xml:"notify_url"`
+	TradeType      string `xml:"trade_type"`
+}
+
+//获取Sign签名
+func getSign(secretKey string, params *WechatParams) string {
+
+	paramMap := make(map[string]string, 0)
+	paramMap["appid"] = params.NecessaryParams.Appid
+	paramMap["mch_id"] = params.NecessaryParams.MchId
+	paramMap["nonce_str"] = params.NecessaryParams.NonceStr
+	paramMap["body"] = params.NecessaryParams.Body
+	paramMap["out_trade_no"] = params.NecessaryParams.OutTradeNo
+	paramMap["total_fee"] = strconv.Itoa(params.NecessaryParams.TotalFee)
+	paramMap["spbill_create_ip"] = params.NecessaryParams.SpbillCreateIp
+	paramMap["notify_url"] = params.NecessaryParams.NotifyUrl
+	paramMap["trade_type"] = params.NecessaryParams.TradeType
+
+	if params.Openid != "" {
+		paramMap["openid"] = params.Openid
+	}
+	if params.DeviceInfo != "" {
+		paramMap["openid"] = params.DeviceInfo
+	}
+	signStr := getSignString(secretKey, paramMap)
+	fmt.Println("signStr:", signStr)
+	hash := md5.New()
+	hash.Write([]byte(signStr))
+	md5Sign := hash.Sum(nil)
+	sign := strings.ToUpper(hex.EncodeToString(md5Sign))
+	return sign
+}
+
+//获取排好序的Key
+func getSignString(secretKey string, paramMap map[string]string) string {
+	keyList := make([]string, 0)
+	for k := range paramMap {
+		keyList = append(keyList, k)
+	}
+	sort.Strings(keyList)
+	stringA := ""
+	for _, k := range keyList {
+		stringA += k + "=" + paramMap[k] + "&"
+	}
+	stringA += "key=" + secretKey
+	return stringA
+}
+
+func generateXml(m map[string]string) string {
+	xml := "<xml>"
+	for k, v := range m {
+		xml += fmt.Sprintf("<%s>%s</%s>", k, v, k)
+	}
+	xml += "</xml>"
+	return xml
+}

+ 20 - 0
wechat_pay.go

@@ -0,0 +1,20 @@
+package go_pay
+
+type WechatPayClient struct {
+	Params *WechatParams
+	Sign   string
+}
+
+func NewWechatPayClient() *WechatPayClient {
+	client := new(WechatPayClient)
+	return client
+}
+
+func (this *WechatPayClient) SetParams(param *WechatParams) {
+	this.Params = param
+}
+
+func (this *WechatPayClient) SetSign(secretKey string) error {
+	this.Sign = getSign(secretKey, this.Params)
+	return nil
+}

+ 27 - 0
wechat_pay_test.go

@@ -0,0 +1,27 @@
+package go_pay
+
+import (
+	"fmt"
+	"testing"
+)
+
+func TestGetSign(t *testing.T) {
+	necessary := new(WechatParamsNecessary)
+	necessary.Appid = "zbcdefg"
+	necessary.MchId = "1234455"
+	necessary.NonceStr = "dyUNIkNS29hvDUC1CmoF0alSdfCQGg9I"
+	necessary.Body = "测试充值"
+	necessary.OutTradeNo = "GYsadfjksdhgflkhfgnlsdkf"
+	necessary.TotalFee = 15
+	necessary.SpbillCreateIp = "127.0.0.1"
+	necessary.NotifyUrl = "http://www.igoogle.ink"
+	necessary.TradeType = "APP"
+
+	params := new(WechatParams)
+	params.DeviceInfo = "WEB"
+	params.NecessaryParams = *necessary
+
+	s := getSign("asdfdsagsfdg", params)
+
+	fmt.Println("sign:", s)
+}