Skip to content

Commit

Permalink
支持API Hook,支持退款通知及解密
Browse files Browse the repository at this point in the history
  • Loading branch information
blusewang committed Sep 7, 2021
1 parent 4e6bf99 commit 7074e7f
Show file tree
Hide file tree
Showing 4 changed files with 64 additions and 15 deletions.
14 changes: 8 additions & 6 deletions http_client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ package wx
import (
"bytes"
"encoding/json"
"github.com/blusewang/wx/mch_api"
"io/ioutil"
"log"
"net/http"
Expand Down Expand Up @@ -38,11 +39,12 @@ func TestMt_RoundTrip(t *testing.T) {
log.Println(string(raw), err)
})

var buf = new(bytes.Buffer)
var coder = json.NewEncoder(buf)
coder.SetEscapeHTML(false)
if err := coder.Encode(map[string]string{"a": "b"}); err != nil {
return
var mch = MchAccount{
MchId: "",
MchKey: "",
MchSSLCert: nil,
MchSSLKey: nil,
MchRSAPublicKey: nil,
}
log.Println(client().Post("https://www.baidu.com", "text/json", buf))
mch.NewMchReq(mch_api.PayOrderQuery)
}
21 changes: 21 additions & 0 deletions mch.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
package wx

import (
"crypto/aes"
"crypto/hmac"
"crypto/md5"
rand2 "crypto/rand"
Expand All @@ -17,6 +18,7 @@ import (
"crypto/x509"
"encoding/base64"
"encoding/pem"
"encoding/xml"
"errors"
"fmt"
"github.com/blusewang/wx/mch_api"
Expand Down Expand Up @@ -93,6 +95,25 @@ func (ma MchAccount) PayNotify(pn mch_api.PayNotify) bool {
return false
}

// DecryptRefundNotify 验证支付成功通知
func (ma MchAccount) DecryptRefundNotify(rn mch_api.RefundNotify) (body mch_api.RefundNotifyBody, err error) {
raw, err := base64.StdEncoding.DecodeString(rn.ReqInfo)
if err != nil {
return
}
block, err := aes.NewCipher([]byte(fmt.Sprintf("%x", md5.Sum([]byte(ma.MchKey)))))
length := len(raw)
size := block.BlockSize()
decrypted := make([]byte, len(raw))
for bs, be := 0, size; bs < len(raw); bs, be = bs+size, be+size {
block.Decrypt(decrypted[bs:be], raw[bs:be])
}
up := int(decrypted[length-1])
decrypted = decrypted[:length-up]
err = xml.Unmarshal(decrypted, &body)
return
}

// RsaEncrypt 银行卡机要信息加密
func (ma MchAccount) RsaEncrypt(plain string) (out string) {
block, _ := pem.Decode(ma.MchRSAPublicKey)
Expand Down
33 changes: 29 additions & 4 deletions mch_api/structs.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ type PayOrderQueryRes PayNotify

type PayRefundData struct {
MchBase
TransactionId string `xml:"transaction_id"`
OutTradeNo string `xml:"out_trade_no"`
TransactionId string `xml:"transaction_id,omitempty"`
OutTradeNo string `xml:"out_trade_no,omitempty"`
OutRefundNo string `xml:"out_refund_no"`
TotalFee int64 `xml:"total_fee"`
RefundFee int64 `xml:"refund_fee"`
RefundDesc string `xml:"refund_desc"`
NotifyUrl string `xml:"notify_url"`
RefundDesc string `xml:"refund_desc,omitempty"`
NotifyUrl string `xml:"notify_url,omitempty"`
}

type PayRefundRes struct {
Expand Down Expand Up @@ -304,3 +304,28 @@ type PublicKeyRes struct {
MchBaseResponse
PubKey string `xml:"pub_key"`
}

// RefundNotify 退款状态通知消息
type RefundNotify struct {
MchBaseResponse
MchBase
ReqInfo string `xml:"req_info"`
}

// RefundNotifyBody 退款状态通知内容
type RefundNotifyBody struct {
XMLName xml.Name `xml:"root"`
TransactionId string `xml:"transaction_id"`
OutTradeNo string `xml:"out_trade_no"`
RefundId string `xml:"refund_id"`
OutRefundNo string `xml:"out_refund_no"`
TotalFee int64 `xml:"total_fee"`
SettlementTotalFee int64 `xml:"settlement_total_fee,omitempty"`
RefundFee int64 `xml:"refund_fee"`
SettlementRefundFee int64 `xml:"settlement_refund_fee"`
RefundStatus string `xml:"refund_status"`
SuccessTime string `xml:"success_time,omitempty"`
RefundRecvAccount string `xml:"refund_recv_account"`
RefundAccount string `xml:"refund_account"`
RefundRequestSource string `xml:"refund_request_source"`
}
11 changes: 6 additions & 5 deletions mch_req.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,16 +59,17 @@ func (mr *mchReq) Bind(data interface{}) *mchReq {

// Do 执行
func (mr *mchReq) Do() (err error) {
var cli http.Client
var cli = client()
if mr.isPrivateClient {
if privateClientCache[mr.account.MchId] != nil {
cli = *privateClientCache[mr.account.MchId]
cli = privateClientCache[mr.account.MchId]
} else {
cli, err = mr.account.newPrivateClient()
_cli, err := mr.account.newPrivateClient()
if err != nil {
return
return err
}
privateClientCache[mr.account.MchId] = &cli
cli = &_cli
privateClientCache[mr.account.MchId] = cli
}
}
if err = mr.sign(); err != nil {
Expand Down

0 comments on commit 7074e7f

Please sign in to comment.