PHP实现微信退款的方法示例

这篇文章主要介绍了PHP实现微信退款的方法,结合实例形式分析了php微信退款功能操作类与相关使用技巧,需要的朋友可以参考下。

本文实例讲述了PHP实现微信退款的方法,分享给大家供大家参考,具体如下:

$obj = new WXRefund('参数');

$obj->refundApi();

直接能用 公众号的参数 自己加上吧 只能帮你们到这了!

  1. <?php
  2. namespace Wechat;
  3. /**
  4. * 微信退款
  5. * @author zzy
  6. * @version $V1.0.0$
  7. * @date 2018-11-9
  8. */
  9. class WXRefund
  10. {
  11. protected $SSLCERT_PATH ='';//证书
  12. protected $SSLKEY_PATH = '';//证书
  13. protected $opUserId = '';//商户号
  14. protected $key = '';//API密钥
  15. protected $appId = '';//appId
  16. function __construct($outTradeNo, $totalFee, $outRefundNo, $refundFee)
  17. {
  18. //初始化退款类需要的变量
  19. $this->totalFee = $totalFee;//订单金额
  20. $this->refundFee = $refundFee;//退款金额
  21. $this->outTradeNo = $outTradeNo;//订单号
  22. $this->outRefundNo = $outRefundNo;//退款订单
  23. }
  24. /**
  25. * 通过微信api进行退款流程 唯一对外接口
  26. * @return string
  27. */
  28. public function refundApi()
  29. {
  30. $parma = array(
  31. 'appid' => $this->appId,
  32. 'mch_id' => $this->opUserId,
  33. 'nonce_str' => randoms(32),//这个是随机数 自己封装去吧。。。
  34. 'out_refund_no' => $this->outRefundNo,
  35. 'out_trade_no' => $this->outTradeNo,
  36. 'total_fee' => intval($this->totalFee * 100),
  37. 'refund_fee' => intval($this->refundFee * 100),
  38. );
  39. $parma['sign'] = $this->getSign($parma, $this->key);
  40. $xmldata = $this->arrayToXml($parma);
  41. $xmlresult = $this->postXmlSSLCurl($xmldata, 'https://api.mch.weixin.qq.com/secapi/pay/refund');
  42. $result = $this->arrayToXml($xmlresult);
  43. return $result;
  44. }
  45. /**
  46. * 数组转xml
  47. * @param $arr
  48. * @return string
  49. */
  50. protected function arrayToXml($arr)
  51. {
  52. $xml = "<xml>";
  53. foreach ($arr as $key => $val) {
  54. if (is_numeric($val)) {
  55. $xml .= "<" . $key . ">" . $val . "</" . $key . ">";
  56. } else {
  57. $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">";
  58. }
  59. }
  60. $xml .= "</xml>";
  61. return $xml;
  62. }
  63. /**
  64. * 签名加密
  65. * @param $params
  66. * @param $key
  67. */
  68. protected function getSign($params, $key)
  69. {
  70. ksort($params, SORT_STRING);
  71. $unSignParaString = $this->formatQueryParaMap($params, false);
  72. return $signStr = strtoupper(md5($unSignParaString . "&key=" . $key));
  73. }
  74. /**
  75. * 排序
  76. * @param $paraMap
  77. * @param bool $urlEncode
  78. * @return bool|string
  79. */
  80. protected function formatQueryParaMap($paraMap, $urlEncode = false)
  81. {
  82. $buff = "";
  83. ksort($paraMap);
  84. foreach ($paraMap as $k => $v) {
  85. if (null != $v && "null" != $v) {
  86. if ($urlEncode) {
  87. $v = urlencode($v);
  88. }
  89. $buff .= $k . "=" . $v . "&";
  90. }
  91. }
  92. $reqPar = '';
  93. if (strlen($buff) > 0) {
  94. $reqPar = substr($buff, 0, strlen($buff) - 1);
  95. }
  96. return $reqPar;
  97. }
  98. /**
  99. * 需要使用证书的请求
  100. * @param $xml
  101. * @param $url
  102. * @param int $second
  103. * @return bool|mixed
  104. */
  105. protected function postXmlSSLCurl($xml, $url, $second = 30)
  106. {
  107. $ch = curl_init();
  108. curl_setopt($ch, CURLOPT_TIMEOUT, $second);
  109. curl_setopt($ch, CURLOPT_URL, $url);
  110. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  111. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
  112. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  113. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  114. curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');
  115. curl_setopt($ch, CURLOPT_SSLCERT, $this->SSLCERT_PATH);
  116. curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');
  117. curl_setopt($ch, CURLOPT_SSLKEY, $this->SSLKEY_PATH);
  118. curl_setopt($ch, CURLOPT_POST, true);
  119. curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
  120. $data = curl_exec($ch);
  121. if ($data) {
  122. curl_close($ch);
  123. return $data;
  124. } else {
  125. $error = curl_errno($ch);
  126. echo "curl出错,错误码:$error" . "<br>";
  127. curl_close($ch);
  128. return false;
  129. }
  130. }
  131. }