refund.go 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. package notify
  2. import (
  3. "crypto/md5"
  4. "encoding/base64"
  5. "encoding/hex"
  6. "encoding/xml"
  7. "errors"
  8. "github.com/silenceper/wechat/v2/util"
  9. )
  10. // reference: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10
  11. // RefundedResult 退款回调
  12. type RefundedResult struct {
  13. ReturnCode *string `xml:"return_code"`
  14. ReturnMsg *string `xml:"return_msg"`
  15. AppID *string `xml:"appid"`
  16. MchID *string `xml:"mch_id"`
  17. NonceStr *string `xml:"nonce_str"`
  18. ReqInfo *string `xml:"req_info"`
  19. }
  20. // RefundedReqInfo 退款结果(明文)
  21. type RefundedReqInfo struct {
  22. TransactionID *string `xml:"transaction_id"`
  23. OutTradeNO *string `xml:"out_trade_no"`
  24. RefundID *string `xml:"refund_id"`
  25. OutRefundNO *string `xml:"out_refund_no"`
  26. TotalFee *int `xml:"total_fee"`
  27. SettlementTotalFee *int `xml:"settlement_total_fee"`
  28. RefundFee *int `xml:"refund_fee"`
  29. SettlementRefundFee *int `xml:"settlement_refund_fee"`
  30. RefundStatus *string `xml:"refund_status"`
  31. SuccessTime *string `xml:"success_time"`
  32. RefundRecvAccount *string `xml:"refund_recv_accout"`
  33. RefundAccount *string `xml:"refund_account"`
  34. RefundRequestSource *string `xml:"refund_request_source"`
  35. }
  36. // RefundedResp 消息通知返回
  37. type RefundedResp struct {
  38. ReturnCode string `xml:"return_code"`
  39. ReturnMsg string `xml:"return_msg"`
  40. }
  41. // DecryptReqInfo 对退款结果进行解密
  42. func (notify *Notify) DecryptReqInfo(result *RefundedResult) (*RefundedReqInfo, error) {
  43. if result == nil || result.ReqInfo == nil {
  44. return nil, errors.New("empty refunded_result or req_info")
  45. }
  46. base64Decode, err := base64.StdEncoding.DecodeString(*result.ReqInfo)
  47. if err != nil {
  48. return nil, err
  49. }
  50. hash := md5.New()
  51. if _, err = hash.Write([]byte(notify.Key)); err != nil {
  52. return nil, err
  53. }
  54. md5APIKey := hex.EncodeToString(hash.Sum(nil))
  55. data, err := util.AesECBDecrypt(base64Decode, []byte(md5APIKey))
  56. if err != nil {
  57. return nil, err
  58. }
  59. res := &RefundedReqInfo{}
  60. if err = xml.Unmarshal(data, res); err != nil {
  61. return nil, err
  62. }
  63. return res, nil
  64. }