WechatRefund.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. <?php
  2. /**
  3. * @note: 微信退款
  4. * @author: jdzor <895947580@qq.com>
  5. * @date: 2019/3/28
  6. */
  7. namespace payment\wechat;
  8. /**
  9. * 关于微信退款的说明
  10. * 1.微信退款要求必传证书,需要到https://pay.weixin.qq.com 账户中心->账户设置->API安全->下载证书,证书路径在第119行和122行修改
  11. * 2.参考 :https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4
  12. *
  13. * 使用方法:
  14. * $wechatRefund = new WechatRefund($config);
  15. * $info = $wechatRefund->doRefund($param);
  16. * $info = $wechatRefund->queryRefund($outTradeNo);
  17. * $info['return_code'] == 'FAIL' && json_error($info['return_msg'], -2);
  18. * $info['result_code'] == 'FAIL' && json_error($info['err_code_des'], -2);
  19. *
  20. * Class WechatRefund
  21. * @package app\common\extend\wechat
  22. */
  23. class WechatRefund extends BaseWechat
  24. {
  25. const REFUND_URL = '/secapi/pay/refund'; //申请退款
  26. const REFUND_QUERY_URL = '/pay/refundquery'; //退款查询
  27. public function __construct($config)
  28. {
  29. parent::__construct($config);
  30. isset($config['sslcert_path']) && $this->sslcertPath = $config['sslcert_path'];
  31. isset($config['sslkey_path']) && $this->sslkeyPath = $config['sslkey_path'];
  32. }
  33. private function checkSsl()
  34. {
  35. $this->sslcertPath || json_error('缺少参数:sslcert_path'); //证书必传
  36. $this->sslkeyPath || json_error('缺少参数:sslkey_path');
  37. }
  38. //退款参数检测
  39. private function check($param)
  40. {
  41. $this->checkSsl();
  42. isset($param['out_trade_no']) || json_error('缺少参数:out_trade_no');
  43. isset($param['out_refund_no']) || json_error('缺少参数:out_refund_no');
  44. isset($param['total_fee']) || json_error('缺少参数:total_fee');
  45. isset($param['refund_fee']) || json_error('缺少参数:refund_fee');
  46. isset($param['refund_desc']) || json_error('缺少参数:refund_desc');
  47. isset($param['notify_url']) || json_error('缺少参数:notify_url');
  48. $this->notifyUrl = $param['notify_url'];
  49. }
  50. //申请退款
  51. public function doRefund($param)
  52. {
  53. $this->check($param);
  54. $data['appid'] = $this->appId;
  55. $data['mch_id'] = $this->mchId;
  56. $data['notify_url'] = $this->notifyUrl;
  57. $data['out_trade_no'] = $param['out_trade_no']; //商户系统内部订单号
  58. $data['out_refund_no'] = $param['out_refund_no']; //商户系统内部的退款单号
  59. $data['total_fee'] = $param['total_fee']; //订单总金额,单位为分,只能为整数
  60. $data['refund_fee'] = $param['refund_fee']; //退款总金额,订单总金额,单位为分,只能为整数
  61. $data['refund_desc'] = $param['refund_desc']; //若商户传入,会在下发给用户的退款消息中体现退款原因,注意:若订单退款金额≤1元且属于部分退款,则不会在退款消息中体现退款原因
  62. $data['nonce_str'] = $this->getRandomString();
  63. $data['sign_type'] = $this->signType;
  64. $data['sign'] = $this->makeSign($data);
  65. $xml = $this->dataToXml($data);
  66. $response = $this->postXmlCurl($xml, self::REFUND_URL, true);
  67. if (!$response) return false;
  68. $result = $this->xmlToArray($response);
  69. return $result;
  70. }
  71. //退款查询
  72. public function queryRefund($outTradeNo, $offset = 0)
  73. {
  74. $data['appid'] = $this->appId;
  75. $data['mch_id'] = $this->mchId;
  76. $data['nonce_str'] = $this->getRandomString();
  77. $data['out_trade_no'] = $outTradeNo;
  78. $data['sign_type'] = $this->signType;
  79. $offset > 10 && $data['offset'] = $offset; //偏移量,当部分退款次数超过10次时可使用,表示返回的查询结果从这个偏移量开始取记录
  80. $data['sign'] = $this->makeSign($data);
  81. $xml = $this->dataToXml($data);
  82. $response = $this->postXmlCurl($xml, self::REFUND_QUERY_URL);
  83. if (!$response) return false;
  84. $result = $this->xmlToArray($response);
  85. return $result;
  86. }
  87. }