1、使用場景以及說明php
使用場景:商戶已有H5商城網站,用戶經過消息或掃描二維碼在微信內打開網頁時,能夠調用微信支付完成下單購買的流程。html
說明:1.用戶打開圖文消息或者掃描二維碼,在微信內置瀏覽器打開網頁進行的支付。前端
2.商戶網頁前端經過使用微信提供的 JSAPI,調用微信支付模塊。這種方式,適合須要在商戶網頁進行選購下單的購買流程。json
2、準備工做api
公共號支付須要提早在微信公共平臺進行業務配置,包括設置支付受權目錄、設置JS接口安全域名以及設置受權回調頁面域名。數組
1.進行微信公衆支付以前,咱們須要申請個公衆號,以及申請微信支付的功能。瀏覽器
2.支付受權目錄:安全
位置:微信支付——>開發配置——>公共號支付服務器
1) 全部使用公衆號支付方式發起支付請求的連接地址,都必須在支付受權目錄之下;微信
2) 正式支付受權目錄最多設置3個,測試受權目錄最多設置1個,且域名必須經過ICP備案;
3) 頭部要包含http或https,須細化到二級或三級目錄,以左斜槓「/」結尾。
業務中發起支付的頁面地址必須在受權目錄下,不然調用下單接口時會提示「當前頁面的URL未註冊」。
這裏再囉嗦地補充兩點:
1)不使用框架的狀況下,好比將官方sdk下載下來,改爲demo放在根目錄下,demo/example/jaspi.php,受權目錄可參考 http://www. ×××.com/demo/example/
2 )使用框架的狀況下,好比ThinkPHP, 項目名叫test ,目錄結構以下,test/Application/Home/controller/WxpayController.class.php,受權目錄可參考 http://www. ×××.com/index.php/Home/Wxpay/
3.JS接口安全域名:
位置:微信支付——>公共號設置——>功能設置——>JS接口安全域名
說明:設置JS接口安全域名後,公衆號開發者可在該域名下調用微信開放的JS接口。
注意事項:
1) 可填寫三個域名,要求是一級或一級以上域名(例:qq.com,或者 www.qq.com ),需使用字母、數字及「-」的組合,不支持IP地址及端口號;
2) 填寫的域名須經過ICP備案的驗證;
3)一個天然月內最多可修改並保存三次。
4.受權回調頁面域名:
位置:微信支付——>接口權限——>網頁受權獲取用戶基本信息
用戶在網頁受權頁贊成受權給公衆號後,微信會將受權數據傳給一個回調頁面,回調頁面需在此域名下,以確保安全可靠。
注意事項:
1) 回調頁面域名需使用字母、數字及「-」的組合,不支持IP地址及端口號。填寫的域名需與實際回調URL中的域名相同;
2) 填寫的域名須經過ICP備案的驗證。
獲取用戶受權時redirect_uri對應的URL必須在此域名下,不然回調的地址會沒法打開。
3、開發步驟
說明:整個微信公衆號支付的流程以下:
【1】用戶點擊公衆號內微信商城打開H5的支付頁面
【2】H5頁面經過JS調用微信支付接口
【3】微信服務器經過判斷輸入的JSON數據,返回給客戶端相應的成功或失敗信息
官方demo結構以下:
1.JSAPI支付——H5網頁端調起支付接口
1)用戶贊成受權,獲取code
請求連接:https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#we-chat_redirect
2)若是有code,直接就經過code能獲取用戶openid
若是沒有code,經過createOauthUrlForCode方法,傳入必要參數,獲取code
3)若是用戶贊成受權,頁面將跳轉至 redirect_uri/?code=CODE&state=STATE。
若用戶禁止受權,則重定向後不會帶上code參數,僅會帶上state參數
redirect_uri?state=STATE
4)code說明以及scope的兩種方式說明
【1】code做爲換取access_token的票據,每次用戶受權帶上的code將不同,code只能使用一次,5分鐘未被使用自動過時。
這裏獲取到code 和 state(訂單號) 後, 對訂單進行驗證,用戶餘額也進行驗證,若是條件都知足則才能進行下面的流程。
【2】scope的兩種方式說明:
微信提供了兩種受權方式:snsapi_base和snsapi_userinfo。
snsapi_base:不彈出受權頁面,直接跳轉,只能獲取用戶openid;
snsapi_userinfo:彈出受權頁面,可經過openid拿到暱稱、性別、所在地。而且,即便在未關注的狀況下,只要用戶受權,也能獲取其信息。
想要獲取code,須要構造以下地址:
2. 經過code換取網頁受權access_token (這裏也獲取到了openid)
1)請求連接:https://api.weixin.qq.com/sns/oauth2/access_token
?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
2)獲取openid:openid是微信支付jsapi支付接口必須的參數
【1】若是網頁受權的做用域爲snsapi_base(靜默受權),則本步驟中獲取到網頁受權access_token的同時,也獲取到了openid,snsapi_base式的網頁受權流程即到此爲止。
【2】若是網頁受權做用域爲snsapi_userinfo,則此時開發者能夠經過access_token和openid拉取用戶信息了。
3)getOpenid方法中調用createOauthUrlForOpenid方法獲取openid
3. 調用統一支付接口獲取預付款id
官方文檔說明:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
1) 設置必傳參數,按照簽名參數產生簽名, 此時參與簽名字段有 : appid, mch_id , nonce_str, openid, body , out_trade_no, total_fee, notify_url , trade_type
2) 將必傳參數轉成xml,createXml方法。
3) 使用xml,請求統一支付接口 https://api.mch.weixin.qq.com/pay/unifiedorder
4) 獲得xml格式的返回值結果
5) 將結果轉成數組,獲取預支付id
4. 使用jsapi調起支付
1. 經過getParameters方法設置必傳參數,接口輸入數據爲json
2. 根據官方demo中jsapi.php 調起支付,獲得支付結果
注:使用以上方式判斷前端返回,res.err_msg 將在用戶支付成功後返回 ok,但不保證它絕對可靠。
5. 通用通知接口 callback
1. 支付完成後,微信會把相關支付和用戶信息發送到該 URL,商戶須要接收處理信息
2. 此時返回的參與簽名的參數有 : appid , mch_id, nonce_str, result_code ,openid , is_subscribe,trade_type , bank_type , total_fee , cash_fee , transaction_id,
out_trade_no , time_end
3. 返回數據爲xml,相關案例參考demo notify.php
4. 參考 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_7
4、可能遇到的問題
1. 返回參數是xml,而不是直接輸出success ,這個與微信app支付有區別。
2. 參與簽名字段要保證一致,保證先後簽名同樣。
3. 因爲存在從新發送後臺通知的狀況,所以一樣的通知可能會屢次發送給商戶系統。商戶系統必須可以正確處理重複的通知。好比在支付成功後寫入了支付日誌,那麼第二次回調前前判斷是否已經有了支付日誌,若是有,直接退出不做處理就行了。
4 . 當用戶有餘額,先用餘額支付,剩下的纔是微信 , 支付成功時,回調扣去餘額
5. 若是同一筆訂單號修改屢次價格進行支付,第二次支付時,會出現生成預支付訂單失敗,主要緣由是同一筆訂單支付時,支付金額不能同樣,或者給到第三方的訂單號不同,因此解決方法就是訂單號+標誌位(好比Z或A)+ 時間戳生成給到的第三方的支付號便可。
===============================支付完成的處理之分割線========================
微信內H5調起支付後,JS API的返回結果get_brand_wcpay_request:ok僅在用戶成功完成支付時返回。因爲前端交互複雜,get_brand_wcpay_request:cancel或者get_brand_wcpay_request:fail能夠統一處理爲用戶遇到錯誤或者主動放棄,沒必要細化區分。
示例代碼以下:
下一節《PHP微信公衆號JSAPI網頁支付(下)》 中將講解支付完成後,須要的回調通知處理等操做。