123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- package wechat
- import (
- "bytes"
- "encoding/xml"
- "errors"
- "fmt"
- "git.chuangxin1.com/cx/util"
- )
- const (
- // WePayHost base host
- WePayHost = `https://api.mch.weixin.qq.com`
- // WePayURLUnifiedOrder pay 付款
- WePayURLUnifiedOrder = `/pay/unifiedorder`
- // WePayURLUnifiedQuery order query 订单查询
- WePayURLUnifiedQuery = `/pay/orderquery`
- // WePayURLPayRefund pay refund 退款
- WePayURLPayRefund = `/secapi/pay/refund`
- // WePayURLPapPay 委托代扣申请扣款
- WePayURLPapPay = `/pay/pappayapply`
- // WePayURLPapayEntrust H5 纯签约
- WePayURLPapayEntrust = `/papay/h5entrustweb`
- // WePayTradeTypeJS JSAPI 公众号支付
- WePayTradeTypeJS = `JSAPI`
- // WePayTradeTypeNative NATIVE 扫码支付
- WePayTradeTypeNative = `NATIVE`
- // WePayTradeTypeAPP APP APP支付
- WePayTradeTypeAPP = `APP`
- // WeOrderPaySuccess pay ok
- WeOrderPaySuccess = 0
- )
- // WePayConfig WeChat pay configure
- type WePayConfig struct {
- AppID string `json:"appid"`
- MchID string `json:"mchid"`
- Key string `json:"key"`
- AppSecret string `json:"appsecret"`
- SSLCert string `json:"sslcert"`
- SSLKey string `json:"sslkey"`
- ContractID string `json:"contractid"`
- NotifyURL string `json:"notify_url"`
- }
- // UnifiedOrder https://api.mch.weixin.qq.com/pay/unifiedorder
- type UnifiedOrder struct {
- XMLName xml.Name `xml:"xml"`
- AppID string `xml:"appid"`
- MchID string `xml:"mch_id"`
- Body string `xml:"body"`
- NonceStr string `xml:"nonce_str"`
- NotifyURL string `xml:"notify_url"`
- TradeType string `xml:"trade_type"`
- OpenID string `xml:"openid"`
- SpbillCreateIP string `xml:"spbill_create_ip"`
- TimeStart string `xml:"time_start"`
- TotalFee int `xml:"total_fee"`
- OutTradeNo string `xml:"out_trade_no"`
- Attach string `xml:"attach"`
- Sign string `xml:"sign"`
- }
- // OrderQuery https://api.mch.weixin.qq.com/pay/orderquery
- type OrderQuery struct {
- XMLName xml.Name `xml:"xml"`
- AppID string `xml:"appid"`
- MchID string `xml:"mch_id"`
- NonceStr string `xml:"nonce_str"`
- TransactionID string `xml:"transaction_id,omitempty"`
- OutTradeNo string `xml:"out_trade_no,omitempty"`
- Sign string `xml:"sign"`
- }
- /*
- <xml><appid><![CDATA[wx0e9caf2ab1fcd508]]></appid>
- <attach><![CDATA[邦泰商旅]]></attach>
- <bank_type><![CDATA[CITIC_CREDIT]]></bank_type>
- <cash_fee><![CDATA[349000]]></cash_fee>
- <fee_type><![CDATA[CNY]]></fee_type>
- <is_subscribe><![CDATA[N]]></is_subscribe>
- <mch_id><![CDATA[1340131101]]></mch_id>
- <nonce_str><![CDATA[0gwbd25n61bxkw6m64kj4ovf60i2q2sg]]></nonce_str>
- <openid><![CDATA[o7-PevpkcTqeJOkOF4X7VFhX_SwY]]></openid>
- <out_trade_no><![CDATA[134013110120180709134447]]></out_trade_no>
- <result_code><![CDATA[SUCCESS]]></result_code>
- <return_code><![CDATA[SUCCESS]]></return_code>
- <sign><![CDATA[8E581E734384DB2EA6FC08B1482BCCFC]]></sign>
- <time_end><![CDATA[20180709134502]]></time_end>
- <total_fee>349000</total_fee>
- <trade_type><![CDATA[JSAPI]]></trade_type>
- <transaction_id><![CDATA[4200000120201807096318807841]]></transaction_id>
- </xml>
- <xml>
- <return_code>SUCCESS</return_code>
- <return_msg></return_msg>
- <appid>wx84998d72abc5970a</appid>
- <mch_id>1511843111</mch_id>
- <nonce_str>1534475690</nonce_str>
- <sign>27577C258DD809DCE0F8A515233494D1</sign>
- <result_code>SUCCESS</result_code>
- <prepay_id></prepay_id>
- <trade_type>JSAPI</trade_type>
- <code_url></code_url>
- <err_code></err_code>
- <err_code_des></err_code_des>
- <openid>opCl81S2TyHPx7IJRZxc2yGrom5E</openid>
- <attach>{"PlaceNo":"603009","VNO":"","Start":"2018-08-17 11:14:50"</attach>
- <is_subscribe>Y</is_subscribe>
- <bank_type>CFT</bank_type>
- <cash_fee>2</cash_fee>
- <fee_type>CNY</fee_type>
- <out_trade_no>1534475690957535612</out_trade_no>
- <time_end>20180817111506</time_end>
- <total_fee>2</total_fee>
- <trade_state></trade_state>
- <trade_state_desc></trade_state_desc>
- <transaction_id>4200000159201808174345835044</transaction_id>
- </xml>
- // */
- // FormWePayNotify notify
- type FormWePayNotify struct {
- XMLName xml.Name `xml:"xml" json:"_,omitempty"`
- AppID string `form:"appid" xml:"appid"`
- Attach string `form:"attach" xml:"attach"`
- BankType string `form:"bank_type" xml:"bank_type"`
- CashFee int `form:"cash_fee" xml:"cash_fee"`
- FeeType string `form:"fee_type" xml:"fee_type"`
- MchID string `form:"mch_id" xml:"mch_id"`
- IsSubscribe string `form:"is_subscribe" xml:"is_subscribe"`
- NonceStr string `form:"nonce_str" xml:"nonce_str"`
- OpenID string `form:"openid" xml:"openid"`
- OutTradeNo string `form:"out_trade_no" xml:"out_trade_no"`
- ResultCode string `form:"result_code" xml:"result_code"`
- ReturnMsg string `form:"return_msg" xml:"return_msg"`
- ReturnCode string `form:"return_code" xml:"return_code"`
- ErrCodeDes string `form:"err_code_des" xml:"err_code_des"`
- ErrCode string `form:"err_code" xml:"err_code"`
- Sign string `form:"sign" xml:"sign"`
- TimeEnd string `form:"time_end" xml:"time_end"`
- TotalFee int `form:"total_fee" xml:"total_fee"`
- TradeType string `form:"trade_type" xml:"trade_type"`
- TransactionID string `form:"transaction_id" xml:"transaction_id"`
- ContractID string `form:"contract_id" xml:"contract_id"`
- }
- // WePayReply pay reply
- type WePayReply struct {
- XMLName xml.Name `xml:"xml" json:"_,omitempty"`
- ReturnCode string `xml:"return_code"`
- ReturnMsg string `xml:"return_msg"`
- AppID string `xml:"appid"`
- MchID string `xml:"mch_id"`
- NonceStr string `xml:"nonce_str"`
- Sign string `xml:"sign"`
- ResultCode string `xml:"result_code"`
- PrePayID string `xml:"prepay_id"`
- TradeType string `xml:"trade_type"`
- URL string `xml:"code_url"`
- ErrCode string `xml:"err_code"`
- ErrCodeDes string `xml:"err_code_des"`
- OpenID string `xml:"openid"`
- Attach string `xml:"attach"`
- IsSubscribe string `xml:"is_subscribe"`
- BankType string `xml:"bank_type"`
- CashFee string `xml:"cash_fee"`
- FeeType string `xml:"fee_type"`
- OutTradeNo string `xml:"out_trade_no"`
- TimeEnd string `xml:"time_end"`
- TotalFee string `xml:"total_fee"`
- TradeState string `xml:"trade_state"`
- TradeStateDesc string `xml:"trade_state_desc"`
- TransactionID string `xml:"transaction_id"`
- ContractID string `form:"contract_id" xml:"contract_id"`
- }
- var (
- // WePayTradeState 交易状态
- WePayTradeState = map[string]int{"SUCCESS": 0, "REFUND": 2, "NOTPAY": 3, "CLOSED": 4, "REVOKED": 5, "USERPAYING": 6, "PAYERROR": 7}
- )
- // PayCheck check reply
- func PayCheck(reply WePayReply) (ok bool, err error) {
- // 通信是否正确
- if reply.ReturnCode == "FAIL" {
- err = errors.New(reply.ReturnMsg)
- return
- }
- // 交易是否成功
- if reply.ResultCode == "FAIL" {
- err = errors.New(reply.ErrCodeDes)
- return
- }
- ok = true
- return
- }
- // PayNotifyCheck check reply
- func PayNotifyCheck(reply FormWePayNotify) (ok bool, err error) {
- // 通信是否正确
- if reply.ReturnCode == "FAIL" {
- err = errors.New(reply.ReturnMsg)
- return
- }
- // 交易是否成功
- if reply.ResultCode == "FAIL" {
- err = errors.New(reply.ErrCodeDes)
- return
- }
- ok = true
- return
- }
- // PayQuery order query
- func PayQuery(cpyid int, config WePayConfig, order OrderQuery) (reply WePayReply, err error) {
- m := make(map[string]interface{})
- m["appid"] = order.AppID
- m["mch_id"] = order.MchID
- m["out_trade_no"] = order.OutTradeNo
- m["nonce_str"] = order.NonceStr
- //m["transaction_id"] = order.TransactionID
- var (
- data []byte
- )
- order.Sign = Sign(m, config.Key)
- data, err = xml.Marshal(order)
- if err != nil {
- return
- }
- reply, err = post(WePayHost+WePayURLUnifiedQuery, data)
- return
- }
- // Pay pay
- func Pay(config WePayConfig, order UnifiedOrder) (reply WePayReply, err error) {
- m := make(map[string]interface{})
- m["appid"] = order.AppID
- m["mch_id"] = order.MchID
- m["body"] = order.Body
- m["notify_url"] = order.NotifyURL
- m["trade_type"] = order.TradeType
- m["spbill_create_ip"] = order.SpbillCreateIP
- m["total_fee"] = order.TotalFee
- m["out_trade_no"] = order.OutTradeNo
- m["nonce_str"] = order.NonceStr
- m["attach"] = order.Attach
- m["time_start"] = order.TimeStart
- m["openid"] = order.OpenID
- var data []byte
- order.Sign = Sign(m, config.Key)
- if data, err = xml.Marshal(order); err != nil {
- return
- }
- fmt.Println(string(data))
- fmt.Println("***********************************************")
- reply, err = post(WePayHost+WePayURLUnifiedOrder, data)
- return
- }
- func post(url string, data []byte) (reply WePayReply, err error) {
- var (
- msg util.Message
- headers = make(map[string]string)
- )
- headers["Accept"] = "application/xml"
- headers["Content-Type"] = "application/xml; charset=utf-8"
- msg, err = util.Post(url, "", "", headers, bytes.NewReader(data))
- if err != nil {
- return
- }
- fmt.Println("************Response************")
- fmt.Println(string(msg.Body))
- fmt.Println("************ResponseEnd************")
- err = xml.Unmarshal(msg.Body, &reply)
- return
- }
|