一 . 小程序提現到零錢的官方文檔,建議先看下,再看下面的代碼
地址: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;
}
