mirror of
https://github.com/silenceper/wechat.git
synced 2026-02-11 16:22:26 +08:00
16
.travis.yml
16
.travis.yml
@@ -1,14 +1,20 @@
|
|||||||
language: go
|
language: go
|
||||||
|
|
||||||
go:
|
go:
|
||||||
- 1.9
|
- 1.9.x
|
||||||
- 1.8
|
- 1.8.x
|
||||||
- 1.7
|
- 1.7.x
|
||||||
- 1.6
|
- 1.6.x
|
||||||
|
|
||||||
services:
|
services:
|
||||||
- memcached
|
- memcached
|
||||||
- redis-server
|
- redis-server
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- GO_FILES=$(find . -iname '*.go' -type f | grep -v /vendor/)
|
||||||
|
- go get github.com/golang/lint/golint
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- go test -v ./...
|
- go test -v -race ./...
|
||||||
|
- go vet ./...
|
||||||
|
- golint -set_exit_status $(go list ./...)
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func hello(ctx *context.Context) {
|
|||||||
|
|
||||||
//回复消息:演示回复用户发送的消息
|
//回复消息:演示回复用户发送的消息
|
||||||
text := message.NewText(msg.Content)
|
text := message.NewText(msg.Content)
|
||||||
return &message.Reply{message.MsgTypeText, text}
|
return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
|
||||||
})
|
})
|
||||||
|
|
||||||
//处理消息接收以及回复
|
//处理消息接收以及回复
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ func hello(c *gin.Context) {
|
|||||||
|
|
||||||
//回复消息:演示回复用户发送的消息
|
//回复消息:演示回复用户发送的消息
|
||||||
text := message.NewText(msg.Content)
|
text := message.NewText(msg.Content)
|
||||||
return &message.Reply{message.MsgTypeText, text}
|
return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
|
||||||
})
|
})
|
||||||
|
|
||||||
//处理消息接收以及回复
|
//处理消息接收以及回复
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ func hello(rw http.ResponseWriter, req *http.Request) {
|
|||||||
|
|
||||||
//回复消息:演示回复用户发送的消息
|
//回复消息:演示回复用户发送的消息
|
||||||
text := message.NewText(msg.Content)
|
text := message.NewText(msg.Content)
|
||||||
return &message.Reply{message.MsgTypeText, text}
|
return &message.Reply{MsgType: message.MsgTypeText, MsgData: text}
|
||||||
})
|
})
|
||||||
|
|
||||||
//处理消息接收以及回复
|
//处理消息接收以及回复
|
||||||
|
|||||||
132
pay/pay.go
132
pay/pay.go
@@ -1,9 +1,10 @@
|
|||||||
package pay
|
package pay
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
"fmt"
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/silenceper/wechat/context"
|
"github.com/silenceper/wechat/context"
|
||||||
"github.com/silenceper/wechat/util"
|
"github.com/silenceper/wechat/util"
|
||||||
)
|
)
|
||||||
@@ -15,65 +16,65 @@ type Pay struct {
|
|||||||
*context.Context
|
*context.Context
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Params was NEEDED when request unifiedorder
|
||||||
// 传入的参数,用于生成 prepay_id 的必需参数
|
// 传入的参数,用于生成 prepay_id 的必需参数
|
||||||
// PayParams was NEEDED when request unifiedorder
|
type Params struct {
|
||||||
type PayParams struct {
|
TotalFee string
|
||||||
TotalFee string
|
CreateIP string
|
||||||
CreateIP string
|
Body string
|
||||||
Body string
|
OutTradeNo string
|
||||||
OutTradeNo string
|
OpenID string
|
||||||
OpenID string
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// PayConfig 是传出用于 jsdk 用的参数
|
// Config 是传出用于 jsdk 用的参数
|
||||||
type PayConfig struct {
|
type Config struct {
|
||||||
Timestamp int64
|
Timestamp int64
|
||||||
NonceStr string
|
NonceStr string
|
||||||
PrePayID string
|
PrePayID string
|
||||||
SignType string
|
SignType string
|
||||||
Sign string
|
Sign string
|
||||||
}
|
}
|
||||||
|
|
||||||
// payResult 是 unifie order 接口的返回
|
// payResult 是 unifie order 接口的返回
|
||||||
type payResult struct {
|
type payResult struct {
|
||||||
ReturnCode string `xml:"return_code"`
|
ReturnCode string `xml:"return_code"`
|
||||||
ReturnMsg string `xml:"return_msg"`
|
ReturnMsg string `xml:"return_msg"`
|
||||||
AppID string `xml:"appid,omitempty"`
|
AppID string `xml:"appid,omitempty"`
|
||||||
MchID string `xml:"mch_id,omitempty"`
|
MchID string `xml:"mch_id,omitempty"`
|
||||||
NonceStr string `xml:"nonce_str,omitempty"`
|
NonceStr string `xml:"nonce_str,omitempty"`
|
||||||
Sign string `xml:"sign,omitempty"`
|
Sign string `xml:"sign,omitempty"`
|
||||||
ResultCode string `xml:"result_code,omitempty"`
|
ResultCode string `xml:"result_code,omitempty"`
|
||||||
TradeType string `xml:"trade_type,omitempty"`
|
TradeType string `xml:"trade_type,omitempty"`
|
||||||
PrePayID string `xml:"prepay_id,omitempty"`
|
PrePayID string `xml:"prepay_id,omitempty"`
|
||||||
CodeURL string `xml:"code_url,omitempty"`
|
CodeURL string `xml:"code_url,omitempty"`
|
||||||
ErrCode string `xml:"err_code,omitempty"`
|
ErrCode string `xml:"err_code,omitempty"`
|
||||||
ErrCodeDes string `xml:"err_code_des,omitempty"`
|
ErrCodeDes string `xml:"err_code_des,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
//payRequest 接口请求参数
|
//payRequest 接口请求参数
|
||||||
type payRequest struct {
|
type payRequest struct {
|
||||||
AppID string `xml:"appid"`
|
AppID string `xml:"appid"`
|
||||||
MchID string `xml:"mch_id"`
|
MchID string `xml:"mch_id"`
|
||||||
DeviceInfo string `xml:"device_info,omitempty"`
|
DeviceInfo string `xml:"device_info,omitempty"`
|
||||||
NonceStr string `xml:"nonce_str"`
|
NonceStr string `xml:"nonce_str"`
|
||||||
Sign string `xml:"sign"`
|
Sign string `xml:"sign"`
|
||||||
SignType string `xml:"sign_type,omitempty"`
|
SignType string `xml:"sign_type,omitempty"`
|
||||||
Body string `xml:"body"`
|
Body string `xml:"body"`
|
||||||
Detail string `xml:"detail,omitempty"`
|
Detail string `xml:"detail,omitempty"`
|
||||||
Attach string `xml:"attach,omitempty"` //附加数据
|
Attach string `xml:"attach,omitempty"` //附加数据
|
||||||
OutTradeNo string `xml:"out_trade_no"` //商户订单号
|
OutTradeNo string `xml:"out_trade_no"` //商户订单号
|
||||||
FeeType string `xml:"fee_type,omitempty"` //标价币种
|
FeeType string `xml:"fee_type,omitempty"` //标价币种
|
||||||
TotalFee string `xml:"total_fee"` //标价金额
|
TotalFee string `xml:"total_fee"` //标价金额
|
||||||
SpbillCreateIp string `xml:"spbill_create_ip"` //终端IP
|
SpbillCreateIP string `xml:"spbill_create_ip"` //终端IP
|
||||||
TimeStart string `xml:"time_start,omitempty"` //交易起始时间
|
TimeStart string `xml:"time_start,omitempty"` //交易起始时间
|
||||||
TimeExpire string `xml:"time_expire,omitempty"` //交易结束时间
|
TimeExpire string `xml:"time_expire,omitempty"` //交易结束时间
|
||||||
GoodsTag string `xml:"goods_tag,omitempty"` //订单优惠标记
|
GoodsTag string `xml:"goods_tag,omitempty"` //订单优惠标记
|
||||||
NotifyUrl string `xml:"notify_url"` //通知地址
|
NotifyURL string `xml:"notify_url"` //通知地址
|
||||||
TradeType string `xml:"trade_type"` //交易类型
|
TradeType string `xml:"trade_type"` //交易类型
|
||||||
ProductId string `xml:"product_id,omitempty"` //商品ID
|
ProductID string `xml:"product_id,omitempty"` //商品ID
|
||||||
LimitPay string `xml:"limit_pay,omitempty"` //
|
LimitPay string `xml:"limit_pay,omitempty"` //
|
||||||
OpenID string `xml:"openid,omitempty"` //用户标识
|
OpenID string `xml:"openid,omitempty"` //用户标识
|
||||||
SceneInfo string `xml:"scene_info,omitempty"` //场景信息
|
SceneInfo string `xml:"scene_info,omitempty"` //场景信息
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewPay return an instance of Pay package
|
// NewPay return an instance of Pay package
|
||||||
@@ -82,25 +83,25 @@ func NewPay(ctx *context.Context) *Pay {
|
|||||||
return &pay
|
return &pay
|
||||||
}
|
}
|
||||||
|
|
||||||
// PrePayId will request wechat merchant api and request for a pre payment order id
|
// PrePayID will request wechat merchant api and request for a pre payment order id
|
||||||
func (pcf *Pay) PrePayId(p *PayParams) (prePayID string, err error) {
|
func (pcf *Pay) PrePayID(p *Params) (prePayID string, err error) {
|
||||||
nonceStr := util.RandomStr(32)
|
nonceStr := util.RandomStr(32)
|
||||||
tradeType := "JSAPI"
|
tradeType := "JSAPI"
|
||||||
template := "appid=%s&body=%s&mch_id=%s&nonce_str=%s¬ify_url=%s&openid=%s&out_trade_no=%s&spbill_create_ip=%s&total_fee=%s&trade_type=%s&key=%s"
|
template := "appid=%s&body=%s&mch_id=%s&nonce_str=%s¬ify_url=%s&openid=%s&out_trade_no=%s&spbill_create_ip=%s&total_fee=%s&trade_type=%s&key=%s"
|
||||||
str := fmt.Sprintf(template, pcf.AppID, p.Body, pcf.PayMchID, nonceStr, pcf.PayNotifyURL, p.OpenID, p.OutTradeNo, p.CreateIP, p.TotalFee, tradeType, pcf.PayKey)
|
str := fmt.Sprintf(template, pcf.AppID, p.Body, pcf.PayMchID, nonceStr, pcf.PayNotifyURL, p.OpenID, p.OutTradeNo, p.CreateIP, p.TotalFee, tradeType, pcf.PayKey)
|
||||||
sign := util.MD5Sum(str)
|
sign := util.MD5Sum(str)
|
||||||
request := payRequest{
|
request := payRequest{
|
||||||
AppID: pcf.AppID,
|
AppID: pcf.AppID,
|
||||||
MchID: pcf.PayMchID,
|
MchID: pcf.PayMchID,
|
||||||
NonceStr: nonceStr,
|
NonceStr: nonceStr,
|
||||||
Sign: sign,
|
Sign: sign,
|
||||||
Body: p.Body,
|
Body: p.Body,
|
||||||
OutTradeNo: p.OutTradeNo,
|
OutTradeNo: p.OutTradeNo,
|
||||||
TotalFee: p.TotalFee,
|
TotalFee: p.TotalFee,
|
||||||
SpbillCreateIp: p.CreateIP,
|
SpbillCreateIP: p.CreateIP,
|
||||||
NotifyUrl: pcf.PayNotifyURL,
|
NotifyURL: pcf.PayNotifyURL,
|
||||||
TradeType: tradeType,
|
TradeType: tradeType,
|
||||||
OpenID: p.OpenID,
|
OpenID: p.OpenID,
|
||||||
}
|
}
|
||||||
rawRet, err := util.PostXML(payGateway, request)
|
rawRet, err := util.PostXML(payGateway, request)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -117,7 +118,6 @@ func (pcf *Pay) PrePayId(p *PayParams) (prePayID string, err error) {
|
|||||||
return payRet.PrePayID, nil
|
return payRet.PrePayID, nil
|
||||||
}
|
}
|
||||||
return "", errors.New(payRet.ErrCode + payRet.ErrCodeDes)
|
return "", errors.New(payRet.ErrCode + payRet.ErrCodeDes)
|
||||||
} else {
|
|
||||||
return "", errors.New("[msg : xmlUnmarshalError] [rawReturn : " + string(rawRet) + "] [params : " + str + "] [sign : " + sign + "]")
|
|
||||||
}
|
}
|
||||||
}
|
return "", errors.New("[msg : xmlUnmarshalError] [rawReturn : " + string(rawRet) + "] [params : " + str + "] [sign : " + sign + "]")
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
package util
|
package util
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"bufio"
|
"bufio"
|
||||||
|
"bytes"
|
||||||
"crypto/aes"
|
"crypto/aes"
|
||||||
"crypto/cipher"
|
"crypto/cipher"
|
||||||
"crypto/md5"
|
"crypto/md5"
|
||||||
@@ -186,7 +186,7 @@ func decodeNetworkByteOrder(orderBytes []byte) (n uint32) {
|
|||||||
uint32(orderBytes[3])
|
uint32(orderBytes[3])
|
||||||
}
|
}
|
||||||
|
|
||||||
// 计算 32 位长度的 MD5 sum
|
// MD5Sum 计算 32 位长度的 MD5 sum
|
||||||
func MD5Sum(txt string) (sum string) {
|
func MD5Sum(txt string) (sum string) {
|
||||||
h := md5.New()
|
h := md5.New()
|
||||||
buf := bufio.NewWriterSize(h, 128)
|
buf := bufio.NewWriterSize(h, 128)
|
||||||
|
|||||||
Reference in New Issue
Block a user