玩轉微信2次開發2_微信支付開發_發送請求(微擎版)

微信支付原理javascript

目前只講解關於H5頁面支付相關php

支付流程前端

咱們的訂單系統-->收到了訂單-->會把訂單相關信息發送給微信訂單服務器java


微信訂單服務器收到咱們的請求--開始下訂單此過程叫作訂單預處理--預處理完畢會返回1個預處理ID表示微信這邊已經處理完畢算法


咱們能夠用這個預處理ID和公衆號應用密匙用微信支付js sdk啓動微信支付api


1:微擎的site基類封裝了pay方法,該方法用於向微擎支付中心傳遞參數 而且打開微擎的支付中心
安全

      簡要介紹下該方法所執行的業務,由於目前只針對微信支付,卡卷部分不涉及服務器

      支付中心須要接受如下參數微信

      商品名稱 :titleapp

      模塊訂單系統的商品訂單:ordersn

     商品金額:fee

      優惠:key-value形式

      封裝其餘參數:模塊名字  公衆號ID

      若是支付金額《=0 直接調用site對象的payResult模擬支付成功 

                                     該模擬是模擬前端支付成功回調 需用用from==return判斷

      微擎本身維護了核心支付表,請查看core_paylog

       該表使用tid(模塊的訂單主鍵)和uniacid(公衆號)來關聯具體模塊的訂單系統

       查詢當前公衆號的這個訂單是否被支付過 支付過提示 禁止重複支付

                       該業務只用了Message提示錯誤,可是代碼還會向下執行 沒有使用exit終止 此處做爲BUG

       查詢是否配置了支付參數 即公衆號的setting信息 沒有配置提示出錯

                        一樣沒有執行exit語句 此處爲BUG

      最終導航到支付中心:common/paycenter

2:在支付中心咱們目前只關注微信支付

    微信支付表單被提交到了app\source\mc\cash.ctrl.php


   該PHP的做用:用於把支付信息存入微擎支付歷史記錄表

    大概介紹下業務:這個表的做用很是大 能夠體驗到微擎的設計前端回調

   封裝core_paylog的全部字段信息 插入記錄表 設置訂單狀態爲0 未支付

  構建支付參數信息 該參數是真正準備傳遞給微信訂單服務器的

     

$ps['tid'] = $log['plid'];//獲取支付記錄表主鍵 傳遞給微信的訂單,對應統一支付 api的商戶訂單號
$ps['user'] = $_W['fans']['from_user'];//支付人
$ps['fee'] = $log['card_fee'];//支付金額,對應統一支付API的total_fee/100
$ps['title'] = $params['title'];//對應統一支付API的body即商品描述
封裝加密數據
請求:/payment/wechat/pay.php
3:pay.php的核心業務
首先驗證加密是否匹配 匹配繼續向下執行 一樣進行了1次重複的系統核心訂單表的支付結果檢測,重複了!
開始構建參數和微信訂單服務器通訊
4:通訊函數wechat_build($params, $wechat)
$params->即第2步封裝的參數信息
$wechar-->支付配置信息 裏面配置支付相關信息好比 
partnerId:商戶號 註冊時分配的財付通號
構建通訊數據
$package = array();
$package['appid'] = $wechat['appid'];
$package['mch_id'] = $wechat['mchid'];//微信支付分配的商戶號
$package['nonce_str'] = random(8);//隨機字符串,不長於32位。推薦隨機數生成算法
$package['body'] = $params['title'];//商品或支付單簡要描述
$package['attach'] = $_W['uniacid'];//該字段主要用於商戶攜帶訂單的自定義數據
$package['out_trade_no'] = $params['tid'];//商戶訂單號
$package['total_fee'] = $params['fee'] * 100;//訂單總金額,單位爲分,
$package['spbill_create_ip'] = CLIENT_IP;//終端IP
$package['time_start'] = date('YmdHis', TIMESTAMP);//交易起始時間
$package['time_expire'] = date('YmdHis', TIMESTAMP + 600);//交易結束時間
$package['notify_url'] = $_W['siteroot'] . 'payment/wechat/notify.php';//通知回調url
$package['trade_type'] = 'JSAPI';
$package['openid'] = $_W['fans']['from_user'];//trade_type=JSAPI,此參數必傳,用戶在商戶appid下的惟一標
按照密鑰算法加密請求數據
即吧全部的請求參數按照URL_QUERY格式封裝 好比a=1&b=2
而後再用結果 拼接字符串key=你的微信支付密鑰
結果用md5加密
結果做爲sing的value
$package['sign'] = strtoupper(md5($string1))
最終生成XML文件:$dat = array2xml($package);
和微信訂單系統交互
$response = ihttp_request('https://api.mch.weixin.qq.com/pay/unifiedorder', $dat);
交互成功會返回預處理ID即
$prepayid = $xml->prepay_id;
使用預處理ID準備啓用JS支付SDK
繼續填充其餘參數
如下參數用於啓動JSSDK
$wOpt['appId'] = $wechat['appid'];
$wOpt['timeStamp'] = TIMESTAMP;
$wOpt['nonceStr'] = random(8);
$wOpt['package'] = 'prepay_id='.$prepayid;
$wOpt['signType'] = 'MD5';
ksort($wOpt, SORT_STRING);
foreach($wOpt as $key => $v) {
$string .= "{$key}={$v}&";
}
$string .= "key={$wechat['signkey']}";
$wOpt['paySign'] = strtoupper(md5($string));

