refund.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. package wechat
  2. import (
  3. "bytes"
  4. "encoding/xml"
  5. "fmt"
  6. "git.chuangxin1.com/cx/util"
  7. )
  8. /*
  9. 退款示例:
  10. <xml>
  11. <appid>wx2421b1c4370ec43b</appid>
  12. <mch_id>10000100</mch_id>
  13. <nonce_str>6cefdb308e1e2e8aabd48cf79e546a02</nonce_str>
  14. <out_refund_no>1415701182</out_refund_no>
  15. <out_trade_no>1415757673</out_trade_no>
  16. <refund_fee>1</refund_fee>
  17. <total_fee>1</total_fee>
  18. <transaction_id>4006252001201705123297353072</transaction_id>
  19. <sign>FE56DD4AA85C0EECA82C35595A69E153</sign>
  20. </xml>
  21. //*/
  22. // WePayRefund https://api.mch.weixin.qq.com/secapi/pay/refund
  23. type WePayRefund struct {
  24. XMLName xml.Name `xml:"xml"`
  25. AppID string `xml:"appid"` // 公众账号 ID string(32)
  26. MchID string `xml:"mch_id"` // 商户号 string(32)
  27. NonceStr string `xml:"nonce_str"` // 随机字符串 string(32)
  28. Sign string `xml:"sign"` // 签名 string(32)
  29. //SignType string `xml:"sign_type"` // 签名类型, 默认 MD5 string(32), HMAC-SHA256 和 MD5
  30. OutTradeNo string `xml:"out_trade_no"` // 商户订单号
  31. OutRefundNo string `xml:"out_refund_no"` // 商户退款单号
  32. TotalFee int `xml:"total_fee"` // 订单金额
  33. RefundFee int `xml:"refund_fee"` // 退款金额
  34. //RefundFeeType string `xml:"refund_fee_type"` // 退款货币种类, 款货币类型,需与支付一致,或者不填。符合ISO 4217标准的三位字母代码,默认人民币:CNY
  35. NotifyURL string `xml:"notify_url"` // 退款结果通知 url, 异步接收微信支付退款结果通知的回调地址,通知URL必须为外网可访问的url,不允许带参数。如果参数中传了notify_url,则商户平台上配置的回调地址将不会生效
  36. }
  37. // WePayRefundReply pay refund reply
  38. type WePayRefundReply struct {
  39. XMLName xml.Name `xml:"xml" json:"_,omitempty"`
  40. ReturnCode string `xml:"return_code"`
  41. ReturnMsg string `xml:"return_msg"`
  42. ResultCode string `xml:"result_code"`
  43. ErrCode string `xml:"err_code"`
  44. ErrCodeDes string `xml:"err_code_des"`
  45. AppID string `xml:"appid"`
  46. MchID string `xml:"mch_id"`
  47. NonceStr string `xml:"nonce_str"`
  48. Sign string `xml:"sign"`
  49. TransactionID string `xml:"transaction_id"`
  50. OutTradeNo string `xml:"out_trade_no"`
  51. OutRefundNo string `xml:"out_refund_no"`
  52. RefundFee int `xml:"refund_fee"` // 退款金额
  53. TotalFee int `xml:"total_fee"` // 标价金额, 订单总金额,单位为分,只能为整数
  54. FeeType int `xml:"fee_type"` // 退款货币种类, 款货币类型,需与支付一致,或者不填。符合ISO 4217标准的三位字母代码,默认人民币:CNY
  55. CashFee int `xml:"cash_fee"` // 现金支付金额
  56. }
  57. // PayRefund 退款
  58. func PayRefund(config WePayConfig, order WePayRefund) (reply WePayRefundReply, err error) {
  59. var data []byte
  60. m := make(map[string]interface{})
  61. m["appid"] = order.AppID
  62. m["mch_id"] = order.MchID
  63. m["nonce_str"] = order.NonceStr
  64. m["total_fee"] = order.TotalFee
  65. m["out_trade_no"] = order.OutTradeNo
  66. m["out_refund_no"] = order.OutRefundNo
  67. m["total_fee"] = order.TotalFee
  68. m["refund_fee"] = order.RefundFee
  69. m["notify_url"] = order.NotifyURL
  70. //order.SignType = `MD5`
  71. order.Sign = Sign(m, config.Key)
  72. if data, err = xml.Marshal(order); err != nil {
  73. return
  74. }
  75. fmt.Println(string(data))
  76. url := WePayHost + WePayURLPayRefund
  77. reply, err = postRefund(url, config.SSLCert, config.SSLKey, data)
  78. bs, _ := xml.Marshal(reply)
  79. fmt.Println(string(bs))
  80. return
  81. }
  82. func postRefund(url, cert, key string, data []byte) (reply WePayRefundReply, err error) {
  83. var (
  84. msg util.Message
  85. headers = make(map[string]string)
  86. )
  87. headers["Accept"] = "application/xml"
  88. headers["Content-Type"] = "application/xml; charset=utf-8"
  89. msg, err = util.Post(url, cert, key, headers, bytes.NewReader(data))
  90. if err != nil {
  91. fmt.Println("util.Post", err)
  92. return
  93. }
  94. fmt.Println(string(msg.Body))
  95. err = xml.Unmarshal(msg.Body, &reply)
  96. return
  97. }