1.介紹
JSAPI支付是用戶在微信中打開商戶的H5頁面,商戶在H5頁面通過調用微信支付提供的JSAPI接口調起微信支付模塊完成支付。
應用場景有:
◆ 用戶在微信公眾賬號內進入商家公眾號,打開某個主頁面,完成支付
◆ 用戶的好友在朋友圈、聊天窗口等分享商家頁面連接,用戶點擊鏈接打開商家頁面,完成支付
◆ 將商戶頁面轉換成二維碼,用戶掃描二維碼后在微信瀏覽器中打開頁面后完成支付
JSAPI支付只能用微信瀏覽器打開
2.商戶號配置
在微信商戶平台(pay.weixin.qq.com)設置您的JSAPI支付支付目錄,設置路徑:商戶平台-->產品中心-->開發配置
JSAPI支付在請求支付的時候會校驗請求來源是否有在商戶平台做了配置,所以必須確保支付目錄已經正確的被配置,否則將驗證失敗,
請求支付不成功。
3.在微信公眾平台設置授權域名
開發JSAPI支付時,在統一下單接口中要求必傳用戶openid,而獲取openid則需要您在公眾平台設置獲取openid的域名
只有被設置過的域名才是一個有效的獲取openid的域名,否則將獲取失敗。
注:使用微信jsapi支付必須先配置好以上信息,不然開發過程成中會有很多頁面錯誤提示報錯,為了避免,先配置好所需要的信息,
網頁授權域名是用來向微信獲取code
4.微信網頁授權
如果用戶在微信客戶端中訪問第三方網頁,公眾號可以通過微信網頁授權機制,來獲取用戶基本信息,進而實現業務邏輯
關於網頁授權的兩種scope的區別說明
1、以snsapi_base為scope發起的網頁授權,是用來獲取進入頁面的用戶的openid的,並且是靜默授權並自動跳轉到回調頁的。用戶感知的就是直接進入了回調頁(往往是業務頁面)
2、以snsapi_userinfo為scope發起的網頁授權,是用來獲取用戶的基本信息的。但這種授權需要用戶手動同意,並且由於用戶同意過,所以無須關注,就可在授權后獲取該用戶的基本信息。
3、用戶管理類接口中的“獲取用戶基本信息接口”,是在用戶和公眾號產生消息交互或關注后事件推送后,才能根據用戶OpenID來獲取用戶基本信息。這個接口,包括其他微信接口,都是需要該用戶(即openid)關注了公眾號后,才能調用成功的。
官方鏈接:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140842
由於我們公司只需要獲取code調取后台接口換取openid,並且不需要獲取用戶昵稱,頭像等信息,所以我只需要使用第一種方式即可
方法如下:
用戶同意授權,獲取code
https://open.weixin.qq.com/connect/oauth2/authorize?appid=APPID&redirect_uri=REDIRECT_URI&response_type=code&scope=SCOPE&state=STATE#wechat_redirect 若提示“該鏈接無法訪問”,請檢查參數是否填寫錯誤,是否擁有scope參數對應的授權作用域權限。
注意:跳轉回調redirect_uri,應當使用https鏈接來確保授權code的安全性。
注意 代碼需要放到線上去運行,才能真的調取成功,在本地運行會報redirect_uri錯誤 提示
注意:code作為換取access_token的票據,每次用戶授權帶上的code將不一樣,code只能使用一次,5分鍾未被使用自動過期
5. 網頁授權成功了,那接下來就可以使用支付了
微信JS-SDK是微信公眾平台 面向網頁開發者提供的基於微信內的網頁開發工具包。
通過使用微信JS-SDK,網頁開發者可借助微信高效地使用拍照、選圖、語音、位置等手機系統的能力,同時可以直接使用微信分享、掃一掃、卡券、支付等微信特有的能力,為微信用戶提供更優質的網頁體驗。
由於jsapi支付是微信JS-SDK工具包的一種方式,所以我們先安裝JS-SDK工具包才能使用
第一步:綁定域名 由於之前我們已經在微信公眾號平台設置了js接口安全域名,故已經綁定成功
第二步:引入js文件
在需要調用JS接口的頁面引入如下JS文件,(支持https):http://res.wx.qq.com/open/js/jweixin-1.4.0.js
如需進一步提升服務穩定性,當上述資源不可訪問時,可改訪問:http://res2.wx.qq.com/open/js/jweixin-1.4.0.js (支持https)。
備注:支持使用 AMD/CMD 標准模塊加載方法加載
第三步 :通過config接口注入權限驗證配置
wx.config({ debug: true, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: '', // 必填,公眾號的唯一標識 timestamp: , // 必填,生成簽名的時間戳 nonceStr: '', // 必填,生成簽名的隨機串 signature: '',// 必填,簽名 jsApiList: [] // 必填,需要使用的JS接口列表 });
6.最后可以發起微信支付了
wx.chooseWXPay({ timestamp: 0, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后台生成簽名使用的timeStamp字段名需大寫其中的S字符 nonceStr: '', // 支付簽名隨機串,不長於 32 位 package: '', // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=\*\*\*) signType: '', // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5' paySign: '', // 支付簽名 success: function (res) { // 支付成功后的回調函數 } });
完整實例如下:
var appid = 'appid';//appid為公眾號appid var local = window.location.href ;//當前跳轉路徑 var code = getParam('code');//獲取地址欄參數code if (code === null || code === '') { // 跳轉至授權地址,該地址只支持微信瀏覽器打開 location.replace("https://open.weixin.qq.com/connect/oauth2/authorize?appid=" + appid + "&redirect_uri=" + encodeURIComponent(local) + "&response_type=code&scope=snsapi_base#wechat_redirect") }else{ getOpenId(code);//拿到了code 找后台換取openid } //為避免網頁授權會刷新界面,ios微信瀏覽器會出現白條切換按鈕會導致支付出錯 ,建議將以上方法寫在首頁中,不要寫在支付頁面 getConfig()//授權方法應放在支付頁面加載的時候。進入支付頁面就執行授權 wx.chooseWXPay({ //此方法應放在調用后台統一下單接口成功后回調里面,接口返回 timeStamp,nonceStr,package,paySign等參數 timestamp: res.data.timeStamp, nonceStr: res.data.nonceStr, package: res.data.package, signType: 'MD5', paySign: res.data.paySign, appId:res.data.appId, //此參數可不用 success: function (r) { // 支付成功后的回調函數 if (r.errMsg == "chooseWXPay:ok") { //支付成功 } else { location.reload();//支付失敗 刷新界面 } }, cancel: function(r) { //支付取消 } }); //以下方法可以放在common.js中 //獲取地址欄 指定參數名參數 function GetQueryString(name) { var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i"); var r = window.location.search.substr(1).match(reg); //獲取url中"?"符后的字符串並正則匹配 var context = ""; if (r != null) context = r[2]; reg = null; r = null; return context == null || context == "" || context == "undefined" ? "" : context; } function getOpenId(code) {//我們公司獲取openid接口 $.ajax({ type: "POST", url: window.baseurl+"/miniprogram/user/getOpenId?code="+code+"&type=2",//1 微信 2公眾號 cache: false, processData: false, contentType: false, dataType: "json", success: function (res) { if (res.msgCode==0) {//成功 localStorage.setItem('openId',res.data.openid)//將openid存入緩存 } else { // alert('openid獲取失敗') } }, error: function (res) { }, }) } function getConfig(){ //獲取后台簽名,向微信獲取授權 $.ajax({ type: "POST", url: window.baseurl+"/miniprogram/user/getTicket", data:{"url":location.href.split("#")[0]}, dataType: "json", success: function (data) { if (data.msgCode==0) {//成功 wxConfig(data.data.timestamp,data.data.nonceStr,data.data.signature) } else { } }, error: function (res) { }, }) } //獲取微信授權 function wxConfig(Timestamp,NonceStr,Signature){ //通過config接口注入權限驗證配置 wx.config({ debug: false, // 開啟調試模式,調用的所有api的返回值會在客戶端alert出來,若要查看傳入的參數,可以在pc端打開,參數信息會通過log打出,僅在pc端時才會打印。 appId: 'wx840b32f985622d8e', // 必填,公眾號的唯一標識 timestamp: Timestamp, // 必填,生成簽名的時間戳 nonceStr: NonceStr, // 必填,生成簽名的隨機串 signature: Signature,// 必填,簽名 jsApiList: ['chooseWXPay','scanQRCode'] // 必填,需要使用的JS接口列表 這里是使用的是微信支付接口 }); //通過ready接口處理成功驗證 wx.ready(function(){ console.log('ready接口處理成功驗證') }); //通過error接口處理失敗驗證 wx.error(function(res){ console.log('error接口處理失敗驗證') }); }
最后注意:(以下都是本人踩過的坑!!!)
1.由於網頁授權會二次刷新頁面,ios手機微信底部會出現白條,故跳轉頁面方法最好使用window,location.replace() 可以避免支付錯誤,比如 提示:調用支付jsapi缺少參數: $key0$ 這是由於沒拿到openid導致
2.調用支付時,錯誤提示為: 支付返回簽名錯誤 可能是由於后台生成簽名時參數大小寫沒有按照官方文檔大小寫來生成簽名。故一定要嚴格按照官方文檔要求開發
3.如果signature簽名和微信校驗工具簽名一致,但是還是報config:invalid signature 錯誤,可能是公眾號后台ip白名單沒有設置當前使用環境的ip