PHP實現微信開發中提現功能(企業付款到用戶零錢)
一.實現該功能目的
這幾天在小程序里要實現用戶從系統中提現到零錢的功能,查了一下文檔可以使用 企業付款到用戶零錢 來實現;
官方文檔:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1;
注意事項:商戶打款時是從商戶可用余額中減錢,所以確保商戶可用余額充足,同時注意官方文檔中的付款規則;
二.PHP實現
//封裝提現方法 function tixian($money){ $appid = "################";//商戶賬號appid $secret = "##########";//api密碼 $mch_id = "#######";//商戶號 $mch_no = "#######"; $openid="123456789";//授權用戶openid $arr = array(); $arr['mch_appid'] = $appid; $arr['mchid'] = $mch_id; $arr['nonce_str'] = ugv::randomid(20);//隨機字符串,不長於32位 $arr['partner_trade_no'] = '1298016501' . date("Ymd") . rand(10000, 90000) . rand(10000, 90000);//商戶訂單號 $arr['openid'] = $openid; $arr['check_name'] = 'NO_CHECK';//是否驗證用戶真實姓名,這里不驗證 $arr['amount'] = $money;//付款金額,單位為分 $desc = "###提現"; $arr['desc'] = $desc;//描述信息 $arr['spbill_create_ip'] = '192.168.0.1';//獲取服務器的ip //封裝的關於簽名的算法 $notify = new Notify_pub(); $notify->weixin_app_config = array(); $notify->weixin_app_config['KEY'] = $mch_no; $arr['sign'] = $notify->getSign($arr);//簽名 $var = $notify->arrayToXml($arr); $xml = $this->curl_post_ssl('https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers', $var, 30, array(), 1); $rdata = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $return_code = (string)$rdata->return_code; $result_code = (string)$rdata->result_code; $return_code = trim(strtoupper($return_code)); $result_code = trim(strtoupper($result_code)); if ($return_code == 'SUCCESS' && $result_code == 'SUCCESS') { $isrr = array( 'con'=>'ok', 'error' => 0, ); } else { $returnmsg = (string)$rdata->return_msg; $isrr = array( 'error' => 1, 'errmsg' => $returnmsg, ); } return json_encode($isrr); }
//上個方法中用到的curl_post_ssl() function curl_post_ssl($url, $vars, $second = 30, $aHeader = array()) { $isdir = "/cert/";//證書位置 $ch = curl_init();//初始化curl curl_setopt($ch, CURLOPT_TIMEOUT, $second);//設置執行最長秒數 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//要求結果為字符串且輸出到屏幕上 curl_setopt($ch, CURLOPT_URL, $url);//抓取指定網頁 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 終止從服務端進行驗證 curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);// 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'); if (count($aHeader) >= 1) { curl_setopt($ch, CURLOPT_HTTPHEADER, $aHeader);//設置頭部 } curl_setopt($ch, CURLOPT_POST, 1);//post提交方式 curl_setopt($ch, CURLOPT_POSTFIELDS, $vars);//全部數據使用HTTP協議中的"POST"操作來發送 $data = curl_exec($ch);//執行回話 if ($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "call faild, errorCode:$error\n"; curl_close($ch); return false; } }
三.補充
關於具體簽名算法,可參考微信官方文檔;
簡單示范簽名算法:
//將要發送的數據整理為$data ksort($data);//排序 //使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串 $str=''; foreach($data as $k=>$v) { $str.=$k.'='.$v.'&'; } //拼接API密鑰 $str.='key='.$secrect; $data['sign']=md5($str);//加密
將數組轉換成xml格式(簡單方法):
//遍歷數組方法 function arraytoxml($data){ $str='<xml>'; foreach($data as $k=>$v) { $str.='<'.$k.'>'.$v.'</'.$k.'>'; } $str.='</xml>'; return $str; }
將xml格式轉換為數組:
function xmltoarray($xml) { //禁止引用外部xml實體 libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring),true); return $val; }
PHP微信商戶支付企業付款到零錢功能
這幾天在給客戶做一個微信現金紅包功能,需要用到微信支付的企業付款到零錢功能。
微信支付企業付款到零錢功能應用廣泛,比如微信紅包獎勵,業務結算等。通過企業向個人付款,付款資金將直接進入用戶微信零錢。
一 開通條件
付款資金
企業付款到零錢資金使用商戶號余額資金。
根據商戶號的賬戶開通情況,實際出款賬戶有做區別:
◆ 默認情況下,企業付款到零錢使用商戶號基本戶(或余額賬戶)余額。如商戶號已開通運營賬戶,則企業付款到零錢使用運營賬戶內的資金。
◆ 基本戶(或上述其他出款賬戶)的資金來源,可能是交易結算款項(僅基本戶),或給賬戶充值的資金。當出款賬戶余額不足時,付款將因余額不足而付款失敗。
付款規則
付款方式
◆ 支持API接口或網頁操作,付款至目標用戶。
收款用戶身份指定
◆ 通過APPID+OPENID指定收款用戶。
◆ APPID需要為申請商戶號時的APPID,或者與商戶號有綁定關系。
◆ OPENID的獲取方式,可參照:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140839
付款額度
◆ 不支持給非實名用戶打款
◆ 給同一個實名用戶付款,單筆單日限額2W/2W
◆ 一個商戶同一日付款總額限額100W
注意:以上規則中的限額2w、100w由於計算規則與風控策略的關系,不是完全精確值,金額僅做參考,請不要依賴此金額做系統處理,應以接口實際返回和查詢結果為准,請知曉。
收款用戶身份校驗
◆ 針對付款的目標用戶,提供可校驗真實姓名的功能
查詢付款情況
◆ 已付款的記錄,企業可通過企業付款查詢查看相應數據,或者查詢商戶號資金流水。
付款頻次
◆ 默認每天最多可向同一個用戶付款10次,可以在商戶平台--API安全進行設置
其他注意事項
◆ 付款金額必須小於或等於商戶當前可用余額的金額;
二 接口地址
接口鏈接:https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
請求參數:
具體參看官方企業付款開發文檔說明
PHP代碼示例調用
<?php
//企業付款到微信零錢,PHP接口調用方法
define("APPID", "wxde3234454354"); // 商戶賬號appid
define("MCHID", "1900000109"); // 商戶號
define("SECRECT_KEY", "145535866885"); //支付密鑰簽名
define("IP", "120.178.12.52"); //IP
function createNoncestr($length =32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str ="";
for ( $i = 0; $i < $length; $i++ ) {
$str.= substr($chars, mt_rand(0, strlen($chars)-1), 1);
}
return $str;
}
function unicode() {
$str = uniqid(mt_rand(),1);
$str=sha1($str);
return md5($str);
}
function arraytoxml($data){
$str='<xml>';
foreach($data as $k=>$v) {
$str.='<'.$k.'>'.$v.'</'.$k.'>';
}
$str.='</xml>';
return $str;
}
function xmltoarray($xml) {
//禁止引用外部xml實體
libxml_disable_entity_loader(true);
$xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
$val = json_decode(json_encode($xmlstring),true);
return $val;
}
function curl($param="",$url) {
$postUrl = $url;
$curlPost = $param;
$ch = curl_init(); //初始化curl
curl_setopt($ch, CURLOPT_URL,$postUrl); //抓取指定網頁
curl_setopt($ch, CURLOPT_HEADER, 0); //設置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求結果為字符串且輸出到屏幕上
curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost); // 增加 HTTP Header(頭)里的字段
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 終止從服務端進行驗證
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch,CURLOPT_SSLCERT,ROOT_PATH .'/wxpay/cacert/apiclient_cert.pem'); //這個是證書的位置絕對路徑
curl_setopt($ch,CURLOPT_SSLKEY,ROOT_PATH .'/wxpay/cacert/apiclient_key.pem'); //這個也是證書的位置絕對路徑
$data = curl_exec($ch); //運行curl
curl_close($ch);
return $data;
}
/*
$amount 發送的金額(分)目前發送金額不能少於1元
$re_openid, 發送人的 openid
$desc // 企業付款描述信息 (必填)
$check_name 收款用戶姓名 (選填)
*/
function sendMoney($amount,$re_openid,$desc='測試',$check_name=''){
$total_amount = (100) * $amount;
$data=array(
'mch_appid'=>APPID,//商戶賬號appid
'mchid'=> MCHID,//商戶號
'nonce_str'=>createNoncestr(),//隨機字符串
'partner_trade_no'=> date('YmdHis').rand(1000, 9999),//商戶訂單號
'openid'=> $re_openid,//用戶openid
'check_name'=>'NO_CHECK',//校驗用戶姓名選項,
're_user_name'=> $check_name,//收款用戶姓名
'amount'=>$total_amount,//金額
'desc'=> $desc,//企業付款描述信息
'spbill_create_ip'=> IP,//Ip地址
);
$secrect_key=SECRECT_KEY;///這個就是個API密碼。MD5 32位。
$data=array_filter($data);
ksort($data);
$str='';
foreach($data as $k=>$v) {
$str.=$k.'='.$v.'&';
}
$str.='key='.$secrect_key;
$data['sign']=md5($str);
$xml=arraytoxml($data);
$url='https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; //調用接口
$res=curl($xml,$url);
$return=xmltoarray($res);
print_r($return);
//返回來的結果
// [return_code] => SUCCESS [return_msg] => Array ( ) [mch_appid] => wxd44b890e61f72c63 [mchid] => 1493475512 [nonce_str] => 616615516 [result_code] => SUCCESS [partner_trade_no] => 20186505080216815
// [payment_no] => 1000018361251805057502564679 [payment_time] => 2018-05-15 15:29:50
$responseObj = simplexml_load_string($res, 'SimpleXMLElement', LIBXML_NOCDATA);
echo $res= $responseObj->return_code; //SUCCESS 如果返回來SUCCESS,則發生成功,處理自己的邏輯
return $res;
}
?>
三 調用方法 :
sendMoney(1,'ewrwexe32423423423423423','xxxx測試');
注釋 :調用的話,稍微在修改下,加上自己的業務邏輯就行了。
調用效果:
注釋 :調用的話,稍微在修改下,加上自己的業務邏輯就行了。
---------------------
作者:Json2008
來源:CSDN
原文:https://blog.csdn.net/fengqingtao2008/article/details/80244182
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
淺析微信支付:(余額提現)企業付款到微信用戶零錢或銀行卡賬戶
淺析微信支付系列已經更新十二篇了喲~,沒有看過的朋友們可以看一下哦。
如果你是做電商或者某些有福利返利的系統,基本上會遇到諸如 余額提現
這類需求,主要就是平台向用戶返利現金,積累到某一個門檻,可以領取到自己的余額賬號、銀行卡;或者是使用為用戶發送現金紅包的方式。
接下來的兩篇文章,會為大家描述在微信支付中,像用戶付款的以上三種方式。
以下為三種付款方式的必要條件:
- 商戶號(或同主體其他非服務商商戶號)已入駐90日
- 商戶號(或同主體其他非服務商商戶號)有30天連續正常交易
- 登錄微信支付商戶平台-產品中心,開通企業付款。
企業付款到微信用戶零錢
企業付款提供由商戶直接付錢至用戶微信零錢的能力,支持平台操作及接口調用兩種方式,資金到賬速度快,使用及查詢方便。主要用來解決合理的商戶對用戶付款需求,比如:保險理賠、彩票兌換等等。
如何開通?
- 入駐成為商戶:在線提交營業執照、身份證、銀行賬戶等基本信息,快速提交申請;
- 超級管理員開通:前往商戶平台-產品中心-企業付款到零錢-申請開通;
- 特殊要求:交易資金是即時入賬到商戶號基本戶的商戶,需要滿足以下要求:需入駐滿90天,連續交易30天。
所需資料:開通企業付款到零錢功能無需提供額外的材料。
費用:試用期間免費使用。
應用場景
企業付款為企業提供付款至用戶零錢的能力,支持通過API接口付款,或通過微信支付商戶平台(pay.weixin.qq.com)網頁操作付款。
以下為官方的解釋:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_1
抓重點,首先需要知道的是,開通了運營賬戶
的商戶,付款時會從運營賬戶余額中扣除,這個一定要注意,以免金額不足時付款失敗(可以使用主賬戶為運營賬戶充值,參考[交易中心]-[充值/轉入])。
以下為特別需要注意的地方,為大家標記出來,設計系統時一定要參考一下,以免入坑。
接口鏈接
https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers
是否需要證書
請求需要雙向證書。
調用接口
注意事項:
◆ 當返回錯誤碼為“SYSTEMERROR”時,請不要更換商戶訂單號,一定要使用原商戶訂單號重試,否則可能造成重復支付等資金風險。
◆ XML具有可擴展性,因此返回參數可能會有新增,而且順序可能不完全遵循此文檔規范,如果在解析回包的時候發生錯誤,請商戶務必不要換單重試,請商戶聯系客服確認付款情況。如果有新回包字段,會更新到此API文檔中。
◆ 因為錯誤代碼字段err_code的值后續可能會增加,所以商戶如果遇到回包返回新的錯誤碼,請商戶務必不要換單重試,請商戶聯系客服確認付款情況。如果有新的錯誤碼,會更新到此API文檔中。
◆ 錯誤代碼描述字段err_code_des只供人工定位問題時做參考,系統實現時請不要依賴這個字段來做自動化處理。
PS:目前支持向指定微信用戶的openid付款。
官方文檔如下:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2
具體的傳入參數,這里就不一一列舉了,請大家參考一下官方文檔,下面貼上具體的實現源碼:
/** * [微信支付提現接口] - 保存調用的相關記錄 * @param payment 支付對象 * @param wxPayConfig 微信支付單例對象 * @return map * * @author yclimb * @date 2018/7/30 */ public Map<String, String> saveWxPayTransfers(Payment payment, WXPayConfig wxPayConfig) throws Exception { // 支付前驗證 // 微信支付對象 // WXPay wxPay = new WXPay(WXPayConfigImpl.getInstance()); WXPay wxPay = new WXPay(wxPayConfig); // 微信退款接口 Map<String, String> resultMap = wxPay.transfers(...); logger.info("saveWxPayTransfers:resultMap:" + resultMap.toString()); // 下單失敗,進行處理 if (WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RETURN_CODE)) || WXPayConstants.FAIL.equals(resultMap.get(WXPayConstants.RESULT_CODE))) { // 處理結果返回,無需繼續執行 // 余額不足提醒 if (WXPayCodeEnum.ERR_CODE_NOTENOUGH.getCode().equals(resultMap.get(WXPayConstants.ERR_CODE))) { // 發送余額不足的消息提醒 } } // 付款記錄修改 & 記錄付款日志 return resultMap; }
以上為調用的應用方法,下面為大家貼出微信接口調用代碼 imall.weixin.sdk.WXPay
:
/** * 作用:企業向微信用戶個人付款<br> * 場景:企業付款為企業提供付款至用戶零錢的能力,支持通過API接口付款,或通過微信支付商戶平台(pay.weixin.qq.com)網頁操作付款。 * 接口文檔地址:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 * * @param partner_trade_no 商戶訂單號 * @param openid 用戶openid * @param amount 企業付款金額 * @param desc 企業付款描述信息 * @param spbill_create_ip 該IP可傳用戶端或者服務端的IP * @return API返回數據 * @throws Exception e */ public Map<String, String> transfers(String partner_trade_no, String openid, String amount, String desc, String spbill_create_ip) throws Exception { /** 構造請求參數數據 **/ Map<String, String> data = new HashMap<>(); // 商戶訂單號 partner_trade_no 是 10000098201411111234567890 String 商戶訂單號,需保持唯一性(只能是字母或者數字,不能包含有符號) data.put("partner_trade_no", partner_trade_no); // 用戶openid openid 是 oxTWIuGaIt6gTKsQRLau2M0yL16E String 商戶appid下,某用戶的openid data.put("openid", openid); // 校驗用戶姓名選項 check_name 是 FORCE_CHECK String NO_CHECK:不校驗真實姓名,FORCE_CHECK:強校驗真實姓名 data.put("check_name", "NO_CHECK"); // 金額 amount 是 10099 int 企業付款金額,單位為分 data.put("amount", String.valueOf(new BigDecimal(amount).multiply(new BigDecimal(100)).setScale(2, BigDecimal.ROUND_HALF_UP).intValue())); // 企業付款描述信息 desc 是 理賠 String 企業付款操作說明信息。必填。 data.put("desc", desc); // Ip地址 spbill_create_ip 是 192.168.0.1 String(32) 該IP同在商戶平台設置的IP白名單中的IP沒有關聯,該IP可傳用戶端或者服務端的IP。 data.put("spbill_create_ip", spbill_create_ip); /** 以下參數為非必填參數 **/ /*// 設備號 device_info 否 013467007045764 String(32) 微信支付分配的終端設備號 data.put("device_info", "xxx"); // 收款用戶姓名 re_user_name 可選 王小王 String 收款用戶真實姓名。(如果check_name設置為FORCE_CHECK,則必填用戶真實姓名) data.put("re_user_name", "xxx");*/ // 微信調用接口 Map<String, String> resultMap = this.transfers(data); WXPayUtil.getLogger().info("wxPay.transfers:" + resultMap); return resultMap; }
PS:推薦數據庫中對於金額存儲為數值單位,以分為單位來存儲,1.1元可以儲存為101,這樣和微信對應,會方便很多。
對於企業付款查詢的接口,這里就不詳細描述了,以下為具體的官方文檔鏈接:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3
需要的朋友,根據文檔進行接口查詢即可,非高頻接口。
企業付款到銀行卡
企業付款到銀行卡提供由商戶直接付錢至指定銀行卡賬戶的能力,支持平台操作及接口調用兩種方式,資金到賬速度快,使用及查詢方便。主要用來解決合理的商戶對用戶付款需求,比如:保險理賠、彩票兌換等等。
開通流程:
- 入駐成為商戶:在線提交營業執照、身份證、銀行賬戶等基本信息,快速提交申請;
- 超級管理員開通:前往商戶平台-產品中心-企業付款到銀行卡-申請開通;
- 特殊要求:交易資金是即時入賬到商戶號基本戶的商戶,需要滿足以下要求:需入駐滿90天,連續交易30天。
所需資料:開通企業付款到銀行卡功能無需提供額外的材料。
費用:此功能需收取手續費,按照單筆金額收取,每筆收取0.1%,最低1元,最高25元。
應用場景
微信支付已上線企業付款至銀行卡功能。商戶可以將商戶號余額付款至指定的收款銀行賬戶。通過指定收款銀行賬戶戶名、卡號,以及收款銀行信息即可實現付款。
官方文檔地址:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_1&index=1
功能說明:
- 企業付款至銀行卡只支持新資金流類型賬戶
- 目前企業付款到銀行卡支持17家銀行,更多銀行逐步開放中
- 付款到賬實效為1-3日,最快次日到賬
- 每筆按付款金額收取手續費,按金額0.1%收取,最低1元,最高25元,如果商戶開通了運營賬戶,手續費和付款的金額都從運營賬戶出。如果沒有開通,則都從基本戶出。
- 每個商戶號每天可以出款100萬,單商戶給同一銀行卡付款每天限額5萬
- 發票:在賬戶中心-發票信息頁面申請開票的商戶會按月收到發票(已申請的無需重復申請)。
企業付款到銀行卡發票與交易手續費發票為拆分單獨開具。
需要注意的是,微信支持的銀行有限,具體的支持銀行見如下鏈接:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_4&index=5
所以肯定會出現不支持的銀行,小伙伴們在開發的時候,可以在前后端控制用戶選擇提現銀行來解決。
平台上手動付款流程:
- 在產品中心,開通企業付款到個人銀行卡功能
- 進入交易中心-企業付款到銀行卡頁面進行付款
- 指定收款銀行賬號、戶名、收款方開戶行,及付款金額信息,即可實現付款
接口鏈接
https://api.mch.weixin.qq.com/mmpaysptrans/pay_bank
是否需要證書
請求需要雙向證書。
調用接口
接口介紹:
用於企業向微信用戶銀行卡付款
目前支持接口API的方式向指定微信用戶的銀行卡付款。
接口調用規則:
◆ 單商戶日限額——單日100w
◆ 單次限額——單次5w
◆ 單商戶給同一銀行卡單日限額——單日5w
注意:重點來了,首先,收款方銀行卡號enc_bank_no
、收款方用戶名enc_true_name
這兩個入參是需要 采用標准RSA算法,公鑰由微信側提供
得到的,所以還需要先拿到這個密鑰,下面是官方文檔地址:
https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=24_7&index=4
以上文檔詳細介紹了如何得到具體的密鑰方式,如果有看不明白的小伙伴,可以直接百度 獲取RSA加密公鑰API
,可以得到很多示例,這里我就不講了。
除入參和企業付款到微信用戶零錢
有所不一致之外,其他方面都差不多,小伙伴們可以參考上面付款到零錢的接口來實現付款到銀行卡接口。
結語
以上為微信余額提現
相關的解釋和源碼,小伙伴們一定要注意看看官方文檔哦,具體的源碼可以看作者的github,里面對每個方法有詳細的注釋。
如果小伙伴有遇到解決不了的問題,可以關注作者微信公眾號,加入討論群中發出疑問,和小伙伴們一起解決哦~
預告:下一篇文章會講發放獎勵的另一種方式 商戶平台-現金紅包
,敬請期待!!!
如果想要提前一覽源碼的小伙伴,可以先看看我的 github,地址如下:
https://github.com/YClimb/wxpay-sdk/blob/master/README.md