当前位置:首页 > PHP教程 > php高级应用 > 列表

php实现微信支付之退款功能

发布:smiling 来源: PHP粉丝网  添加日期:2021-09-21 19:54:05 浏览: 评论:0 

网上的很多PHP微信支付接入教程都颇为复杂,且需要配置和引入较多的文件,本人通过整理后给出一个单文件版的,希望可以给各位想接入微信支付的带来些许帮助和借鉴意义。

直接运行该文件即可给指定的微信用户退款。

需要注意的事项:

1.微信退款到零钱要求必传证书,需要到这里账户中心->账户设置->API安全->下载证书,然后修改代码中的证书路径

2.该文件需放到支付授权目录下,可以在微信支付商户平台->产品中心->开发配置中设置。

3.如提示签名错误可以通过微信支付签名验证工具进行验证:微信公众平台支付接口调试工具

4.错误码参照:参照地址代码如下:

  1. <?php 
  2. /** 
  3.  * 关于微信退款的说明 
  4.  * 1.微信退款要求必传证书,需要到https://pay.weixin.qq.com 账户中心->账户设置->API安全->下载证书,证书路径在第119行和122行修改 
  5.  * 2.错误码参照 :https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_4 
  6.  */ 
  7. header('Content-type:text/html; Charset=utf-8'); 
  8. $mchid = 'xxxxx';     //微信支付商户号 PartnerID 通过微信支付商户资料审核后邮件发送 
  9. $appid = 'xxxxx'//微信支付申请对应的公众号的APPID 
  10. $apiKey = 'xxxxx';  //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 
  11. $orderNo = '';           //商户订单号(商户订单号与微信订单号二选一,至少填一个) 
  12. $wxOrderNo = '';           //微信订单号(商户订单号与微信订单号二选一,至少填一个) 
  13. $totalFee = 0.01;          //订单金额,单位:元 
  14. $refundFee = 0.01;         //退款金额,单位:元 
  15. $refundNo = 'refund_'.uniqid();    //退款订单号(可随机生成) 
  16. $wxPay = new WxpayService($mchid,$appid,$apiKey); 
  17. $result = $wxPay->doRefund($totalFee$refundFee$refundNo$wxOrderNo,$orderNo); 
  18. if($result===true){ 
  19.   echo 'refund success';exit(); 
  20. echo 'refund fail'
  21. class WxpayService 
  22.   protected $mchid
  23.   protected $appid
  24.   protected $apiKey
  25.   public $data = null; 
  26.   public function __construct($mchid$appid$key
  27.   { 
  28.     $this->mchid = $mchid//https://pay.weixin.qq.com 产品中心-开发配置-商户号 
  29.     $this->appid = $appid//微信支付申请对应的公众号的APPID 
  30.     $this->apiKey = $key;  //https://pay.weixin.qq.com 帐户设置-安全设置-API安全-API密钥-设置API密钥 
  31.   } 
  32.   /** 
  33.    * 退款 
  34.    * @param float $totalFee 订单金额 单位元 
  35.    * @param float $refundFee 退款金额 单位元 
  36.    * @param string $refundNo 退款单号 
  37.    * @param string $wxOrderNo 微信订单号 
  38.    * @param string $orderNo 商户订单号 
  39.    * @return string 
  40.    */ 
  41.   public function doRefund($totalFee$refundFee$refundNo$wxOrderNo='',$orderNo=''
  42.   { 
  43.     $config = array
  44.       'mch_id' => $this->mchid, 
  45.       'appid' => $this->appid, 
  46.       'key' => $this->apiKey, 
  47.     ); 
  48.     $unified = array
  49.       'appid' => $config['appid'], 
  50.       'mch_id' => $config['mch_id'], 
  51.       'nonce_str' => self::createNonceStr(), 
  52.       'total_fee' => intval($totalFee * 100),    //订单金额  单位 转为分 
  53.       'refund_fee' => intval($refundFee * 100),    //退款金额 单位 转为分 
  54.       'sign_type' => 'MD5',      //签名类型 支持HMAC-SHA256和MD5,默认为MD5 
  55.       'transaction_id'=>$wxOrderNo,        //微信订单号 
  56.       'out_trade_no'=>$orderNo,    //商户订单号 
  57.       'out_refund_no'=>$refundNo,    //商户退款单号 
  58.       'refund_desc'=>'商品已售完',   //退款原因(选填) 
  59.     ); 
  60.     $unified['sign'] = self::getSign($unified$config['key']); 
  61.     $responseXml = $this->curlPost('https://api.mch.weixin.qq.com/secapi/pay/refund', self::arrayToXml($unified)); 
  62.     $unifiedOrder = simplexml_load_string($responseXml'SimpleXMLElement', LIBXML_NOCDATA); 
  63.     if ($unifiedOrder === false) { 
  64.       die('parse xml error'); 
  65.     } 
  66.     if ($unifiedOrder->return_code != 'SUCCESS') { 
  67.       die($unifiedOrder->return_msg); 
  68.     } 
  69.     if ($unifiedOrder->result_code != 'SUCCESS') { 
  70.       die($unifiedOrder->err_code); 
  71.     } 
  72.     return true; 
  73.   } 
  74.   public static function curlGet($url = ''$options = array()) 
  75.   { 
  76.     $ch = curl_init($url); 
  77.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  78.     curl_setopt($ch, CURLOPT_TIMEOUT, 30); 
  79.     if (!emptyempty($options)) { 
  80.       curl_setopt_array($ch$options); 
  81.     } 
  82.     //https请求 不验证证书和host 
  83.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  84.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
  85.     $data = curl_exec($ch); 
  86.     curl_close($ch); 
  87.     return $data
  88.   } 
  89.   public function curlPost($url = ''$postData = ''$options = array()) 
  90.   { 
  91.     if (is_array($postData)) { 
  92.       $postData = http_build_query($postData); 
  93.     } 
  94.     $ch = curl_init(); 
  95.     curl_setopt($ch, CURLOPT_URL, $url); 
  96.     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
  97.     curl_setopt($ch, CURLOPT_POST, 1); 
  98.     curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); 
  99.     curl_setopt($ch, CURLOPT_TIMEOUT, 30); //设置cURL允许执行的最长秒数 
  100.     if (!emptyempty($options)) { 
  101.       curl_setopt_array($ch$options); 
  102.     } 
  103.     //https请求 不验证证书和host 
  104.     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); 
  105.     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); 
  106.     //第一种方法,cert 与 key 分别属于两个.pem文件 
  107.     //默认格式为PEM,可以注释 
  108.     curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); 
  109.     curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/cert/apiclient_cert.pem'); 
  110.     //默认格式为PEM,可以注释 
  111.     curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); 
  112.     curl_setopt($ch,CURLOPT_SSLKEY,getcwd().'/cert/apiclient_key.pem'); 
  113.     //第二种方式,两个文件合成一个.pem文件 
  114. //    curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem'); 
  115.     $data = curl_exec($ch); 
  116.     curl_close($ch); 
  117.     return $data
  118.   } 
  119.   public static function createNonceStr($length = 16) 
  120.   { 
  121.     $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'
  122.     $str = ''
  123.     for ($i = 0; $i < $length$i++) { 
  124.       $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 
  125.     } 
  126.     return $str
  127.   } 
  128.   public static function arrayToXml($arr
  129.   { 
  130.     $xml = "<xml>"
  131.     foreach ($arr as $key => $val) { 
  132.       if (is_numeric($val)) { 
  133.         $xml .= "<" . $key . ">" . $val . "</" . $key . ">"
  134.       } else 
  135.         $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"
  136.     } 
  137.     $xml .= "</xml>"
  138.     return $xml
  139.   } 
  140.   public static function getSign($params$key
  141.   { 
  142.     ksort($params, SORT_STRING); 
  143.     $unSignParaString = self::formatQueryParaMap($params, false); 
  144.     $signStr = strtoupper(md5($unSignParaString . "&key=" . $key)); 
  145.     return $signStr
  146.   } 
  147.   protected static function formatQueryParaMap($paraMap$urlEncode = false) 
  148.   { 
  149.     $buff = ""
  150.     ksort($paraMap); 
  151.     foreach ($paraMap as $k => $v) { 
  152.       if (null != $v && "null" != $v) { 
  153.         if ($urlEncode) { 
  154.           $v = urlencode($v); 
  155.         } 
  156.         $buff .= $k . "=" . $v . "&"
  157.       } 
  158.     } 
  159.     $reqPar = ''
  160.     if (strlen($buff) > 0) { 
  161.       $reqPar = substr($buff, 0, strlen($buff) - 1); 
  162.     } 
  163.     return $reqPar
  164.   } 
  165. ?>

Tags: php微信支付 php微信退款

分享到: