1
0
mirror of https://github.com/silenceper/wechat.git synced 2026-02-11 00:02:27 +08:00

add H5 payment support

This commit is contained in:
Mongo
2017-10-29 21:01:27 +08:00
parent 97752d09a6
commit a4a567e1d4
4 changed files with 50 additions and 22 deletions

View File

@@ -15,6 +15,7 @@ type Context struct {
EncodingAESKey string EncodingAESKey string
PayMchID string PayMchID string
PayNotifyURL string PayNotifyURL string
PayKey string
Cache cache.Cache Cache cache.Cache

View File

@@ -1,13 +1,16 @@
package pay package pay
import ( import (
"crypto/md5" "errors"
"crypto/md5"
"encoding/xml"
"fmt"
"strings" "strings"
"github.com/silenceper/wechat/context" "github.com/silenceper/wechat/context"
"github.com/silenceper/wechat/util" "github.com/silenceper/wechat/util"
) )
var payGateway := "https://api.mch.weixin.qq.com/pay/unifiedorder" var payGateway = "https://api.mch.weixin.qq.com/pay/unifiedorder"
// Pay struct extends context // Pay struct extends context
type Pay struct { type Pay struct {
@@ -20,14 +23,26 @@ type PayParams struct {
CreateIP string CreateIP string
Body string Body string
OutTradeNo string OutTradeNo string
OpenID string
} }
type PayResult struct { // payResult 是 unifie order 接口的返回
Success bool type payResult struct {
PrePayID string ReturnCode string `xml:"return_code"`
ReturnMsg string `xml:"return_msg"`
AppID string `xml:"appid,omitempty"`
MchID string `xml:"mch_id,omitempty"`
NonceStr string `xml:"nonce_str,omitempty"`
Sign string `xml:"sign,omitempty"`
ResultCode string `xml:"result_code,omitempty"`
TradeType string `xml:"trade_type,omitempty"`
PrePayID string `xml:"prepay_id,omitempty"`
CodeURL string `xml:"code_url,omitempty"`
ErrCode string `xml:"err_code,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"`
@@ -53,10 +68,6 @@ type payRequest struct {
SceneInfo string `xml:"scene_info,omitempty"` //场景信息 SceneInfo string `xml:"scene_info,omitempty"` //场景信息
} }
type payResponse struct {
}
// NewPay return an instance of Pay package // NewPay return an instance of Pay package
func NewPay(ctx *context.Context) *Pay { func NewPay(ctx *context.Context) *Pay {
pay := Pay{Context: ctx} pay := Pay{Context: ctx}
@@ -64,28 +75,43 @@ func NewPay(ctx *context.Context) *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) payResult *PayResult { func (pcf *Pay) PrePayId(p *PayParams) (prePayID string, err error) {
nonceStr := util.RandomStr(32) nonceStr := util.RandomStr(32)
pType = "JSAPI" pType := "JSAPI"
template := "appid=%s&body=%s&mch_id=%s&nonce_str=%s&notify_url=%s&out_trade_no=%s&spbill_create_ip=%s&total_fee=%s&trade_type" template := "appid=%s&body=%s&mch_id=%s&nonce_str=%s&notify_url=%s&out_trade_no=%s&spbill_create_ip=%s&total_fee=%s&trade_type"
stringA := fmt.Sprintf(template, pcf.AppID, p.Body, pcf.MchID, nonceStr, pcf.NotifyUrl, p.OutTradeNo, p.CreateIP, p.TotalFee, pType) str := fmt.Sprintf(template, pcf.AppID, p.Body, pcf.PayMchID, nonceStr, pcf.PayNotifyURL, p.OutTradeNo, p.CreateIP, p.TotalFee, pType)
signature := md5.Sum(stringA + pcf.PayKey) str += pcf.PayKey
sum := md5.Sum([]byte(str))
signature := string(sum[:])
sign := strings.ToUpper(signature) sign := strings.ToUpper(signature)
request := payRequest{ request := payRequest{
AppID: pcf.AppID, AppID: pcf.AppID,
MchID: pcf.MchID, MchID: pcf.PayMchID,
NotifyUrl: pcf.NotifyUrl, NotifyUrl: pcf.PayNotifyURL,
NonceStr: util.RandomStr(32), NonceStr: util.RandomStr(32),
Sign: sign, Sign: sign,
Body: p.Body, Body: p.Body,
OutTradeNo: p.OutTradeNo, OutTradeNo: p.OutTradeNo,
TotalFee: p.TotalFee, TotalFee: p.TotalFee,
SpbillCreateIp: params.CreateIP, SpbillCreateIp: p.CreateIP,
OpenID: params.OpenID, OpenID: p.OpenID,
} }
ret, err := util.PostXML(payGateway, request) rawRet, err := util.PostXML(payGateway, request)
if err != nil { if err != nil {
return "", err
}
payRet := payResult{}
err = xml.Unmarshal(rawRet, &payRet)
if err != nil {
return "", errors.New(err.Error())
}
if payRet.ReturnCode == "SUCCESS" {
//pay success
if payRet.ResultCode == "SUCCESS" {
return payRet.PrePayID, nil
}
return "", errors.New(payRet.ErrCode + payRet.ErrCodeDes)
} else {
return "", errors.New("xml unmarshal err : raw - " + string(rawRet))
} }
fmt.Println(string(ret))
} }

View File

@@ -137,7 +137,7 @@ func PostXML(uri string, obj interface{}) ([]byte, error) {
defer response.Body.Close() defer response.Body.Close()
if response.StatusCode != http.StatusOK { if response.StatusCode != http.StatusOK {
return nil, fmt.Errorf("http get error : uri=%v , statusCode=%v", uri, response.StatusCode) return nil, fmt.Errorf("http code error : uri=%v , statusCode=%v", uri, response.StatusCode)
} }
return ioutil.ReadAll(response.Body) return ioutil.ReadAll(response.Body)
} }

1
wechat Symbolic link
View File

@@ -0,0 +1 @@
wechat