一 . 小程序提現到零錢的官方文檔,建議先看下,再看下面的代碼
地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
付款規則:
調用接口所需參數,除下圖中所需參數外,還需要小程序的支付key,證書。這兩樣在商戶平台可以查看到,請提前准備好:
二 . 小程序提現到零錢不同於小程序退款,調用的是不同的微信接口,我的博客園也記載了小程序的退款,如有需要,前往查看。
三 . 准備好所需的參數后,只需要把我代碼中對應的參數更改為你的,就可以用了
//微信小程序提現到零錢 public function wxWithdraw(Request $request) { //$openid = $request->param('wxopenid'); $openid = '接收提現的用戶openid'; $amount = $request->param('w_money'); $data = [ 'mch_appid' => '小程序appid', 'mchid' => '小程序商戶號',//商戶號 'nonce_str' => self::getNonceStr(),//隨機字符串,長度要求在32位以內 'partner_trade_no' => self::create_order_no(),//商戶訂單號 'openid' => $openid, 'check_name' => 'NO_CHECK', 'amount' => 30,//標價金額,單位分 'desc' => '提現的描述', 'spbill_create_ip' => self::getip()//終端IP ]; $data['sign'] = self::makeSign($data); $xmldata = self::array2xml($data); $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; $res = self::curl_post_ssl2($url, $xmldata); if (empty($res)) { return json(['status' => 0, 'data' => '', 'msg' => '連接失敗']); } $content = self::xml2array($res); p($content);//打印提現結果 } //商戶系統內部訂單號,要求32個字符內 public function getNonceStr($length = 32) { $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; $str = ""; for ( $i = 0; $i < $length; $i++ ) { $str .= substr($chars, mt_rand(0, strlen($chars)-1), 1); } return $str; } //生成唯一訂單號(簡化版) public function create_order_no() { $order_no = substr(date('YmdHis'),2).rand(10000, 99999); return $order_no; } //獲取IP地址 public function getip() { static $ip = ''; $ip = $_SERVER['REMOTE_ADDR']; if(isset($_SERVER['HTTP_CDN_SRC_IP'])) { $ip = $_SERVER['HTTP_CDN_SRC_IP']; } elseif (isset($_SERVER['HTTP_CLIENT_IP']) && preg_match('/^([0-9]{1,3}\.){3}[0-9]{1,3}$/', $_SERVER['HTTP_CLIENT_IP'])) { $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif(isset($_SERVER['HTTP_X_FORWARDED_FOR']) AND preg_match_all('#\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}#s', $_SERVER['HTTP_X_FORWARDED_FOR']matches)) { foreach ($matches[0] AS $xip) { if (!preg_match('#^(10|172\.16|192\.168)\.#', $xip)) { $ip = $xip; break; } } } return $ip; } //生成簽名 public function makeSign($data){ //獲取微信支付秘鑰 $key = "小程序支付key";//這個在微信商戶平台可以查看 // 去空 $data=array_filter($data); //簽名步驟一:按字典序排序參數 ksort($data); $string_a=http_build_query($data); $string_a=urldecode($string_a); //簽名步驟二:在string后加入KEY $string_sign_temp=$string_a."&key=".$key; //簽名步驟三:MD5加密 $sign = md5($string_sign_temp); // 簽名步驟四:所有字符轉為大寫 $result=strtoupper($sign); return $result; } public function array2xml($arr, $level = 1) { $s = $level == 1 ? "<xml>" : ''; foreach ($arr as $tagname => $value) { if (is_numeric($tagname)) { $tagname = $value['TagName']; unset($value['TagName']); } if (!is_array($value)) { $s .= "<{$tagname}>" . (!is_numeric($value) ? '<![CDATA[' : '') . $value . (!is_numeric($value) ? ']]>' : '') . "</{$tagname}>"; } else { $s .= "<{$tagname}>" . $this->array2xml($value, $level + 1) . "</{$tagname}>"; } } $s = preg_replace("/([\x01-\x08\x0b-\x0c\x0e-\x1f])+/", ' ', $s); return $level == 1 ? $s . "</xml>" : $s; } public function curl_post_ssl2($url, $xmldata, $second=30,$aHeader=array()){ $isdir = str_replace('Api.php','',__FILE__) . 'cert/';//這個是證書,需要到微信商戶平台下載,然后放到服務器上 $ch = curl_init(); curl_setopt($ch,CURLOPT_TIMEOUT,$second); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); //這里設置代理,如果有的話 //curl_setopt($ch,CURLOPT_PROXY, '10.206.30.98'); //curl_setopt($ch,CURLOPT_PROXYPORT, 8080); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,false); curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader); curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');//證書類型 curl_setopt($ch, CURLOPT_SSLCERT, $isdir . 'apiclient_cert.pem');//證書位置 curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');//CURLOPT_SSLKEY中規定的私鑰的加密類型 curl_setopt($ch, CURLOPT_SSLKEY, $isdir . 'apiclient_key.pem');//證書位置 curl_setopt($ch, CURLOPT_CAINFO, 'PEM'); //curl_setopt($ch, CURLOPT_CAINFO, $isdir . 'rootca.pem');這個是可選的 curl_setopt($ch,CURLOPT_POST, 1); curl_setopt($ch,CURLOPT_POSTFIELDS,$xmldata); $data = curl_exec($ch); if(curl_errno($ch)){ echo 'Error+'.curl_error($ch); } curl_close($ch); return $data; } //將xml轉為array public function xml2array($xml){ //禁止引用外部xml實體 libxml_disable_entity_loader(false); $result= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $result; }