/*** @Notes:退款* @param $out_trade_no 支付時候訂單號(order表 original_bn)兩個參數選一個這個要選對* @param $out_refund_no 退款訂單號* @param $total 訂單金額* @param $refund 退款金額* @Time: 2023-08-10*/public function refundMoney($out_trade_no , $out_refund_no , $total , $refund){$config = config('wechat.wechat');$time=time();$refundData=['out_refund_no'=>$out_refund_no, //退款訂單號自己生成就好'reason'=>'商品退款','notify_url'=>$config['pay']['refundNotifyUrl'],//退款回調地址'out_trade_no' => $out_trade_no,'amount'=>['refund'=> $refund, //退款標價金額,單位為分,可以做部分退款'total'=> $total, //訂單總金額,單位為分'currency'=>'CNY']];$url='https://api.mch.weixin.qq.com/v3/refund/domestic/refunds';$urlarr = parse_url($url); //拆解為:[scheme=>https,host=>api.mch.weixin.qq.com,path=>/v3/pay/transactions/native]$mchid =$config['pay']['merchantId'];//商戶ID$xlid = $config['pay']['serialNumber'];//證書序列號$refundData=json_encode($refundData);$nonce = $this->randomString();$key = $this->getSign($refundData,$urlarr['path'],$nonce,$time);$token = sprintf('mchid="%s",serial_no="%s",nonce_str="%s",timestamp="%d",signature="%s"',$mchid,$xlid,$nonce,$time,$key);$header = array('Accept: application/json','Content-Type: application/json','User-Agent:*/*','Authorization: WECHATPAY2-SHA256-RSA2048 '.$token);$res=$this->curl_post_https($url,$refundData,$header);$res_array=json_decode($res,true);return $res_array;}
// 生成隨機字符串private function randomString($len = 32){$string = '';$char = 'ABCDEFGHJKMNPQRSTWXYZabcdefhijkmnprstwxyz2345678';for ($i = 0; $i < $len; $i++) {$string .= $char[mt_rand(0, strlen($char) - 1)];}return $string;}//微信支付簽名function getSign($data=array(),$url,$randstr,$time){$str = "POST"."\n".$url."\n".$time."\n".$randstr."\n".$data."\n";$key = file_get_contents(getcwd() .'/cert/apiclient_key.pem');//在商戶平臺下載的秘鑰,讀取到變量 最好是放到public下邊 $str = $this->getSha256WithRSA($str,$key);return $str;}//加密public function getSha256WithRSA($content, $privateKey){$binary_signature = "";$algo = "SHA256";openssl_sign($content, $binary_signature, $privateKey, $algo);$sign = base64_encode($binary_signature);return $sign;}//退款用function curl_post_https($url,$data,$header){ // 模擬提交數據函數$curl = curl_init(); // 啟動一個CURL會話curl_setopt($curl, CURLOPT_URL, $url); // 要訪問的地址curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 對認證證書來源的檢查curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0); // 從證書中檢查SSL加密算法是否存在,如果出錯則修改為0,默認為1curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模擬用戶使用的瀏覽器curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自動跳轉curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自動設置Referercurl_setopt($curl, CURLOPT_POST, 1); // 發送一個常規的Post請求curl_setopt($curl, CURLOPT_POSTFIELDS, $data); // Post提交的數據包curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 設置超時限制防止死循環curl_setopt($curl, CURLOPT_HEADER, 0); // 顯示返回的Header區域內容curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 獲取的信息以文件流的形式返回curl_setopt($curl, CURLOPT_HTTPHEADER, $header);$tmpInfo = curl_exec($curl); // 執行操作if (curl_errno($curl)) {echo 'Errno'.curl_error($curl);//捕抓異常}curl_close($curl); // 關閉CURL會話return $tmpInfo; // 返回數據,json格式}
調用
$res = WxPay::instance()->refundMoney($order['original_bn'] , $order['order_bn'] , $sum , $order['total_money']);$msg = '';if (!empty($res['code'])) {$msg = $res['message'];}if (!empty($res['status'])) {if ($res['status'] == 'SUCCESS'){$msg = '退款成功';} else if ($res['status'] == 'CLOSED') {$msg = '退款關閉';} else if ($res['status'] == 'PROCESSING') {$msg = '退款處理中';} else if ($res['status'] == 'ABNORMAL') {$msg = '退款異常';}}return $msg;