ps:注冊微信測試公眾號
01 獲取access_token
access_token是公眾號的全局唯一票據,公眾號調用各接口時都需使用access_token。開發者需要進行妥善保存。access_token的存儲至少要保留512個字符空間。access_token的有效期目前為2個小時,需定時刷新,重復獲取將導致上次獲取的access_token失效。
公眾平台的API調用所需的access_token的使用及生成方式說明:
1、為了保密appsecrect,第三方需要一個access_token獲取和刷新的中控服務器。而其他業務邏輯服務器所使用的access_token均來自於該中控服務器,不應該各自去刷新,否則會造成access_token覆蓋而影響業務; 2、目前access_token的有效期通過返回的expire_in來傳達,目前是7200秒之內的值。中控服務器需要根據這個有效時間提前去刷新新access_token。在刷新過程中,中控服務器對外輸出的依然是老access_token,此時公眾平台后台會保證在刷新短時間內,新老access_token都可用,這保證了第三方業務的平滑過渡; 3、access_token的有效時間可能會在未來有調整,所以中控服務器不僅需要內部定時主動刷新,還需要提供被動刷新access_token的接口,這樣便於業務服務器在API調用獲知access_token已超時的情況下,可以觸發access_token的刷新流程。
如果第三方不使用中控服務器,而是選擇各個業務邏輯點各自去刷新access_token,那么就可能會產生沖突,導致服務不穩定。
公眾號可以使用AppID和AppSecret調用本接口來獲取access_token。AppID和AppSecret可在微信公眾平台官網-開發者中心頁中獲得(需要已經成為開發者,且帳號沒有異常狀態)。注意調用所有微信接口時均需使用https協議。
接口調用請求說明
http請求方式: GET https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=APPID&secret=APPSECRET
參數說明
參數 | 是否必須 | 說明 |
---|---|---|
grant_type | 是 | 獲取access_token填寫client_credential |
appid | 是 | 第三方用戶唯一憑證 |
secret | 是 | 第三方用戶唯一憑證密鑰,即appsecret |
返回說明
正常情況下,微信會返回下述JSON數據包給公眾號:
{"access_token":"ACCESS_TOKEN","expires_in":7200}
參數 | 說明 |
---|---|
access_token | 獲取到的憑證 |
expires_in | 憑證有效時間,單位:秒 |
錯誤時微信會返回錯誤碼等信息,JSON數據包示例如下(該示例為AppID無效錯誤):
{"errcode":40013,"errmsg":"invalid appid"}
02 獲取jsapi_ticket
用第一步拿到的access_token 采用http GET方式請求獲得jsapi_ticket(有效期7200秒,開發者必須在自己的服務全局緩存jsapi_ticket):
https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
我們可以獲得
{"errcode":0, "errmsg":"ok", "ticket":"bxLdikRXVbTPdHSM05e5u5sUoXNKd8-41ZO3MhKoyN5OfkWITDGgnr2fwJ0m9E8NYzWKVZvdVtaUgWvsdshFKA", "expires_in":7200 }
里面的ticket就是jsapi_ticket。
03按簽名算法得到signature
簽名生成規則如下:
參與簽名的字段包括noncestr(隨機字符串), 有效的jsapi_ticket, timestamp(時間戳), url(當前網頁的URL,不包含#及其后面部分) 。
對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1。
這里需要注意的是所有參數名均為小寫字符。對string1作sha1加密,字段名和字段值都采用原始值,不進行URL 轉義。 即signature=sha1(string1)。 示例: noncestr=Wm3WZYTPz0wzccnW jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg timestamp=1414587457 url=http://mp.weixin.qq.com?params=value
步驟1. 對所有待簽名參數按照字段名的ASCII 碼從小到大排序(字典序)后,使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串string1: jsapi_ticket=sM4AOVdWfPE4DxkXGEs8VMCPGGVi4C3VM0P37wVUCFvkVAy_90u5h9nbSlYy3-Sl-HhTdfl2fzFy1AOcHKP7qg&noncestr=Wm3WZYTPz0wzccnW×tamp=1414587457&url=http://mp.weixin.qq.com?params=value 步驟2. 對string1進行sha1簽名,得到signature: 0f9de62fce790f9a083d5c99e95740ceb90c27ed 注意事項 簽名用的noncestr和timestamp必須與wx.config中的nonceStr和timestamp相同。 簽名用的url必須是調用JS接口頁面的完整URL。 出於安全考慮,開發者必須在服務器端實現簽名的邏輯。 如出現invalid signature 等錯誤詳見附錄5常見錯誤及解決辦法。
配置完成之后,我們就可以在下面的函數中調用微信支付接口了。
wx.ready(function(){ wx.chooseWXPay({ timestamp: 0, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后台生成簽名使用的timeStamp字段名需大寫其中的S字符 nonceStr: '', // 支付簽名隨機串,不長於 32 位 package: '', // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=***) signType: '', // 簽名方式,默認為'SHA1',使用新版支付需傳入'MD5' paySign: '', // 支付簽名 success: function (res) { // 支付成功后的回調函數 } }); // config信息驗證后會執行ready方法,所有接口調用都必須在config接口獲得結果之后,config是一個客戶端的異步操作,所以如果需要在頁面加載時就調用相關接口,則須把相關接口放在ready函數中調用來確保正確執行。對於用戶觸發時才調用的接口,則可以直接調用,不需要放在ready函數中。 });
然后,這里的支付簽名paySign和package按照前面的方式得來就行了。
總結:如果僅僅是實現微信支付這樣的功能,還是參考第三項。因為第四項多了一步,v2版本已經淘汰。
如果需要實現微信支付和其他微信功能,那么參考第四項。
里面的坑很多:記住,參數名的大小寫要一致,不管是前端還是后台,在簽名時,只要大小寫不一致,就會出錯。