一、有言在先
1、俺家公眾號開通微信支付時間是9月22號,所以適用文檔版本號是v3.3.6,當時一不小心從微信客服那裡拿到一個v2.7的文檔,撲騰了1天時間,從一個個水坑裡爬出來又跌入尿坑,把人坑慘了,後面找到相關人士才拿到真相,不過現在公眾平台也可以下載到了~希望大家伙繞開這個坑!
2、最重要一點:此文有軟廣告嫌疑,慎入!先幫朋友們把評論寫在這裡~~~
二、需要到這些地方去扒參數
1、登錄微信公眾號管理後台mp.weixin.qq.com,在左側菜單欄找到開發者中心,點開如下圖就能看到AppID和AppSecret:
2、在微信支付通過之後,財付通會發3封郵件到申請人郵箱中,俺家之前開通過財付通的賬戶用於主站支付接口, 不過這次又新發了一個財付通賬號,不過讓人驚喜的是這次微信支付免了保證金,不知為啥?
點開weixinpay那封郵件就可以看到這些賬號信息,把附件中pem格式的文件下載保存到web服務器上,請記下文件絕對路徑,在下面代碼中需要用到:
3、登錄微信商戶平台(mch.weixin.qq.com),去設置商戶支付密鑰Key:
4、登錄微信公眾號管理後台mp.weixin.qq.com,設置支付配置,支付測試,支付白名單
三、找到參數來配置該個類class WxPayConf
class WxPayConf
{
//=======【基本信息設置】=====================================
//微信公眾號身份的唯一標識。審核通過後,在微信發送的郵件中查看
const APPID = "填上二、1中看到的AppID";
//受理商ID,身份標識
const MCHID = "填上二、2中看到的MCHID";
//商戶支付密鑰Key。審核通過後,在微信發送的郵件中查看(如果沒有,可以登錄微信商戶平台去設置)
const KEY = "填上二、3中設置的密鑰";
//JSAPI接口中獲取openid,審核後在公眾平台開啟開發模式後可查看
const APPSECRET = "填上二、1中看到的AppSecret";
//=======【JSAPI路徑設置】===================================
//獲取access_token過程中的跳轉uri,通過跳轉將code傳入jsapi支付頁面
const JS_API_CALL_URL = "http://www.xxx.com/wxpay/js_api_call.php";
//=======【證書路徑設置】=====================================
//證書路徑,注意應該填寫絕對路徑
const SSLCERT_PATH = "填上二、2中下載的pem文件放在服務器上的路徑";
const SSLKEY_PATH = "填上二、2中下載的pem文件放在服務器上的路徑";
//=======【異步通知url設置】===================================
//異步通知url,商戶根據實際開發過程設定
const NOTIFY_URL = http://www.xxxx.com/wxpay/notify_url.php;
}
四、JSAPI支付
微信JS API只能在微信內置浏覽器中使用,其他浏覽器調用無效。
下面代碼是微信官方提供的JS API支付demo
include_once("WxPayHelper/WxPayHelper.php");
//使用jsapi接口 $jsApi = new JsApi(); //=========步驟1:網頁授權獲取用戶openid============ //通過code獲得openid if(!isWeixin()){ echo "請在微信內掃描二維碼"; exit; } if (!isset($_GET['code'])) { //觸發微信返回code碼 $url = $jsApi->createOauthUrlForCode(WxPayConf::JS_API_CALL_URL."); Header("Location: $url"); }else { //獲取code碼,以獲取openid $code = $_GET['code']; $jsApi->setCode($code); $openid = $jsApi->getOpenId(); } if(empty($order)){ echo "數據錯誤!"; exit; } } //=========步驟2:使用統一支付接口,獲取prepay_id============ //使用統一支付接口 $unifiedOrder = new UnifiedOrder(); //設置統一支付接口參數 //設置必填參數 //appid已填,商戶無需重復填寫 //mch_id已填,商戶無需重復填寫 //noncestr已填,商戶無需重復填寫 //spbill_create_ip已填,商戶無需重復填寫 //sign已填,商戶無需重復填寫 $unifiedOrder->setParameter("openid","$openid");//商品描述 $unifiedOrder->setParameter("body","test");//商品描述 //自定義訂單號,此處僅作舉例 $timeStamp = time(); $out_trade_no = timeStamp; $total_fee = 1; $unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商戶訂單號 $unifiedOrder->setParameter("total_fee",$total_fee);//總金額 $unifiedOrder->setParameter("notify_url",WxPayConf::NOTIFY_URL);//通知地址 $unifiedOrder->setParameter("trade_type","JSAPI");//交易類型 //非必填參數,商戶可根據實際情況選填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商戶號 //$unifiedOrder->setParameter("device_info","XXXX");//設備號 //$unifiedOrder->setParameter("attach","XXXX");//附加數據 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始時間 //$unifiedOrder->setParameter("time_expire","XXXX");//交易結束時間 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品標記 //$unifiedOrder->setParameter("openid","XXXX");//用戶標識 //$unifiedOrder->setParameter("product_id","XXXX");//商品ID $prepay_id = $unifiedOrder->getPrepayId(); //=========步驟3:使用jsapi調起支付============ $jsApi->setPrepayId($prepay_id); $jsApiParameters = $jsApi->getParameters(); function isWeixin(){ $agent = strtolower($_SERVER['HTTP_USER_AGENT']); $is_weixin = strpos($agent, 'micromessenger') ? true : false ; if($is_weixin){ return true; }else{ return false; } } ?> <html> <head> <meta http-equiv="content-type" content="text/html;charset=utf-8" /> <title>微信安全支付</title> <script type="text/javascript"> //調用微信JS api 支付 function jsApiCall() { WeixinJSBridge.invoke( 'getBrandWCPayRequest', <?php echo $jsApiParameters; ?>, function(res){ WeixinJSBridge.log(res.err_msg); //alert(res.err_code+res.err_desc+res.err_msg); } ); } function callpay() { if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } }else{ jsApiCall(); } } </script> </head> <body onload=""> </br> </br> </br> </br> <div align="center"> <button type="button" onclick="callpay()">貢獻一下</button> </div> </body> </html>
將其中的微信支付參數修改成自己申請得到的,然後將網頁上傳到微信支付目錄下,使用公眾號給測試賬號回復該網頁地址。用戶就可以實現一次JS API支付。
五、NATIVE支付
采用了官方提供的demo,native支付模式2完成
下面代碼是微信官方提供的natice支付demo
include_once("WxPayHelper/WxPayHelper.php");
//使用統一支付接口 $unifiedOrder = new UnifiedOrder(); //設置統一支付接口參數 //設置必填參數 //appid已填,商戶無需重復填寫 //mch_id已填,商戶無需重復填寫 //noncestr已填,商戶無需重復填寫 //spbill_create_ip已填,商戶無需重復填寫 //sign已填,商戶無需重復填寫 $unifiedOrder->setParameter("body","貢獻一分錢");//商品描述 //自定義訂單號,此處僅作舉例 $timeStamp = time(); $out_trade_no = WxPayConf::APPID."$timeStamp"; $unifiedOrder->setParameter("out_trade_no","$out_trade_no");//商戶訂單號 $unifiedOrder->setParameter("total_fee","1");//總金額 $unifiedOrder->setParameter("notify_url",WxPayConf::NOTIFY_URL);//通知地址 $unifiedOrder->setParameter("trade_type","NATIVE");//交易類型 //非必填參數,商戶可根據實際情況選填 //$unifiedOrder->setParameter("sub_mch_id","XXXX");//子商戶號 //$unifiedOrder->setParameter("device_info","XXXX");//設備號 //$unifiedOrder->setParameter("attach","XXXX");//附加數據 //$unifiedOrder->setParameter("time_start","XXXX");//交易起始時間 //$unifiedOrder->setParameter("time_expire","XXXX");//交易結束時間 //$unifiedOrder->setParameter("goods_tag","XXXX");//商品標記 //$unifiedOrder->setParameter("openid","XXXX");//用戶標識 //$unifiedOrder->setParameter("product_id","XXXX");//商品ID //獲取統一支付接口結果 $unifiedOrderResult = $unifiedOrder->getResult(); //商戶根據實際情況設置相應的處理流程 if ($unifiedOrderResult["return_code"] == "FAIL") { //商戶自行增加處理流程 echo "通信出錯:".$unifiedOrderResult['return_msg']."<br>"; } elseif($unifiedOrderResult["result_code"] == "FAIL") { //商戶自行增加處理流程 echo "錯誤代碼:".$unifiedOrderResult['err_code']."<br>"; echo "錯誤代碼描述:".$unifiedOrderResult['err_code_des']."<br>"; } elseif($unifiedOrderResult["code_url"] != NULL) { //從統一支付接口獲取到code_url $code_url = $unifiedOrderResult["code_url"]; //商戶自行增加處理流程 //...... } ?> <!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <title>微信安全支付</title> </head> <body> <div align="center" id="qrcode"> </div> <div align="center"> <p>訂單號:<?php echo $out_trade_no; ?></p> </div> <div align="center"> <form action="./order_query.php" method="post"> <input name="out_trade_no" type='hidden' value="<?php echo $out_trade_no; ?>"> <button type="submit" >查詢訂單狀態</button> </form> </div> <br> <div align="center"> <form action="./refund.php" method="post"> <input name="out_trade_no" type='hidden' value="<?php echo $out_trade_no; ?>"> <input name="refund_fee" type='hidden' value="1"> <button type="submit" >申請退款</button> </form> </div> <br> <div align="center"> <a href="../index.php">返回首頁</a> </div> </body> <script src="./qrcode.js"></script> <script> if(<?php echo $unifiedOrderResult["code_url"] != NULL; ?>) { var url = "<?php echo $code_url;?>"; //參數1表示圖像大小,取值范圍1-10;參數2表示質量,取值范圍'L','M','Q','H' var qr = qrcode(10, 'M'); qr.addData(url); qr.make(); var wording=document.createElement('p'); wording.innerHTML = "掃我,掃我"; var code=document.createElement('DIV'); code.innerHTML = qr.createImgTag(); var element=document.getElementById("qrcode"); element.appendChild(wording); element.appendChild(code); } </script> </html>
六、調用WxPayHelper.php存在的問題
在做開發時,官方demo 提供的wxPayHeler.php 存在部分問題,導致結果sign 錯誤。
使用jpapi 支付時候需要修改3
大家可以根據自己下載到的版本看是否需要修改
這裡貼出修改後的代碼
<?php /** * 微信支付幫助庫 * ==================================================== * 接口分三種類型: * 【請求型接口】--Wxpay_client_ * 統一支付接口類--UnifiedOrder * 訂單查詢接口--OrderQuery * 退款申請接口--Refund * 退款查詢接口--RefundQuery * 對賬單接口--DownloadBill * 短鏈接轉換接口--ShortUrl * 【響應型接口】--Wxpay_server_ * 通用通知接口--Notify * Native支付——請求商家獲取商品信息接口--NativeCall * 【其他】 * 靜態鏈接二維碼--NativeLink * JSAPI支付--JsApi * ===================================================== * 【CommonUtil】常用工具: * trimString(),設置參數時需要用到的字符處理函數 * createNoncestr(),產生隨機字符串,不長於32位 * formatBizQueryParaMap(),格式化參數,簽名過程需要用到 * getSign(),生成簽名 * arrayToXml(),array轉xml * xmlToArray(),xml轉 array * postXmlCurl(),以post方式提交xml到對應的接口url * postXmlSSLCurl(),使用證書,以post方式提交xml到對應的接口url */ include_once("SDKRuntimeException.php"); include_once("WxPay.config.php"); /** * 所有接口的基類 */ class Common_util_ { function __construct($argument) { } function trimString($value) { $ret = null; if (null != $value) { $ret = $value; if (strlen($ret) == 0) { $ret = null; } } return $ret; } /** * 作用:產生隨機字符串,不長於32位 */ public 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 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; } /** * 作用:生成簽名 */ public function getSign($Obj) { foreach ($Obj as $k => $v) { // $Parameters[strtolower($k)] = $v; $Parameters[$k] = $v; } //簽名步驟一:按字典序排序參數 ksort($Parameters); $String = $this->formatBizQueryParaMap($Parameters, false); //echo "【string】 =".$String."</br>"; //簽名步驟二:在string後加入KEY $String = $String."&key=".WxPayConf::KEY; //echo "【string】 =".$String."</br>"; //簽名步驟三:MD5加密 $result_ = strtoupper(md5($String)); return $result_; } /** * 作用:array轉xml */ function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key=>$val) { if (is_numeric($val)) { $xml.="<".$key.">".$val."</".$key.">"; } else $xml.="<".$key."><![CDATA[".$val."]]></".$key.">"; } $xml.="</xml>"; return $xml; } /** * 作用:將xml轉為array */ public function xmlToArray($xml) { //將XML轉為array $array_data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true); return $array_data; } /** * 作用:以post方式提交xml到對應的接口url */ public function postXmlCurl($xml,$url) { //初始化curl $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); //設置header curl_setopt($ch, CURLOPT_HEADER, 0); //要求結果為字符串且輸出到屏幕上 curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //post提交方式 curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); //運行curl $data = curl_exec($ch); curl_close($ch); //返回結果 if($data) { curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出錯,錯誤碼:$error"."<br>"; curl_close($ch); return false; } } /** * 作用:使用證書,以post方式提交xml到對應的接口url */ function postXmlSSLCurl($xml,$url) { $ch = curl_init(); curl_setopt($ch,CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch,CURLOPT_HEADER, 0); curl_setopt($ch,CURLOPT_URL,$url); //設置證書 curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,true); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST,2); curl_setopt($ch,CURLOPT_SSLCERTTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLCERT, WxPayConf::SSLCERT_PATH); curl_setopt($ch,CURLOPT_SSLKEYTYPE,'PEM'); curl_setopt($ch,CURLOPT_SSLKEY, WxPayConf::SSLKEY_PATH); //post提交方式 curl_setopt($ch,CURLOPT_POST, true); curl_setopt($ch,CURLOPT_POSTFIELDS,$xml); $data = curl_exec($ch); //返回結果 if($data){ curl_close($ch); return $data; } else { $error = curl_errno($ch); echo "curl出錯,錯誤碼:$error"."<br>"; curl_close($ch); return false; } } /** * 作用:打印數組 */ function printErr($wording='',$err='') { print_r('<pre>'); echo $wording."</br>"; var_dump($err); print_r('</pre>'); } } /** * 請求型接口的基類 */ class Wxpay_client_ extends Common_util_ { var $parameters;//請求參數,類型為關聯數組 public $response;//微信返回的響應 public $result;//返回參數,類型為關聯數組 var $url;//接口鏈接 /** * 作用:設置請求參數 */ function setParameter($parameter, $parameterValue) { $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); } /** * 作用:設置標配的請求參數,生成簽名,生成接口參數xml */ function createXml() { $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); } /** * 作用:post請求xml */ function postXml() { $xml = $this->createXml(); $this->response = $this->postXmlCurl($xml,$this->url); return $this->response; } /** * 作用:使用證書post請求xml */ function postXmlSSL() { $xml = $this->createXml(); $this->response = $this->postXmlSSLCurl($xml,$this->url); return $this->response; } /** * 作用:獲取結果,默認不使用證書 */ function getResult() { $this->postXml(); $this->result = $this->xmlToArray($this->response); return $this->result; } } /** * 統一支付接口類 */ class UnifiedOrder extends Wxpay_client_ { function __construct($argument) { //設置接口鏈接 $this->url = "https://api.mch.weixin.qq.com/pay/unifiedorder"; } /** * 生成接口參數xml */ function createXml() { try { //檢測必填參數 if($this->parameters["out_trade_no"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數out_trade_no!"."<br>"); }elseif($this->parameters["body"] == null){ throw new SDKRuntimeException("缺少統一支付接口必填參數body!"."<br>"); }elseif ($this->parameters["total_fee"] == null ) { throw new SDKRuntimeException("缺少統一支付接口必填參數total_fee!"."<br>"); }elseif ($this->parameters["notify_url"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數notify_url!"."<br>"); }elseif ($this->parameters["trade_type"] == null) { throw new SDKRuntimeException("缺少統一支付接口必填參數trade_type!"."<br>"); }elseif ($this->parameters["trade_type"] == "JSAPI" && $this->parameters["openid"] == NULL){ throw new SDKRuntimeException("統一支付接口中,缺少必填參數openid!trade_type為JSAPI時,openid為必填參數!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//終端ip $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 獲取prepay_id */ function getPrepayId() { $this->postXml(); $this->result = $this->xmlToArray($this->response); $prepay_id = $this->result['prepay_id']; //$prepay_id = $this->result["prepay_id"]; return $prepay_id; } } /** * 訂單查詢接口 */ class OrderQuery extends Wxpay_client_ { function __construct($argument) { //設置接口鏈接 $this->url = "https://api.mch.weixin.qq.com/pay/orderquery"; } /** * 生成接口參數xml */ function createXml() { try { //檢測必填參數 if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) { throw new SDKRuntimeException("訂單查詢接口中,out_trade_no、transaction_id至少填一個!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } } /** * 退款申請接口 */ class Refund extends Wxpay_client_ { function __construct($argument) { $this->url = "https://api.mch.weixin.qq.com/secapi/pay/refund"; } /** * 生成接口參數xml */ function createXml() { try { //檢測必填參數 if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null) { throw new SDKRuntimeException("退款申請接口中,out_trade_no、transaction_id至少填一個!"."<br>"); }elseif($this->parameters["out_refund_no"] == null){ throw new SDKRuntimeException("退款申請接口中,缺少必填參數out_refund_no!"."<br>"); }elseif($this->parameters["total_fee"] == null){ throw new SDKRuntimeException("退款申請接口中,缺少必填參數total_fee!"."<br>"); }elseif($this->parameters["refund_fee"] == null){ throw new SDKRuntimeException("退款申請接口中,缺少必填參數refund_fee!"."<br>"); }elseif($this->parameters["op_user_id"] == null){ throw new SDKRuntimeException("退款申請接口中,缺少必填參數op_user_id!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 作用:獲取結果,使用證書通信 */ function getResult() { $this->postXmlSSL(); $this->result = $this->xmlToArray($this->response); return $this->result; } } /** * 退款查詢接口 */ class RefundQuery extends Wxpay_client_ { function __construct($argument) { $this->url = "https://api.mch.weixin.qq.com/pay/refundquery"; } /** * 生成接口參數xml */ function createXml() { try { if($this->parameters["out_refund_no"] == null && $this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null && $this->parameters["refund_id "] == null) { throw new SDKRuntimeException("退款查詢接口中,out_refund_no、out_trade_no、transaction_id、refund_id四個參數必填一個!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 作用:獲取結果,使用證書通信 */ function getResult() { $this->postXmlSSL(); $this->result = $this->xmlToArray($this->response); return $this->result; } } /** * 對賬單接口 */ class DownloadBill extends Wxpay_client_ { function __construct($argument) { $this->url = "https://api.mch.weixin.qq.com/pay/downloadbill"; } /** * 生成接口參數xml */ function createXml() { try { if($this->parameters["bill_date"] == null ) { throw new SDKRuntimeException("對賬單接口中,缺少必填參數bill_date!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 作用:獲取結果,默認不使用證書 */ function getResult() { $this->postXml(); $this->result = $this->xmlToArray($this->result_xml); return $this->result; } } /** * 短鏈接轉換接口 */ class ShortUrl extends Wxpay_client_ { function __construct($argument) { $this->url = "https://api.mch.weixin.qq.com/tools/shorturl"; } /** * 生成接口參數xml */ function createXml() { try { if($this->parameters["long_url"] == null ) { throw new SDKRuntimeException("短鏈接轉換接口中,缺少必填參數long_url!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 獲取prepay_id */ function getShortUrl() { $this->postXml(); $prepay_id = $this->result["short_url"]; return $prepay_id; } } /** * 沖正接口 */ class Reverse extends Wxpay_client_ { function __construct($argument) { $this->url = "https://api.mch.weixin.qq.com/secapi/pay/reverse"; } /** * 生成接口參數xml */ function createXml() { try { if($this->parameters["out_trade_no"] == null && $this->parameters["transaction_id"] == null){ throw new SDKRuntimeException("沖正接口中,transaction_id、out_trade_no至少填一個!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 作用:獲取結果,使用證書通信 */ function getResult() { $this->postXmlSSL(); $this->result = $this->xmlToArray($this->response); return $this->result; } } /** * 被掃支付接口 */ class MicropayCall extends Wxpay_client_ { function __construct($argument) { //設置接口鏈接 $this->url = "https://api.mch.weixin.qq.com/pay/micropay"; } /** * 生成接口參數xml */ function createXml() { try { if($this->parameters["out_trade_no"] == null) { throw new SDKRuntimeException("缺少被掃支付接口必填參數out_trade_no!"."<br>"); }elseif ($this->parameters["body"] == null) { throw new SDKRuntimeException("缺少被掃支付接口必填參數body!"."<br>"); }elseif ($this->parameters["total_fee"] == null) { throw new SDKRuntimeException("缺少被掃支付接口必填參數total_fee!"."<br>"); }elseif ($this->parameters["auth_code"] == null) { throw new SDKRuntimeException("缺少被掃支付接口必填參數auth_code!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->parameters["spbill_create_ip"] = $_SERVER['REMOTE_ADDR'];//終端ip $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 return $this->arrayToXml($this->parameters); }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } } /** * 響應型接口基類 */ class Wxpay_server_ extends Common_util_ { public $data;//接收到的數據,類型為關聯數組 var $returnParameters;//返回參數,類型為關聯數組 /** * 將微信的請求xml轉換成關聯數組,以方便數據處理 */ function saveData($xml) { $this->data = $this->xmlToArray($xml); } function checkSign() { $tmpData = $this->data; unset($tmpData['sign']); $sign = $this->getSign($tmpData);//本地簽名 if ($this->data['sign'] == $sign) { return TRUE; } return FALSE; } /** * 獲取微信的請求數據 */ function getData() { return $this->data; } /** * 設置返回微信的xml數據 */ function setReturnParameter($parameter, $parameterValue) { $this->returnParameters[$this->trimString($parameter)] = $this->trimString($parameterValue); } /** * 生成接口參數xml */ function createXml() { return $this->arrayToXml($this->returnParameters); } /** * 將xml數據返回微信 */ function returnXml() { $returnXml = $this->createXml(); return $returnXml; } } /** * 通用通知接口 */ class Notify extends Wxpay_server_ { } /** * 請求商家獲取商品信息接口 */ class NativeCall extends Wxpay_server_ { /** * 生成接口參數xml */ function createXml() { if($this->returnParameters["return_code"] == "SUCCESS"){ $this->returnParameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->returnParameters["mch_id"] = WxPayConf::MCHID;//商戶號 $this->returnParameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->returnParameters["sign"] = $this->getSign($this->returnParameters);//簽名 } return $this->arrayToXml($this->returnParameters); } /** * 獲取product_id */ function getProductId() { $product_id = $this->data["product_id"]; return $product_id; } } /** * 靜態鏈接二維碼 */ class NativeLink extends Common_util_ { var $parameters;//靜態鏈接參數 var $url;//靜態鏈接 function __construct($argument) { } /** * 設置參數 */ function setParameter($parameter, $parameterValue) { $this->parameters[$this->trimString($parameter)] = $this->trimString($parameterValue); } /** * 生成Native支付鏈接二維碼 */ function createLink() { try { if($this->parameters["product_id"] == null) { throw new SDKRuntimeException("缺少Native支付二維碼鏈接必填參數product_id!"."<br>"); } $this->parameters["appid"] = WxPayConf::APPID;//公眾賬號ID $this->parameters["mch_id"] = WxPayConf::MCHID;//商戶號 $time_stamp = time(); $this->parameters["time_stamp"] = "$time_stamp";//時間戳 $this->parameters["nonce_str"] = $this->createNoncestr();//隨機字符串 $this->parameters["sign"] = $this->getSign($this->parameters);//簽名 $bizString = $this->formatBizQueryParaMap($this->parameters, false); $this->url = "weixin://wxpay/bizpayurl?".$bizString; }catch (SDKRuntimeException $e) { die($e->errorMessage()); } } /** * 返回鏈接 */ function getUrl() { $this->createLink(); return $this->url; } } /** * JSAPI支付——H5網頁端調起支付接口 */ class JsApi extends Common_util_ { var $code;//code碼,用以獲取openid var $openid;//用戶的openid var $parameters;//jsapi參數,格式為json var $prepay_id;//使用統一支付接口得到的預支付id /** * 作用:生成可以獲得code的url */ function createOauthUrlForCode($redirectUrl) { $urlObj["appid"] = WxPayConf::APPID; $urlObj["redirect_uri"] = "$redirectUrl"; $urlObj["response_type"] = "code"; $urlObj["scope"] = "snsapi_base"; $urlObj["state"] = "SATE"."#wechat_redirect"; $bizString = $this->formatBizQueryParaMap($urlObj, false); return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString; } /** * 作用:生成可以獲得openid的url */ function createOauthUrlForOpenid() { $urlObj["appid"] = WxPayConf::APPID; $urlObj["secret"] = WxPayConf::APPSECRET; $urlObj["code"] = $this->code; $urlObj["grant_type"] = "authorization_code"; $bizString = $this->formatBizQueryParaMap($urlObj, false); return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString; } /** * 作用:通過curl向微信提交code,以獲取openid */ function getOpenid() { $url = $this->createOauthUrlForOpenid(); //初始化curl $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //運行curl,結果以jason形式返回 $res = curl_exec($ch); curl_close($ch); //取出openid $data = json_decode($res,true); $this->openid = $data['openid']; return $this->openid; } /** * 作用:設置prepay_id */ function setPrepayId($prepayId) { $this->prepay_id = $prepayId; } /** * 作用:設置code */ function setCode($code_) { $this->code = $code_; } /** * 作用:設置jsapi的參數 */ public function getParameters() { $jsApiObj["appId"] = WxPayConf::APPID; $timeStamp = time(); $jsApiObj["timeStamp"] = "$timeStamp"; $jsApiObj["nonceStr"] = $this->createNoncestr(); $jsApiObj["package"] = "prepay_id=$this->prepay_id"; $jsApiObj["signType"] = "MD5"; $jsApiObj["paySign"] = $this->getSign($jsApiObj); $this->parameters = json_encode($jsApiObj); return $this->parameters; } } ?>
恭喜您~有超一流的忍耐力看完這篇臭(湊)文-_-,如果覺得對你有那麼一點點幫助,點贊就不要了, 省下那點力氣請猛戳俺家小店(www.wsyu.com),為您的女盆友(我一直堅信程序猿有女盆友!!!)備上一款精美項鏈、手鏈或腳鏈,她一高興,您晚上就不用撸管了!
或者關注下俺家的公眾號:
近期正在趕工微信小店的接口,歡迎加群:204689062 討論~
我不太喜歡趕時髦,當大家早就在使用微信傳遞信息的時候,我還是恪守習慣的交流方式,電話,短信和電子郵件。這並非是我不接受新生事物,因為我知道,在信息傳遞的過程中,中間環節越多,信息的安全性就越差,飛信不如短信,短信不如電話,手機不如座機,座機不如見面,在咖啡館聊不如在家裡聊。當政府嚴格要求網絡實名制的時候,微信,把你的手機號碼、所在位置、你的親朋好友。。。一網打盡的時候,任何“實名制”都相形見绌了。在用飛信的時候就發生過這樣的事情:飛信系統把俺的前女友的號碼推介給俺媳婦:你們有一個共同的好友。 在朋友的忽悠下,再看看周邊的哥們都在用微信聯系打球等事宜,你不加微信,人家都不帶你玩了。於是,也換了手機,上了微信。卻不料用了微信後第一次和朋友約會打球時,就收到了微信要收費的傳言。在到網上去一看,為了微信收費的問題,已經打成一鍋粥了:微信的制造商騰訊急忙出來辟謠;受到微信正面直接沖擊的中國移動的董事長也赤膊上陣大談“微信等OTT服務確實造成了運營商的網絡負擔加重”等論調;政府主管部門、工信部部長苗圩公開表示,工信部目前正協調運營商微信收費一事,“收流量以外的費用也是合情合理的”;與政府保持一致的官媒也紛紛找出了國外收費的案例加以渲染;但是,已經習慣了免費的網民們根本不接受除了數據流量費以外的其他收費,一時間,板磚一致飛向“收費”。 專家們,不論是挺收費的還是反收費,都在用很多諸如OTT(增值業務)、信令信道之類的專業術語,試圖向大家說明微信的是與非。但這些東西除了業內人士能夠聽明白,就連我這曾經在北郵混過8年的人都聽得雲山霧罩。我就曾為此問過IT專家:你們老說微信占用了信令信道,你們要是認為信令信道擁堵了,那就再從其他7條信道裡面拿出一個信道來做信令呗。被專家們嘲諷:別老外了,再拿一條信道做信令?那語音豈不是受影響?!語音才是移動運營商的根本!可見,對於數據業務,移動運營商是愛恨交加。數據多了,必然沖擊傳統的語音通話,而他們又不願意放棄傳統的話務量,現在還要死守語音這個陣地,而置數據業務發展大趨勢於不顧。照此下去,移動運營商或可成為下一個柯達。 其實,對於微信的收費而言,不存在這麼多的專業術語,也不需要找到什麼理論根據和外國的經驗。收費與否,收費的多寡,都取決於提供商品服務的買賣雙方的博弈和達成的共識。 就微信而言,騰訊是服務提供商,我們都是用戶,移動運營商則是傳遞這個服務的中介。所以,在這一個服務鏈中,可以有3個收費的服務項目:收費1:騰訊向用戶收(買賣關系);收費2:騰訊付給運營商(賣方中介),收費3:運營商收用戶(買方中介)。在這3個或有的收費項目中,與用戶直接有關的,是“收費1”和“收費3”這兩個項目,“收費3”是已經在收的,不論是總量包月,還是計算流量,用戶都已經向運營商支付了費用;而“收費1”,騰訊已經再三表態:目前不會收費。那麼,作為用戶我們還有什麼可擔心的?還需要扔什麼板磚呢? 所以,需要討論的只有“收費2”——運營商向騰訊收取接入費用。從道理上來說,這個收費是可以的,也是應該的。但是,這必須在一個公平的條件下進行,不能有歧視。運營商不能只對騰訊的微信收費,而要對運營商接入的所有的OTT產品都有一個明確的收費標准。即,對騰訊微信收費了,也要對skype、飛聊、翼信等采取同樣的收費標准。當然,對於運營商的收費,騰訊也有權選擇不交費,如,對某一家運營商的收費說不,從而不使用該運營商提供的網絡。這樣一來,由於騰訊不使用該運營商的網絡,對騰訊來講,可能會導致使用該運營商網絡的一些微信用戶的流失,同時,該運營商的數據流量的業務會受到影響,而一些手機用......余下全文>>