<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??一站式輕松地調用各大LLM模型接口,支持GPT4、智譜、豆包、星火、月之暗面及文生圖、文生視頻 廣告
                [TOC] ## 前言 H5支付是基于公眾號基礎開發的一種非微信內瀏覽器支付方式(需要單獨申請支付權限),可以滿足在微信外的手機H5頁面進行微信支付的需求。同時,由于H5鏈接傳播十分方便、來源不易追蹤,商戶需要特別注意做好防釣魚、防刷單的處理,控制風險。 **備注:** 本文檔重點介紹與前端相關的以及一些準備工作的部分,部分后端接口實現的不重點描述 ## 微信支付場景 ![微信支付種類](https://box.kancloud.cn/626f542460906f704a69875264662e3f_708x368.png) ## h5支付場景介紹 ![微信h5支付場景](https://box.kancloud.cn/c4ded64a883c11ae666d10185ef7106b_1316x362.png) ## 準備工作 ### 申請入口 ![申請流程](https://box.kancloud.cn/3eec50daf2459ca383f443e0912a750a_960x170.png) ### ua確定 為了保證最后的微信h5能成功,請確認需要的ua能把案例的微信支付喚起,其本質是一個url連接,帶有喚起微信支付的功能。 案例url:http://wxpay.wxutil.com/mch/pay/h5.v2.php 參考的生成地址格式(該頁面首先進行安全校驗,通過后才會喚起支付,不通過則會提示各種問題):https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx201711292155101b1c4a8fce0223911410&package=3611216311 ### 商戶準備 ![商戶準備](https://box.kancloud.cn/81ef7e5a0c789781400a8d9d69bf5e6b_592x228.png) ### 用戶設置圖解 ### 用戶支付流程 ![用戶支付流程圖解](https://box.kancloud.cn/72e9b08fc244298385cfde0e633d76d3_2304x510.png) ### 圖解支付流程(來源微信官網) ![下單支付時序圖](https://pay.weixin.qq.com/wiki/doc/api/img/chapter15_1.png) ### 注意事項 1、由商戶后臺向微信支付發起下單請求(調用統一下單接口)注:交易類型trade_type=MWEB,[參考下單文檔](https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=9_20&index=1) 2、統一下單接口返回支付相關參數給商戶后臺,如支付跳轉url(參數名“mweb_url”),商戶通過mweb_url調起微信支付中間頁 3、中間頁進行H5權限的校驗,安全性檢查(此處常見錯誤請見下文) 4、如支付成功,商戶后臺會接收到微信側的異步通知,后臺部分需要同步訂單的狀態 5、用戶界面需要正確設置支付結果的顯示邏輯,建議如上圖設計。 ## 技術準備 ## 常見的技術問題 ### 圖解常見的技術問題 ![校驗失敗錯誤圖解](https://box.kancloud.cn/aa329534552661c01cb20446b8f3cbcb_2934x886.png) ### 1 . 網絡環境未能通過安全驗證,請稍后再試 ip問題:本質原因是因為生成支付地址與實際支付時ip不一致,除去個人切換網絡之外的個人原因,其主要難點存在于獲取用戶網絡ip的部分。 **參考文檔**:[獲取ip指引](https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_5) **備注**:文檔已經比較詳細了,只不過如果你是純前端資源項目比如spa的,可能需要自己通過某種方式獲取用戶的ip,那么一種方式可以通過設置nginx實現,比如提到的下面的方式: ~~~ proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Real-Port $remote_port; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; ~~~ **其他方式:** 你也可以通過請求一個線上比較穩定的獲取ip的站點來實現如果以上的方式行不通,參考代碼如下,依賴于jsonp方案實現前端跨域請求。 ~~~ // 獲取ip的方法 getIp(){ return new Promise((resolve, reject) => { request.get('https://freegeoip.net/json/').use(jsonp({ })).end( (err, res)=>{ if(res&&res.body){ localStorage.setItem('ip',res['body']['ip']) } } ) }) }, ~~~ ### 2 . 商家參數格式有誤,請聯系商家解決 1. 當前調起H5支付的referer為空導致,一般是因為直接訪問頁面調起H5支付,請按正常流程進行頁面跳轉后發起支付,或自行抓包確認referer值是否為空。換句話就是說,需要你從產品支付頁生成調節跳轉到這個頁面,不能直接跳轉到該地址。 2. 如果是APP里調起H5支付,需要在webview中手動設置referer,如( Map extraHeaders = new HashMap(); extraHeaders.put("Referer", "商戶申請H5時提交的授權域名");//例如 http://www.baidu.com )) ### 3. 商家存在未配置的參數,請聯系商家解決 1,當前調起H5支付的域名(微信側從referer中獲取)與申請H5支付時提交的授權域名不一致,如需添加或修改授權域名,請登陸商戶號對應的商戶平臺--"產品中心"--"開發配置"自行配置 2,如果設置了回跳地址redirect_url,請確認設置的回跳地址的域名與申請H5支付時提交的授權域名是否一致(**需對redirect_url進行urlencode處理,js中建議使用encodeURIComponent方法**) ### 4. 支付請求已失效,請重新發起支付 一般很少發生這種情況,如果已失效,需要產品定義相關的方案,一般是用戶返回上一個頁面,重新進行支付流程。 ### 5. 請在微信外打開訂單,進行支付 h5支付不能再微信端進行 ### 6. OS:簽名驗證失敗 或者 安卓:系統繁忙,請稍后再試 基本不會遇到,如果遇到了參考官網的解釋: 1,請確認同一個MWEB_URL只被一個微信號調起,如果不同微信號調起請重新下單生成新的MWEB_URL 2,如MWEB_URL有添加redirect_url,請確認參數拼接格式是否有誤,是否有對redirect_url的值做urlencode,可對比以下例子格式: https://wx.tenpay.com/cgi-bin/mmpayweb-bin/checkmweb?prepay_id=wx20161110163838f231619da20804912345&package=1037687096&redirect_url=https%3A%2F%2Fwww.wechatpay.com.cn ## 其他 ### App-webview中支持支付 * 安卓代碼,需要攔截頁面的url,如果有對應的協議關鍵字,就用相關的喚起工具類 ![代碼實例](https://box.kancloud.cn/aae0f5a4c255153a1c129b25074795dc_1550x1530.png) 參考文檔:[csdn:安卓webview喚起微信支付](http://m.blog.csdn.net/xiaoxiao_ming/article/details/54692378) * ios 完成配置即可 ![微信支付配置](https://box.kancloud.cn/694b765bec2d66526815021115a71bf1_478x52.png) ![支付寶支付配置](https://box.kancloud.cn/56228b5683d43493927f69704691e689_525x38.png) 備注:如果你遇到了其他app打開支付寶支付跳轉到了你的app,是因為你的配置文檔里寫了支付寶的協議,去掉即可。比如下面的配置就會導致這種情況。 ![ios錯誤配置alipay.](https://box.kancloud.cn/c1b08168b7cb35e74411a97a77b54180_1061x158.png) ### 獲取app中的用戶信息 * 前提說明 如果你需要在app中一定要使用微信h5的支付,那么你肯定需要需要獲取用戶的信息,因為app中已經登錄過的不需要進入webivew重新登錄。 * 區分ua 因為wap是針對所有ua的,所以針對不同的ua需要單獨做處理,就需要區分不同的ua,那么app重需要追加特殊的標識,比如"XHX-v1.1.1",針對ua的轉化以及識別,本次方案中采用了ua-parse的模塊。 ~~~ let UAParser = require('ua-parser-js') let parser = new UAParser() let result = parser.getResult() // TYPE 枚舉: Mobile Safari ; WeChat ; App ; QQ ; ali let type = result.browser.name let version = result.browser.version let os = result.os.name let isApp=result.ua.indexOf('XHX')>-1 if(isApp){ type='App' }else if(result.ua.indexOf('AlipayClient')>-1){ type="ali" } var info = { os, type, version } module.exports = info ~~~ * 如果你是vue的項目,建議store中存儲一份ua相關的數據,便于使用,代碼如下(僅供參考) ~~~ const state = { // type 枚舉: 'Mobile Safari' ; 'WeChat' ; 'App' ; 'QQ' ; 'ali' ; os:localStorage.getItem("os")?localStorage.getItem("os"):'', type:localStorage.getItem("type")?localStorage.getItem("type"):'', version:localStorage.getItem("version")?localStorage.getItem("version"):'', ip:localStorage.getItem("ip")?localStorage.getItem("ip"):'', } const getters = { getUa:state=>{ return state } } const mutations = { // 更新用戶存儲信息,建議存儲到cookie一份,用于網關的請求 updateUa(state, ua) { state.os = ua.os localStorage.setItem('os', ua.os) state.type = ua.type localStorage.setItem('type', ua.type) state.version = ua.version localStorage.setItem('version', ua.version) }, updateIp(state,ip){ state.ip = ua.ip localStorage.setItem('ip', ua.ip) } } const actions = { } export default { state, getters, mutations, actions } ~~~ * **定義獲取用戶信息方法** 因為ios和安卓載入webview的時機不同,我們做了針對性的處理,如果你們不做區分也可以的。另外這里做個常識性的解釋:app中有js相關的方法的寫法,可以將一些js的方法注入到webview之中,在使用之前需要確定這些方法注入時是在你的方法之前還是之后。 我們目前摸索出來并決定的結果是:ios在前端之后,安卓在前端之后,客戶端的方法定義在window.xhxapp域名空間下,前端定義在window域名空間下,具體代碼如下: ~~~ if(ua.type=='App'){ //ios app內 if(ua.os=="iOS"){ // 與ios 約定 ,ios加載webview之后調用前端isReady方法 window.isReady=function(){ //約定 getUserInfo 返回user的json對象,共四個字段 if(window.xhxapp&&window.xhxapp.getUserInfo){ let user=window.xhxapp.getUserInfo(); store.commit("updateUser",user) } } } else{ //安卓app內 if(window.xhxapp&&window.xhxapp.getUserInfo){ let user=window.xhxapp.getUserInfo(); user=JSON.parse(user) //是否加json轉換根據app傳值類型,不固定 store.commit("updateUser",user) } } }else { } ~~~ ### 用戶支付界面產品設計 相信你可能理解了我的支付流程以及交互界面,但可能對具體的實現效果還不是特別清楚,下面我分四種情況分別介紹微信h5的最終實現效果。 1 常規瀏覽器 :微信支付 - 支持微信以及支付寶支付的兩種場景, - 傳回調地址,回調地址為支付成功的頁面 - 基于全面的考慮,建議訂單成功頁也進行訂單狀態查詢,如果還是未支付成功的再調回支付頁 - 請求接口拿到微信支付地址之后,選擇一次微信支付,記錄一次用戶支付 - 用戶取消支付回到支付頁,支付成功會到支付成功頁 - 支付頁進入時判斷是否有支付操作,有的話加用戶支付確認彈窗進行訂單查詢,查詢支付成功跳轉到訂單成功頁 2 qq瀏覽器 :微信支付 - 支持微信支付的一種場景, - 傳回調地址,回調地址為支付成功的頁面 - 基于全面的考慮,建議訂單成功頁也進行訂單狀態查詢,如果還是未支付成功的再調回支付頁 - 請求接口拿到微信支付地址之后,選擇一次微信支付,記錄一次用戶支付 - 用戶取消支付回到支付頁,支付成功會到支付成功頁 - 支付頁進入時判斷是否有支付操作,有的話加用戶支付確認彈窗進行訂單查詢,查詢支付成功跳轉到訂單成功頁 3 安卓 app:微信支付 - 支持微信支付,支付寶支付的2種場景, - 傳回調地址,回調地址為支付成功的頁面 - 基于全面的考慮,建議訂單成功頁也進行訂單狀態查詢,如果還是未支付成功的再調回支付頁 - 請求接口拿到微信支付地址之后,選擇一次微信支付,記錄一次用戶支付 - 用戶取消支付回到支付頁,支付成功會到app支付成功頁,這點安卓支持性較好 - 支付頁進入時判斷是否有支付操作,有的話加用戶支付確認彈窗進行訂單查詢,查詢支付成功跳轉到訂單成功頁 4 ios app:微信支付 - 支持微信支付,支付寶支付的2種場景, - 不傳回調地址 - 基于全面的考慮,建議訂單成功頁也進行訂單狀態查詢,如果還是未支付成功的再調回支付頁 - 請求接口拿到微信支付地址之后,選擇一次微信支付,記錄一次用戶支付 - 支付頁進入時判斷是否有支付操作,有的話加用戶支付確認彈窗進行訂單查詢,查詢支付成功跳轉到訂單成功頁 - ios app返回傳遞參數返回會有問題,所以我們不傳回調頁面,它默認返回項目根目錄,我們在h5的根目錄展示一個提示頁,告訴用戶切換到app進行查看訂單。 5 最終建議:希望大家針對app webview中的支付盡量不要用h5的方式,讓app單獨去開發,這是最好的方式。 ## 頁面支付邏輯判斷 ## 參考文檔 * [微信h5支付文檔](https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_1) * [微信h5支付,知乎問答](https://www.zhihu.com/question/39182675) * [常見的問題類型-微信官方](https://pay.weixin.qq.com/wiki/doc/api/H5.php?chapter=15_4)
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看