摘要:微信商戶向個人退款轉(zhuǎn)賬零錢入賬本屌一向抱著開源精神的態(tài)度,為大家分享文章和技巧,當然分享出來的代碼都是可以直接。。。。
微信商戶向個人退款(轉(zhuǎn)賬)---零錢入賬
本屌一向抱著開源精神的態(tài)度,為大家分享文章和技巧,當然~分享出來的代碼都是可以直接copy in。。。。望大家看完后點贊打賞收藏!謝謝~!如果有寫的不對或者描述不正確的,歡迎大家給我留言指出錯誤,我將立即修改,以免誤導(dǎo)大眾!
此篇文章如題,實現(xiàn)商戶向個人支付,零錢入賬。下面我還是老規(guī)矩,一行代碼一行注釋,請大家注意看,在文章最后會附上完整代碼!~定義函數(shù),首先進行基本信息的定義
/** * 微信企業(yè)付款 * @param [type] $openid 商戶appid下,某用戶的openid * @param [type] $username 收款用戶真實姓名。 * @param [type] $desc 企業(yè)付款操作說明信息。必填。 * @param [type] $money 企業(yè)付款金額,單位為分 * @author appyjj <[email protected]> */ function pay($openid="", $username="", $desc="", $money=0){ $apiUrl = $this->APPURL;//企業(yè)付款接口url $Parameters=array(); $Parameters["amount"] = $money;//企業(yè)付款金額,單位為分 $Parameters["check_name"] = "NO_CHECK";//NO_CHECK:不校驗真實姓名 FORCE_CHECK:強校驗真實姓名(未實名認證的用戶會校驗失敗,無法轉(zhuǎn)賬) OPTION_CHECK:針對已實名認證的用戶才校驗真實姓名(未實名認證用戶不校驗,可以轉(zhuǎn)賬成功) $Parameters["desc"] = $desc;//企業(yè)付款操作說明信息。必填。 $Parameters["mch_appid"] = $this->APPID;//微信分配的公眾賬號ID $Parameters["mchid"] = $this->MCHID;//微信支付分配的商戶號 $Parameters["nonce_str"] = $this->createNoncestr();//隨機字符串,不長于32位 $Parameters["openid"] = $openid;//商戶appid下,某用戶的openid $Parameters["partner_trade_no"] = "saso".time().rand(10000, 99999);//商戶訂單號,需保持唯一性 $Parameters["re_user_name"] = $username;//收款用戶真實姓名。 如果check_name設(shè)置為FORCE_CHECK或OPTION_CHECK,則必填用戶真實姓名 $Parameters["spbill_create_ip"] = $_SERVER["SERVER_ADDR"];//調(diào)用接口的機器Ip地址 $Parameters["sign"] = $this->getSign($Parameters);//簽名 $xml = $this->arrayToXml($Parameters); $res = $this->postXmlSSLCurl($xml,$apiUrl); $return = $this->xmlToArray($res); var_dump($return); //return $res; }
格式化參數(shù),在簽名過程中需要使用到
function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; }
此處代碼很簡單~不做過多注釋。就一個排序、循環(huán)和字符串長度判斷。
生成簽名---這里很重要~擼主也弄了好一會~請大家務(wù)必認真看注釋
function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //簽名步驟一:按字典序排序參數(shù) ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo "【string1】".$String.""; //簽名步驟二:在string后加入KEY $String = $String."&key=1231231231234321abcdxingaaabb235";//此處請?zhí)顚懮虘羝脚_中的 API密鑰 //echo "【string2】".$String.""; //簽名步驟三:MD5加密 $String = md5($String); //echo "【string3】 ".$String.""; //簽名步驟四:所有字符轉(zhuǎn)為大寫 $result_ = strtoupper($String); //echo "【result】 ".$result_.""; return $result_; }
排序的規(guī)則,沒理解的請看這: ◆ 參數(shù)名ASCII碼從小到大排序(字典序); ◆ 如果參數(shù)的值為空不參與簽名; ◆ 參數(shù)名區(qū)分大小寫; ◆ 驗證調(diào)用返回或微信主動通知簽名時,傳送的sign參數(shù)不參與簽名,將生成的簽名與該sign值作校驗。 ◆ 微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段 第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉(zhuǎn)換為大寫,得到sign值signValue。 舉例:
假設(shè)傳送的參數(shù)如下:
appid: wxd930ea5d5a258f4f mch_id: 10000100 device_info: 1000 body: test nonce_str: ibuaiVcKdpRxkhJA 第一步:對參數(shù)按照key=value的格式,并按照參數(shù)名ASCII字典序排序如下: stringA="appid=wxd930ea5d5a258f4f&body=test&device_info=1000&mch_id=10000100&nonce_str=ibuaiVcKdpRxkhJA";
第二步:拼接API密鑰:
stringSignTemp="stringA&key=192006250b4c09247ec02edce69f6a2d" sign=MD5(stringSignTemp).toUpperCase()="9A0A8659F005D6984697E2CA0A9CF3B7"
最終得到最終發(fā)送的數(shù)據(jù):
wxd930ea5d5a258f4f 10000100 1000 test ibuaiVcKdpRxkhJA 9A0A8659F005D6984697E2CA0A9CF3B7
**以上示例摘抄自微信支付官方文檔**
產(chǎn)生隨機字符串,長度不超過32位
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; }
太過簡單,不做敘述!
數(shù)組轉(zhuǎn)xml
function arrayToXml($arr) { $xml = ""; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."".$key.">"; } else $xml.="<".$key.">".$key.">"; } $xml.=" "; return $xml; }
xml轉(zhuǎn)數(shù)組
function xmlToArray($xml) { //將XML轉(zhuǎn)為array $array_data = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true); return $array_data; }
好的,下面是最后一步,請求
使用證書,以POST的方式提交xml到對應(yīng)接口的URL
function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超時時間 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //這里設(shè)置代理,如果有的話 //curl_setopt($ch,CURLOPT_PROXY, "8.8.8.8"); //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); //設(shè)置header curl_setopt($ch,CURLOPT_HEADER,FALSE); //要求結(jié)果為字符串且輸出到屏幕上 curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE); //設(shè)置證書 //使用證書:cert 與 key 分別屬于兩個.pem文件 //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH); //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLKEYTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回結(jié)果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出錯,錯誤碼:$error"."
"; curl_close($ch); return false; } }
程序執(zhí)行的時候往往沒有一次性成功的~下面給大家附上返回的錯誤信息對照查詢表
更詳細的信息~請參考微信官方說明文檔:[傳送門][2]
下面是完整代碼示例
直接copy后,修改一下參數(shù)既可以使用!
pay("這里填寫收款人的openid", "姓名", "這里是描述(如果報utf8的錯誤,請把這里改為數(shù)字,此參數(shù)最好是傳值過來)", 100); //最后這里的100為金額 (單位為分:即100 = 1元) class wxPay{ //=======【證書路徑設(shè)置】===================================== //證書路徑,注意應(yīng)該填寫絕對路徑 protected $SSLCERT_PATH = "cert/apiclient_cert.pem";//請各位大爺自己修改一下路徑 protected $SSLKEY_PATH = "cert/apiclient_key.pem";//請各位大爺自己修改一下路徑 //=======【基本信息設(shè)置】===================================== //微信公眾號身份的唯一標識。審核通過后,在微信發(fā)送的郵件中查看 protected $APPID = "wx123123123123";//填寫您的appid。微信公眾平臺里的 //受理商ID,身份標識 protected $MCHID = "123123123";//商戶id //商戶支付密鑰Key。審核通過后,在微信發(fā)送的郵件中查看 protected $KEY = "192006250b4c09247ec02edce69f6a2d"; //JSAPI接口中獲取openid,審核后在公眾平臺開啟開發(fā)模式后可查看 protected $APPSECRET = "123123123123123123123123123123"; //JSAPI接口地址 protected $APPURL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; /** * 微信企業(yè)付款 * @param [type] $openid 商戶appid下,某用戶的openid * @param [type] $username 收款用戶真實姓名。 * @param [type] $desc 企業(yè)付款操作說明信息。必填。 * @param [type] $money 企業(yè)付款金額,單位為分 * @author appyjj <[email protected]> */ function pay($openid="", $username="", $desc="", $money=0){ $apiUrl = $this->APPURL;//企業(yè)付款接口url $Parameters=array(); $Parameters["amount"] = $money;//企業(yè)付款金額,單位為分 $Parameters["check_name"] = "NO_CHECK";//NO_CHECK:不校驗真實姓名 FORCE_CHECK:強校驗真實姓名(未實名認證的用戶會校驗失敗,無法轉(zhuǎn)賬) OPTION_CHECK:針對已實名認證的用戶才校驗真實姓名(未實名認證用戶不校驗,可以轉(zhuǎn)賬成功) $Parameters["desc"] = $desc;//企業(yè)付款操作說明信息。必填。 $Parameters["mch_appid"] = $this->APPID;//微信分配的公眾賬號ID $Parameters["mchid"] = $this->MCHID;//微信支付分配的商戶號 $Parameters["nonce_str"] = $this->createNoncestr();//隨機字符串,不長于32位 $Parameters["openid"] = $openid;//商戶appid下,某用戶的openid $Parameters["partner_trade_no"] = "saso".time().rand(10000, 99999);//商戶訂單號,需保持唯一性 $Parameters["re_user_name"] = $username;//收款用戶真實姓名。 如果check_name設(shè)置為FORCE_CHECK或OPTION_CHECK,則必填用戶真實姓名 $Parameters["spbill_create_ip"] = $_SERVER["SERVER_ADDR"];//調(diào)用接口的機器Ip地址 $Parameters["sign"] = $this->getSign($Parameters);//簽名 $xml = $this->arrayToXml($Parameters); $res = $this->postXmlSSLCurl($xml,$apiUrl); $return = $this->xmlToArray($res); var_dump($return); //return $res; } /** * 作用:格式化參數(shù),簽名過程需要使用 */ function formatBizQueryParaMap($paraMap, $urlencode) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if($urlencode) { $v = urlencode($v); } //$buff .= strtolower($k) . "=" . $v . "&"; $buff .= $k . "=" . $v . "&"; } $reqPar; if (strlen($buff) > 0) { $reqPar = substr($buff, 0, strlen($buff)-1); } return $reqPar; } /** * 作用:生成簽名 */ function getSign($Obj) { foreach ($Obj as $k => $v) { $Parameters[$k] = $v; } //簽名步驟一:按字典序排序參數(shù) ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo "【string1】".$String.""; //簽名步驟二:在string后加入KEY $String = $String."&key=guoyaojituanfengliaoxing82093235"; //echo "【string2】".$String.""; //簽名步驟三:MD5加密 $String = md5($String); //echo "【string3】 ".$String.""; //簽名步驟四:所有字符轉(zhuǎn)為大寫 $result_ = strtoupper($String); //echo "【result】 ".$result_.""; return $result_; } /** * 作用:產(chǎn)生隨機字符串,不長于32位 */ 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; } /** * 作用:array轉(zhuǎn)xml */ function arrayToXml($arr) { $xml = ""; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."".$key.">"; } else $xml.="<".$key.">".$key.">"; } $xml.=" "; return $xml; } /** * 作用:將xml轉(zhuǎn)為array */ function xmlToArray($xml) { //將XML轉(zhuǎn)為array $array_data = json_decode(json_encode(simplexml_load_string($xml, "SimpleXMLElement", LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:使用證書,以post方式提交xml到對應(yīng)的接口url */ function postXmlSSLCurl($xml,$url,$second=30) { $ch = curl_init(); //超時時間 curl_setopt($ch,CURLOPT_TIMEOUT,$second); //這里設(shè)置代理,如果有的話 //curl_setopt($ch,CURLOPT_PROXY, "8.8.8.8"); //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); //設(shè)置header curl_setopt($ch,CURLOPT_HEADER,FALSE); //要求結(jié)果為字符串且輸出到屏幕上 curl_setopt($ch,CURLOPT_RETURNTRANSFER,TRUE); //設(shè)置證書 //使用證書:cert 與 key 分別屬于兩個.pem文件 //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLCERTTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLCERT, $this->SSLCERT_PATH); //默認格式為PEM,可以注釋 curl_setopt($ch,CURLOPT_SSLKEYTYPE,"PEM"); curl_setopt($ch,CURLOPT_SSLKEY, $this->SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回結(jié)果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出錯,錯誤碼:$error"."
"; curl_close($ch); return false; } } }
ok!此文半抄半寫~總之代碼沒問題的~!分享創(chuàng)造動力,擼主繼續(xù)干活了!
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/22647.html
摘要:本文是淺析微信支付系列文章的第十二篇,主要講解在商戶存在的提現(xiàn)商戶付款到微信用戶零錢或者銀行卡需求。應(yīng)用場景微信支付已上線企業(yè)付款至銀行卡功能。企業(yè)付款到銀行卡發(fā)票與交易手續(xù)費發(fā)票為拆分單獨開具。 本文是【淺析微信支付】系列文章的第十二篇,主要講解在商戶存在的提現(xiàn)、商戶付款到微信用戶零錢或者銀行卡需求。 淺析微信支付系列已經(jīng)更新十二篇了喲~,沒有看過的朋友們可以看一下哦。 淺析微信支...
摘要:對于微信支付訂單以及退款訂單可以根據(jù)微信支付的流水號進行查詢。 payment 項目2.0版本 微信并未提供一個統(tǒng)一的查詢接口。對應(yīng)每種查詢均需要不同的api。為了便于大家在項目中使用,忽略細節(jié)。對以上三種進行了封裝。通過工廠的方式降低調(diào)用成本。 $wxconfig = [ app_id => wxxxx, // 公眾賬號ID mch_id => xxx...
摘要:本文是淺析微信支付系列文章的第三篇,主要會講一下在開發(fā)前的一些注意事項。淺析微信支付系列已經(jīng)更新兩篇了喲,沒有看過的朋友們可以看一下。開通微信支付需要注冊登陸微信商戶平臺,微信支付相關(guān)的信息都需要在這個平臺上進行操作。 本文是【淺析微信支付】系列文章的第三篇,主要會講一下在開發(fā)前的一些注意事項。 淺析微信支付系列已經(jīng)更新兩篇了喲~,沒有看過的朋友們可以看一下。 淺析微信支付:前篇大綱...
閱讀 3500·2021-11-18 10:07
閱讀 1595·2021-11-04 16:08
閱讀 1522·2021-11-02 14:43
閱讀 1098·2021-10-09 09:59
閱讀 852·2021-09-08 10:43
閱讀 1087·2021-09-07 09:59
閱讀 975·2019-12-27 11:56
閱讀 1028·2019-08-30 15:56