tp5微信開發(五)--- tp5微信企業付款到零錢開發實踐

葉落無痕123發表於2020-11-02

專案需求:客戶有一個分銷專案,需要對分享獲得的獎勵直接發放至客戶零錢錢包。

開發文件傳送門:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1

企業付款到使用者零錢開通條件:

  1、商戶號(或同主體其他非服務商商戶號)已入駐90日

  2、商戶號(或同主體其他非服務商商戶號)有30天連續正常交易

  3、 登入微信支付商戶平臺-產品中心,開通企業付款。

企業付款資金來源:

◆ 預設情況下,企業付款到零錢使用商戶號基本戶(或餘額賬戶)餘額。如商戶號已開通運營賬戶,則企業付款到零錢使用運營賬戶內的資金。

◆ 基本戶(或上述其他出款賬戶)的資金來源,可能是交易結算款項(僅基本戶),或給賬戶充值的資金。當出款賬戶餘額不足時,付款將因餘額不足而付款失敗。

專案準備:分銷關係的建立不做說明,現在假設已建立上下級關係,下級支付後對使用者進行佣金獎勵。

程式碼實際上網上已經有很多版本demo,我選了一個並與其他版本進行比對,經過三個小時踩坑和各種除錯,總結了一個可執行版本。

程式碼:

 
  1. public function sendMoney($amount,$re_openid,$desc='推薦獎勵',$check_name=''){

  2. $total_amount = (100) * $amount;

  3. $data=array(

  4. 'mch_appid'=> '',//商戶賬號appid

  5. 'mchid'=> '',//商戶號

  6. 'nonce_str'=> $this->createNoncestr(),//隨機字串

  7. 'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商戶訂單號

  8. 'openid'=> $re_openid,//使用者openid

  9. 'check_name'=>'NO_CHECK',//校驗使用者姓名選項,

  10. 're_user_name'=> $check_name,//收款使用者姓名

  11. 'amount'=>$total_amount,//金額

  12. 'desc'=> $desc,//企業付款描述資訊

  13. 'spbill_create_ip'=> '',//Ip地址

  14. );

  15. $secrect_key = '';//API密碼

  16. $data = array_filter($data);

  17. ksort($data);

  18. $str ='';

  19. foreach($data as $k=>$v) {

  20. $str.=$k.'='.$v.'&';

  21. }

  22. $str.='key='.$secrect_key;

  23. $data['sign'] = md5($str);

  24. $xml = $this->arraytoxml($data);

  25. $url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //呼叫介面

  26. $res = $this->wx_curl($xml,$url);

  27. $return = $this->xmltoarray($res);

  28.  
  29. $responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);

  30. echo $res= $responseObj->return_code; //SUCCESS 如果返回來SUCCESS,則發生成功,處理自己的邏輯

  31.  
  32. return $res;

  33. }

  34.  
  35. public function createNoncestr($length =32){

  36. $chars = "abcdefghijklmnopqrstuvwxyz0123456789";

  37. $str ="";

  38. for ( $i = 0; $i < $length; $i++ ) {

  39. $str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);

  40. }

  41. return $str;

  42. }

  43.  
  44. public function arraytoxml($data){

  45. $str='<xml>';

  46. foreach($data as $k=>$v) {

  47. $str.='<'.$k.'>'.$v.'</'.$k.'>';

  48. }

  49. $str.='</xml>';

  50. return $str;

  51. }

  52.  
  53. public function xmltoarray($xml) {

  54. //禁止引用外部xml實體

  55. libxml_disable_entity_loader(true);

  56. $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);

  57. $val = json_decode(json_encode($xmlstring),true);

  58. return $val;

  59. }

  60.  
  61. public function wx_curl($vars,$url,$second = 30, $aHeader = array()) {

  62. $isdir = ROOT_PATH."cert/";//證照位置

  63. $ch = curl_init();//初始化curl

  64. curl_setopt($ch, CURLOPT_TIMEOUT, $second);//設定執行最長秒數

  65. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求結果為字串且輸出到螢幕上

  66. curl_setopt($ch, CURLOPT_URL, $url);//抓取指定網頁

  67. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);// 終止從服務端進行驗證

  68. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);//

  69. curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//證照型別

  70. curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//證照位置

  71. curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中規定的私鑰的加密型別

  72. curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//證照位置

  73. if (count($aHeader) >= 1) {

  74. curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//設定頭部

  75. }

  76. curl_setopt($ch, CURLOPT_POST, 1);//post提交方式

  77. curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部資料使用HTTP協議中的"POST"操作來傳送

  78.  
  79. $data = curl_exec($ch);//執行回話

  80. if ($data) {

  81. curl_close($ch);

  82. return $data;

  83. } else {

  84. $error = curl_errno($ch);

  85. echo "call faild, errorCode:$error\n";

  86. curl_close($ch);

  87. return false;

  88. }

  89. }

測試方法:新建一個check方法,通過訪問域名/index/base/send_check 進行測試:

備註說明:第一個引數是付款金額,第二個引數是收款openid,這個我本身已經存的有所以直接從資料庫貼上過來的。

 
  1. public function send_check(){

  2. $this->sendMoney(1,'olrMRuIULa1k_GKC7XwLWPlH0IA8','哎咖啡付款到零錢測試');

  3. }

劃重點:

1,付款到零錢需要用到證照,現在微信已經在推行新的api證照,新版證照生成說明傳送門:https://kf.qq.com/faq/180824BrQnQB180824m6v2yA.html 操作不難,按照指引,就兩個複製貼上的事,最終點選生成會自動下載一個證照壓縮包。

我們是php的,所以用得到下面兩個證照檔案,在tp5專案根目錄下建立 cert 資料夾,並上傳兩個證照檔案【我看有的網友總結說,證照必須要放到根目錄而且必須是cert命名,這個我沒有求證,不知道是否是強制要求,不過我是的確是這麼做的】。

2,在測試過程中,總會踩各種各樣的坑,我把我大概的除錯過程中遇到的錯誤進行說明:

   1),列印curl 返回錯誤 int(58),查詢 curl 對應返回碼得知是證照問題,我能確定我證照是最新生成的,所以證照是沒問題,查文件要求證照檔案必須是絕對路徑,改之,成功。對於證照檔案路徑,可在curl請求中列印具體路徑值,確保是絕對路徑。

  2),提示簽名錯誤,核驗方法:一再需要確認商戶號,appid以及支付祕鑰是否正確,我當時沒留意,就這個問題查了一個小時,結果發現是商戶號寫的是之前測試對應的賬戶,結果一直都驗籤不成功,WTF!

  3),支付提示賬戶餘額不足,查客戶的基本賬戶,交易型別設定的是T+1的,可能是這個原因,導致商戶收到的錢都直接轉到客戶指定的銀行賬號了,點選交易中心->充值->選擇銀行,充值了測試金,返回繼續訪問路由,OK,成功。

最終效果:

 

 

轉載自:https://blog.csdn.net/qq_27987023/article/details/89810035

 

 

相關文章