5:微擎預留了前端通知接口

<script type="text/javascript">
document.addEventListener('WeixinJSBridgeReady', function onBridgeReady() {
WeixinJSBridge.invoke('getBrandWCPayRequest', {
'appId' : '<?php echo $wOpt['appId'];?>',
'timeStamp': '<?php echo $wOpt['timeStamp'];?>',
'nonceStr' : '<?php echo $wOpt['nonceStr'];?>',
'package' : '<?php echo $wOpt['package'];?>',
'signType' : '<?php echo $wOpt['signType'];?>',
'paySign' : '<?php echo $wOpt['paySign'];?>'
}, function(res) {
if(res.err_msg == 'get_brand_wcpay_request:ok') {
location.search += '&done=1';//支付成功之後再次會訪問pay.php執行done=1代碼塊
} else {
//alert('啓動微信支付失敗, 請檢查你的支付參數. 詳細錯誤爲: ' + res.err_msg);
history.go(-1);
}
});
}, false);
</script>
該JS是用戶在支付成功之後點擊手機界面右上角完成按鈕會觸發get_brand_wcpay_request:ok
看下該鉤子的寫法
$site = WeUtility::createModuleSite($log['module']);
if(!is_error($site)) {
$method = 'payResult';
if (method_exists($site, $method)) {
$ret = array();
$ret['weid'] = $log['uniacid'];//該鉤子獲取的信息都是從支付記錄中查詢到了  不得不說微擎的思路很贊
$ret['uniacid'] = $log['uniacid'];
$ret['result'] = $log['status'] == '1' ? 'success' : 'failed';//該字段會在微信支付成功後觸發回調URL更新
$ret['type'] = $log['type'];
$ret['from'] = 'return';//用於識別是JS返回仍是微信URL通知,因此咱們能夠同該參數的from屬性識別是否支付成功,該方式不安全,若是用戶支付完畢不點擊完成直接關閉頁面 是接受不到該參數的 即from一直爲空 致使系統認定你覺得沒有支付
$ret['tid'] = $log['tid'];
$ret['user'] = $log['openid'];
$ret['fee'] = $log['fee'];
$ret['tag'] = $tag;
$ret['is_usecard'] = $log['is_usecard'];
$ret['card_type'] = $log['card_type'];
$ret['card_fee'] = $log['card_fee'];
$ret['card_id'] = $log['card_id'];
exit($site->$method($ret));
}
相關文章
相關標籤/搜索