微信公眾號(hào)支付實(shí)現(xiàn)詳解(前端)

前言

完成微信h5支付的你,繼續(xù)公眾號(hào)的支付也許更簡(jiǎn)單哦胆剧。

場(chǎng)景

微信瀏覽器中的應(yīng)用支付必須依賴于公眾號(hào)支付,下面就公眾號(hào)支付中的一些技術(shù)點(diǎn)進(jìn)行詳細(xì)的解析。

準(zhǔn)備工作

基本配置申請(qǐng)

參考資料:微信公眾號(hào)開通支付功能--百度經(jīng)驗(yàn)教程

基本信息

  • 服務(wù)號(hào)捉片,服務(wù)號(hào)綁定的管理員號(hào)
  • 開通支付賬號(hào),并記住支付賬號(hào)汞舱,與支付賬號(hào)綁定的微信號(hào)
  • appid,秘鑰
  • 支付賬號(hào)開通支付目錄(直接支付地址的上一級(jí)目錄
  • 設(shè)置了頁面授權(quán)域名伍纫,并且是你的站點(diǎn)域名地址
  • 基本接口權(quán)限,尤其是jssdk部分權(quán)限昂芜,保證盡可能都開通

業(yè)務(wù)流程圖解以及時(shí)序圖

與微信h5基本相同莹规,唯一不同的是這次微信返回的需要喚起微信sdk支付的參數(shù)列表。

技術(shù)問題

獲取openid

網(wǎng)站應(yīng)用微信登錄是基于OAuth2.0協(xié)議標(biāo)準(zhǔn)構(gòu)建的微信OAuth2.0授權(quán)登錄系統(tǒng)泌神。獲取openid分為兩步良漱,獲取code,然后根據(jù)code獲取openid欢际,建議這兩部分請(qǐng)求由后端發(fā)起母市,前端直接請(qǐng)求會(huì)涉及到跨域問題。后端直接把這兩個(gè)方法定義為工具方法损趋,使用方便窒篱,便于其他場(chǎng)景的復(fù)用。

一 :請(qǐng)求獲取code,如果不想浪費(fèi)時(shí)間請(qǐng)直接復(fù)制粘貼使用

  • 標(biāo)準(zhǔn)格式拼接代碼:

    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`
    
  • 請(qǐng)求參數(shù)說明

    參數(shù) 是否必須 說明
    appid 應(yīng)用唯一標(biāo)識(shí)
    redirect_uri 請(qǐng)使用urlEncode對(duì)鏈接進(jìn)行處理
    response_type 填code
    scope 應(yīng)用授權(quán)作用域墙杯,擁有多個(gè)作用域用逗號(hào)(,)分隔配并,網(wǎng)頁應(yīng)用目前僅填寫snsapi_login即可,這里用的 snsapi_userinfo
    state 用于保持請(qǐng)求和回調(diào)的狀態(tài)高镐,授權(quán)請(qǐng)求后原樣帶回給第三方溉旋。該參數(shù)可用于防止csrf攻擊(跨站請(qǐng)求偽造攻擊),建議第三方帶上該參數(shù)嫉髓,可設(shè)置為簡(jiǎn)單的隨機(jī)數(shù)加session進(jìn)行校驗(yàn)
  • 返回說明:
    用戶允許授權(quán)后观腊,將會(huì)重定向到redirect_uri的網(wǎng)址上,并且?guī)蟘ode和state參數(shù)
    redirect_uri?code=CODE&state=STATE
    若用戶禁止授權(quán)算行,則重定向后不會(huì)帶上code參數(shù)梧油,僅會(huì)帶上state參數(shù)
    redirect_uri?state=STATE

  • 參考文檔:微信中web網(wǎng)站獲取code參考文檔

二 根據(jù)code獲取openid

  • 一個(gè)用戶針對(duì)一個(gè)公眾號(hào)openid是固定的,所以獲取到一樣的不用懷疑州邢,涉及到部分敏感的公眾號(hào)的秘鑰等儡陨,建議是后端處理發(fā)起請(qǐng)求,這樣也可以避免前端跨域的問題。

    //網(wǎng)關(guān)或者后端的設(shè)置(以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 傳入對(duì)象的形式量淌,改造通用的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),
    
    //前端的寫法骗村,好處是避免暴露公眾號(hào)的相關(guān)信息
    this.$api.post("order/getOpenId", { code: this.code }).then(res => {
          //  正確獲取openid的情況下 請(qǐng)求后臺(tái)參數(shù)得到對(duì)應(yīng)的返回參數(shù),目前只需要openid
          if (res.openid) {
            this.openId = res.openid;
            //準(zhǔn)備條件足夠的話 可以喚起支付
            this.topay()
         }else {
           //請(qǐng)求失敗或者沒有對(duì)應(yīng)的字段
           }
    
  • 請(qǐng)求參數(shù)說明,通過code獲取access_token

    https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
    
    
    參數(shù) 是否必須 說明
    appid 應(yīng)用唯一標(biāo)識(shí)呀枢,在微信開放平臺(tái)提交應(yīng)用審核通過后獲得
    secret 應(yīng)用密鑰AppSecret胚股,在微信開放平臺(tái)提交應(yīng)用審核通過后獲得
    code 填寫第一步獲取的code參數(shù)
    grant_type 填authorization_code
  • 返回結(jié)果說明

    //正確的返回
    { 
    "access_token":"ACCESS_TOKEN", 
    "expires_in":7200, 
    "refresh_token":"REFRESH_TOKEN",
    "openid":"OPENID", 
    "scope":"SCOPE",
    "unionid": "o6_bmasdasdsad6_2sgVt7hMZOPfL"
    }
    //錯(cuò)誤的返回
    {"errcode":40029,"errmsg":"invalid code"}
    
  • 刷新fresh-token有效期
    如果token失效了,可以用refresh_token重新獲取一個(gè)裙秋。

微信支付sdk

方式一 :官網(wǎng)的方式

invoke方法 琅拌,簡(jiǎn)單有效,直接根據(jù)接口返回參數(shù)喚起摘刑。以下代碼實(shí)例是vue環(huán)境下的进宝,其他環(huán)境請(qǐng)自行匹配,僅供參考泣侮。

// 準(zhǔn)備好微信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準(zhǔn)備完成
    onBridgeReady() {

    // 觸發(fā)微信支付
          WeixinJSBridge.invoke(
       'getBrandWCPayRequest', {
       appId: this.payOption.appId, //公眾號(hào)名稱即彪,由商戶傳入
        timeStamp: this.payOption.timeStamp, //時(shí)間戳紧唱,自1970年以來的秒數(shù)
        nonceStr: this.payOption.nonceStr, //隨機(jī)串
        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="http://paysucc"
            location.href=tempUr
           } else{
            //  取消支付或者其他情況 get_brand_wcpay_request:cancel get_brand_wcpay_request:fail
            let tempUrl='//topay'
            location.href=tempUrl
           }    
       }
   ); 
    },

方式二 : 需要引入js-weixin的模塊活尊,流程如下:

引入模塊--ready--獲取access-token--獲取ticket--生成簽名(wx.config需要)--結(jié)合接口返回參數(shù)--喚起wxpay。(比較麻煩漏益,不推薦使用)
參考文檔:

參考文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末蛹锰,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绰疤,更是在濱河造成了極大的恐慌铜犬,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異癣猾,居然都是意外死亡敛劝,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門纷宇,熙熙樓的掌柜王于貴愁眉苦臉地迎上來夸盟,“玉大人,你說我怎么就攤上這事像捶∩仙拢” “怎么了?”我有些...
    開封第一講書人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵拓春,是天一觀的道長(zhǎng)释簿。 經(jīng)常有香客問我,道長(zhǎng)硼莽,這世上最難降的妖魔是什么庶溶? 我笑而不...
    開封第一講書人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮沉删,結(jié)果婚禮上渐尿,老公的妹妹穿的比我還像新娘。我一直安慰自己矾瑰,他們只是感情好砖茸,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著殴穴,像睡著了一般凉夯。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上采幌,一...
    開封第一講書人閱讀 49,842評(píng)論 1 290
  • 那天劲够,我揣著相機(jī)與錄音,去河邊找鬼休傍。 笑死征绎,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的磨取。 我是一名探鬼主播人柿,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼忙厌!你這毒婦竟也來了凫岖?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬榮一對(duì)情侶失蹤逢净,失蹤者是張志新(化名)和其女友劉穎哥放,沒想到半個(gè)月后歼指,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡甥雕,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年踩身,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片社露。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡惰赋,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出呵哨,到底是詐尸還是另有隱情赁濒,我是刑警寧澤,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布孟害,位于F島的核電站拒炎,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏挨务。R本人自食惡果不足惜击你,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谎柄。 院中可真熱鬧丁侄,春花似錦、人聲如沸朝巫。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽劈猿。三九已至拙吉,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間揪荣,已是汗流浹背筷黔。 一陣腳步聲響...
    開封第一講書人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留仗颈,地道東北人佛舱。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像挨决,于是被迫代替她去往敵國(guó)和親请祖。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

推薦閱讀更多精彩內(nèi)容