完成微信h5支付的你,繼續公衆號的支付也許更簡單哦。php
微信瀏覽器中的應用支付必須依賴於公衆號支付,下面就公衆號支付中的一些技術點進行詳細的解析。html
參考資料:微信公衆號開通支付功能--百度經驗教程前端
與微信h5基本相同,惟一不一樣的是此次微信返回的須要喚起微信sdk支付的參數列表。vue
網站應用微信登陸是基於OAuth2.0協議標準構建的微信OAuth2.0受權登陸系統。獲取openid分爲兩步,獲取code,而後根據code獲取openid,建議這兩部分請求由後端發起,前端直接請求會涉及到跨域問題。後端直接把這兩個方法定義爲工具方法,使用方便,便於其餘場景的複用。web
標準格式拼接代碼:json
let encodeUrl=encodeURIComponent(`http://xxx/xhxwxpay?productId=${productId}&orderNo=${orderNo}`) let tempUrl=`https://open.weixin.qq.com/connect/oauth2/authorize?appid=wx6f5de09c8ef178a7&redirect_uri=${encodeUrl}&response_type=code&scope=snsapi_userinfo&state=STATE#wechat_redirect`
請求參數說明後端
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應用惟一標識 |
redirect_uri | 是 | 請使用urlEncode對連接進行處理 |
response_type | 是 | 填code |
scope | 是 | 應用受權做用域,擁有多個做用域用逗號(,)分隔,網頁應用目前僅填寫snsapi_login便可,這裏用的 snsapi_userinfo |
state | 否 | 用於保持請求和回調的狀態,受權請求後原樣帶回給第三方。該參數可用於防止csrf攻擊(跨站請求僞造攻擊),建議第三方帶上該參數,可設置爲簡單的隨機數加session進行校驗 |
用戶容許受權後,將會重定向到redirect_uri的網址上,而且帶上code和state參數redirect_uri?code=CODE&state=STATE
若用戶禁止受權,則重定向後不會帶上code參數,僅會帶上state參數redirect_uri?state=STATE
api
一個用戶針對一個公衆號openid是固定的,因此獲取到同樣的不用懷疑,涉及到部分敏感的公衆號的祕鑰等,建議是後端處理髮起請求,這樣也能夠避免前端跨域的問題。跨域
//網關或者後端的設置(以koa框架的爲例) *post_getOpenId(){ let reqData = this.request.body; let param = { appid:'wxxxx', secret:'affsdcsdvdsvfv6', code:reqData.code, grant_type:'authorization_code' } let result = yield this.api.getOpenId(param); this.body = result; } // 獲取openid 傳入對象的形式,改造通用的api方法 getOpenId: function* (apiParam, json = true) { // 獲取token的地址 let apiUrl='https://api.weixin.qq.com/sns/oauth2/access_token' let response = yield request.get(apiUrl, { qs: apiParam, json: json }); return responseHandle(response, apiUrl, apiParam); }.bind(this), //前端的寫法,好處是避免暴露公衆號的相關信息 this.$api.post("order/getOpenId", { code: this.code }).then(res => { // 正確獲取openid的狀況下 請求後臺參數獲得對應的返回參數,目前只須要openid if (res.openid) { this.openId = res.openid; //準備條件足夠的話 能夠喚起支付 this.topay() }else { //請求失敗或者沒有對應的字段 }
請求參數說明,經過code獲取access_token瀏覽器
https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
參數 | 是否必須 | 說明 |
---|---|---|
appid | 是 | 應用惟一標識,在微信開放平臺提交應用審覈經過後得到 |
secret | 是 | 應用密鑰AppSecret,在微信開放平臺提交應用審覈經過後得到 |
code | 是 | 填寫第一步獲取的code參數 |
grant_type | 是 | 填authorization_code |
返回結果說明
//正確的返回 { "access_token":"ACCESS_TOKEN", "expires_in":7200, "refresh_token":"REFRESH_TOKEN", "openid":"OPENID", "scope":"SCOPE", "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL" } //錯誤的返回 {"errcode":40029,"errmsg":"invalid code"}
若是token失效了,能夠用refresh_token從新獲取一個。
invoke方法 ,簡單有效,直接根據接口返回參數喚起。如下代碼實例是vue環境下的,其餘環境請自行匹配,僅供參考。
// 準備好微信sdk部分 jsSdk(){ // 判斷微信的WeixinJSBridge if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', this.onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', this.onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', this.onBridgeReady); } }else{ this.onBridgeReady(); } }, // 支付sdk準備完成 onBridgeReady() { // 觸發微信支付 WeixinJSBridge.invoke( 'getBrandWCPayRequest', { appId: this.payOption.appId, //公衆號名稱,由商戶傳入 timeStamp: this.payOption.timeStamp, //時間戳,自1970年以來的秒數 nonceStr: this.payOption.nonceStr, //隨機串 package: this.payOption.package, //prepay_id用等式的格式 signType: this.payOption.signType, //微信簽名方式: paySign: this.payOption.paySign, //微信簽名 }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ) { // 支付成功 返回成功頁 let tempUrl="//paysucc" location.href=tempUr } else{ // 取消支付或者其餘狀況 get_brand_wcpay_request:cancel get_brand_wcpay_request:fail let tempUrl='//topay' location.href=tempUrl } } ); },
引入模塊--ready--獲取access-token--獲取ticket--生成簽名(wx.config須要)--結合接口返回參數--喚起wxpay。(比較麻煩,不推薦使用)
參考文檔: