微信退款一定要寫回調函數!!!一定要寫回調函數!!!一定要寫回調函數!!!
昨天,小編線上的版本微信退款失敗了,失敗了,由於沒寫回調函數,我當時還是一臉蒙蔽,還確信退款成功了,結果打開微信商戶平台發現,還真沒退成功,而且查不到任何信息,不說了,小編這個月要吃土了T_T.
有時候微信退款,會有延時,比如銀行卡支付的,會有1-3個工作日,所以,有些業務邏輯要在回調里寫。
下面擼退款代碼……
首先是申請退款的代碼
1 $app = app('wechat.payment'); 2 $total_money = $order_pay->pay_money * 100; 3 $refund_money = $order_pay->pay_money * 100; 4 $result = $app->refund->byOutTradeNumber( 5 $order_pay->pay_order_id, 6 $order_pay->transaction, 7 $total_money, 8 $refund_money, 9 [ 10 'refund_desc' => $reason, 11 'notify_url' => config('wechat.payment.default.refund_url'), 12 'out_refund_no' => $order_pay->out_refund_no 13 ] 14 ); 15 if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') { 16 Log::info('退款申請請求成功'); 17 }
注意,這里只是申請退款成功,並不是退款成功,因為微信那邊也有可能失敗的。
上面設置了notify_url這個回調地址。微信會把退款結果發送到這個地址,然后你需要寫一些你的業務邏輯。
注意:
在申請退款接口中上傳參數“notify_url”以開通該功能
如果鏈接無法訪問,商戶將無法接收到微信通知。
通知url必須為直接可訪問的url,不能攜帶參數。示例:notify_url:“https://pay.weixin.qq.com/wxpay/pay.action”
如果參數中傳了notify_url,則商戶平台上配置的回調地址將不會生效。
然后接下來就是寫回調函數,處理退款成功/失敗的相關邏輯
微信通知的相關參數
哈哈,是不是沒有看到你想要的參數,比如訂單號,沒關系,微信都返回給你了,只是做了加密處理,都在加密信息req_info這個字段里。
所以在做業務邏輯處理之前,我們先需要對這個req_info做解密處理。
解密步驟如下:
(1)對加密串A做base64解碼,得到加密串B
(2)對商戶key做md5,得到32位小寫key* ( key設置路徑:微信商戶平台(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置 )
(3)用key*對加密串B做AES-256-ECB解密(PKCS7Padding)
看到解密步驟是不是有種吃屎的感覺(故意用了個屎黃色的底色,嘎嘎),很難受。emmmm。。。。還是直接我自己寫(baidu copy)的解密代碼吧。不然我怕你順着網線過來打我
1 public function req_info_decrypt($str, $key = null) 2 { 3 $key = $key ? : md5(config('wechat.payment.default.key')); 4 $str = base64_decode($str); 5 $str = mcrypt_decrypt(MCRYPT_RIJNDAEL_128, $key, $str, MCRYPT_MODE_ECB); 6 $block = mcrypt_get_block_size('rijndael_128', 'ecb'); 7 $pad = ord($str[($len = strlen($str)) - 1]); 8 $len = strlen($str); 9 $pad = ord($str[$len - 1]); 10 $xml = substr($str, 0, strlen($str) - $pad); 11 libxml_disable_entity_loader(true); 12 return json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); 13 }
解密出來的參數:
(未截全)具體參考微信官方文檔。
有了這個自定的解密函數之后就可以愉快的在自己的回調函數里玩耍啦。
回調函數:
1 public function refundSuccess() 2 { 3 $app = app('wechat.payment'); 4 $response = $app->handleRefundedNotify(function ($message, $fail) { 5 if($message['appid'] != config('wechat.payment.default.app_id')){ 6 //不是商戶本身的請求,直接略過 7 return true; 8 } 9 $data = $this->req_info_decrypt($message['req_info']); 10 Log::info($data); 11 $order_pay = OrderPay::where('out_trade_no', $data['out_trade_no'])
14 ->first(); 15 if($order_pay){
18 Log::info('微信退款成功 pay_id:'.$order_pay->pay_id);
30 return true; 31 } 32 Log::info('Order not exists.'); 33 $fail('Order not exists.'); 34 }); 35 return $response; 36 }
好了,差不多就是這樣,上面我把我自己處理的邏輯都給刪掉了。差不多就是改一些訂單的狀態,發通知啊這類。