Browse Source

wechat pap pay

ls 5 years ago
parent
commit
7c9c93b3b1
3 changed files with 106 additions and 11 deletions
  1. 88 0
      wechat/pap.go
  2. 17 11
      wechat/pay.go
  3. 1 0
      wechat/wechat.go

+ 88 - 0
wechat/pap.go

@@ -0,0 +1,88 @@
+// 委托代扣
+
+package wechat
+
+import "encoding/xml"
+
+// PapPay 委托代扣申请扣款
+type PapPay struct {
+	XMLName        xml.Name `xml:"xml"`
+	AppID          string   `xml:"appid"`
+	MchID          string   `xml:"mch_id"`
+	NonceStr       string   `xml:"nonce_str"`        // 随机字符串,不长于32位
+	Sign           string   `xml:"sign"`             // 签名
+	Body           string   `xml:"body"`             // 商品或支付单简要描述, max 32
+	Detail         string   `xml:"detail"`           // 商品名称明细列表, 8192
+	Attach         string   `xml:"attach"`           // 附加数据,在查询API和支付通知中原样返回
+	OutTradeNo     string   `xml:"out_trade_no"`     // 商户系统内部的订单号, 32个字符内、可包含字母
+	TotalFee       int      `xml:"total_fee"`        // 订单总金额,单位为分,只能为整数
+	SpbillCreateIP string   `xml:"spbill_create_ip"` // 调用微信支付API的机器IP
+	NotifyURL      string   `xml:"notify_url"`       // 接受扣款结果异步回调通知的url
+	ContractID     string   `xml:"contract_id"`      // 委托代扣协议id
+
+	OpenID    string `xml:"openid"`    // OpenID
+	Mobile    string `xml:"mobile"`    // 手机号
+	Creid     string `xml:"creid"`     // 身份证号码
+	Timestamp int    `xml:"timestamp"` // 时间戳, 10位时间戳
+}
+
+// PapPayApply 委托代扣申请扣款
+func PapPayApply(config WePayConfig, order PapPay) (reply WePayReply, err error) {
+	m := make(map[string]interface{})
+
+	m["appid"] = order.AppID
+	m["mch_id"] = order.MchID
+	m["nonce_str"] = order.NonceStr
+	m["body"] = order.Body
+	m["detail"] = order.Detail
+	m["attach"] = order.Attach
+	m["out_trade_no"] = order.OutTradeNo
+	m["total_fee"] = order.TotalFee
+	m["spbill_create_ip"] = order.SpbillCreateIP
+	m["notify_url"] = order.NotifyURL
+	m["trade_type"] = `PAP`
+	m["contract_id"] = order.ContractID
+
+	m["openid"] = order.OpenID
+	m["mobile"] = order.Mobile
+	m["creid"] = order.Creid
+	m["timestamp"] = order.Timestamp
+
+	var data []byte
+
+	order.Sign = Sign(m, config.Key)
+	if data, err = xml.Marshal(order); err != nil {
+		return
+	}
+
+	reply, err = post(WePayHost+WePayURLPapPay, data)
+	return
+}
+
+/*
+POST
+<xml>
+<mch_id>10000098</mch_id>
+<appid>wxcbda96de0b165486</appid>
+<nonce_str>5K8264ILTKCH16CQ2502SI8ZNMTM67VS</nonce_str>
+<sign>C380BEC2BFD727A4B6845133519F3AD6</sign>
+<body>水电代扣</body>
+<out_trade_no>217752501201407033233368018</out_trade_no>
+<total_fee>888</total_fee>
+<spbill_create_ip>8.8.8.8</spbill_create_ip>
+<notify_url>http://yoursite.com/wxpay.html</notify_url>
+<contract_id>Wx15463511252015071056489715</contract_id>
+</xml>
+
+Return
+<xml>
+<return_code><![CDATA[SUCCESS]]></return_code>
+<return_msg><![CDATA[OK]]></return_msg>
+<appid><![CDATA[wxcbda96de0b165486]]></wxappid>
+<mch_id><![CDATA[10000098]]></mch_id>
+<nonce_str><![CDATA[IITRi8Iabbblz1Jc]]></nonce_str>
+<sign><![CDATA[E1EE61A91C8E90F299DE6AE075D60A2D]]></sign>
+<result_code><![CDATA[SUCCESS]]></result_code>
+
+</xml>
+// */

+ 17 - 11
wechat/pay.go

@@ -4,6 +4,7 @@ import (
 	"bytes"
 	"encoding/xml"
 	"errors"
+	"fmt"
 
 	"git.chuangxin1.com/cx/util"
 )
@@ -18,6 +19,8 @@ const (
 	WePayURLUnifiedQuery = `/pay/orderquery`
 	// WePayURLPayRefund pay refund 退款
 	WePayURLPayRefund = `/secapi/pay/refund`
+	// WePayURLPapPay 委托代扣申请扣款
+	WePayURLPapPay = `/pay/pappayapply`
 
 	// WePayTradeTypeJS JSAPI 公众号支付
 	WePayTradeTypeJS = `JSAPI`
@@ -32,13 +35,14 @@ const (
 
 // 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"`
-	NotifyURL string `json:"notify_url"`
+	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
@@ -145,6 +149,7 @@ type FormWePayNotify struct {
 
 	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
@@ -174,6 +179,7 @@ type WePayReply struct {
 	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 (
@@ -244,8 +250,8 @@ func Pay(config WePayConfig, order UnifiedOrder) (reply WePayReply, err error) {
 	m := make(map[string]interface{})
 
 	m["appid"] = order.AppID
-	m["body"] = order.Body
 	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
@@ -280,9 +286,9 @@ func post(url string, data []byte) (reply WePayReply, err error) {
 		return
 	}
 
-	//fmt.Println("************Response************")
-	//fmt.Println(string(msg.Body))
-	//fmt.Println("************ResponseEnd************")
+	fmt.Println("************Response************")
+	fmt.Println(string(msg.Body))
+	fmt.Println("************ResponseEnd************")
 	err = xml.Unmarshal(msg.Body, &reply)
 
 	return

+ 1 - 0
wechat/wechat.go

@@ -136,6 +136,7 @@ func Random(n int) string {
 	return string(result)
 }
 
+// makeSignature echo 签名验证
 func makeSignature(token, signature, timestamp, nonce string) bool {
 	sl := []string{token, timestamp, nonce}
 	sort.Strings(sl)