摘要:這是我第一次接觸微信支付,發現網上還是有很多同學在求助,了怎么辦是什么情況為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。
凡是和錢打交道的事,沒有一樣是容易的。這是我第一次接觸微信支付,發現網上還是有很多同學在求助,XXX了怎么辦?XXX是什么情況?為了幫助更多的小伙伴脫離“苦海”,我決定寫下這次的踩坑之旅,給更多的人幫助。介紹
微信支付方式分為刷卡支付、公眾號支付、掃碼支付、APP支付、H5支付、小程序支付。
先從應用場景來各自說一說,這樣,能夠最快的判斷出應該選擇哪一種支付。
刷卡支付:使用掃描設備(掃描槍)多見于超市、便利店使用
公眾號支付:嵌入公眾號的H5頁面
掃碼支付:用戶打開“微信掃一掃”,掃描商戶的二維碼并支付
APP支付:外部APP應用,用戶觸發支付時,轉到微信內完成支付
H5支付:非微信內置瀏覽器請求微信支付
小程序支付:用戶在微信小程序中使用微信支付
背景我們公司申請的是微信服務號,需要微信支付的是嵌入服務號內部的網頁,所以根據介紹,應該選擇“公眾號支付”。
開發步驟首先不要被微信支付的開發嚇著,其實它很簡單。先仔細看公眾號支付的文檔,看不懂的多看幾遍,還看不懂的,動手操作一下,試一試。
文檔在此:
https://pay.weixin.qq.com/wik...
步驟一:統一下單
跟著文檔,咱一點點來,搞明白每一步是為什么,就不會迷迷糊糊搞不清楚了。
首先說一下,這個接口是后臺需要完成的,這個接口的目的就是獲取prepay_id,它是預支付交易回話標識。將prepay_id傳給前臺,前臺調用js-sdk,這屬于步驟二的范圍了,一會講。
接口鏈接
URL地址:https://api.mch.weixin.qq.com...
在文檔中說明了,必須使用post 方法請求微信給的接口鏈接,傳入的數據也必須是xml格式,返回的也是xml的。醉了?不要醉,微信是這樣的,支付寶也是這樣的。手動微笑,接受吧。
接著來。
簡單粗暴貼代碼:
// "/addOrder"是留給前臺的調用接口 router.post("/addOrder",(req,res)=>{ const addOrderUrl = "https://api.mch.weixin.qq.com/pay/unifiedorder"; var client_ip = ""; client_ip = req.body.ipaddr; var appid = "1234567890"; // 服務號|公眾號的appid var body = "商品簡單描述-測試"; // 商品簡單描述 var mch_id= "1234567890"; // 商戶號,申請微信支付,騰訊給的商戶號 // var device_info = "WEB"; var nonce_str = getRanId(32); // 隨機字符串 var out_trade_no = "" +new Date().getTime() + Math.floor( Math.random() * 10 ); //商戶訂單號 var total_fee = req.body.total_fee; //支付金額,單位:分 var sign = ""; var notify_url = "http://123.456.789"; //異步接收微信支付結果通知的回調地址 var trade_type = "JSAPI"; // 交易類型 var openid = req.session.openId; console.log(openid); var stringA = `appid=${appid}&body=${body}&mch_id=${mch_id}&nonce_str=${nonce_str}¬ify_url=${notify_url}&openid=${openid}&out_trade_no=${out_trade_no}&spbill_create_ip=${client_ip}&total_fee=${total_fee}&trade_type=${trade_type}`; var stringSighTemp = stringA+"&key=****#####jiaoyuguihuayuan----***"; //32位的商戶key,自定義的,這里為了隱私,我用的特殊符號給你們展示 sign = md5(stringSighTemp).toUpperCase(); var xml = ``; var Res = res;axios({ method: "post", url: addOrderUrl, data: xml, responseType: "text/xml", headers: { "Content-Type": "text/xml" } }).then( res=>{ console.log(res) Res.send(res.data) }).catch( err=>{ console.log( err)}) }) ${appid} ${body}${mch_id} ${nonce_str} ${notify_url} ${openid} ${out_trade_no} ${client_ip} ${total_fee} ${trade_type} ${sign}
說明
client_ip 參數 是客戶端的ip地址,本來我是在后臺獲取客戶端ip地址的,因為我們使用了nginx代理,req.ip 返回的都是 ::ffff:127.0.0.1 這是IPV6格式的字符串。網上有一個答案對此做出了解釋: stackoverflow.com/questions/2…
在這里,我用的一個網上的腳本在前臺獲取的, http://pv.sohu.com/cityjson?i...
使用方法: window.ipaddr = returnCitySN[‘cip’];
其他的參數,都是參考微信支付的要求去寫的。
出現的錯誤
XML格式錯誤
而查看文檔,原因是這樣的
我:#&(%#@+%),也不給個詳細點的說明…
這種錯誤需要“頓悟”,我突然發現了我的錯誤。是我理解錯了!我給body標簽加了一個 導致我的xml格式錯誤,其實是有detail字段才需要添加 <[CDATA[]]>, 其他的不需要。
我:咳咳,低級錯誤。注意看文檔,按照要求來,既不多添什么,也不要少什么。
我把<[CDATA[]]>去掉之后,發現果真是這個原因,不再出現XML格式錯誤了,然而,還是高興的太早,因為它報了簽名錯誤。呵呵呵~
簽名錯誤
文檔中說的簽名計算很嚴格:
第一步,設所有發送或者接收到的數據為集合M,將集合M內非空參數值的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特別注意以下重要規則:
第一步,設所有發送或者接收到的數據為集合M,將集合M內非空參數值的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
◆ 參數名ASCII碼從小到大排序(字典序);
◆ 如果參數的值為空不參與簽名;
◆ 參數名區分大小寫; (公眾號支付全是小寫)
◆ 驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,將生成的簽名與該sign值作校驗。
◆ 微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。
◆ key設置路徑:微信商戶平臺(pay.weixin.qq.com)–>賬戶設置–>API安全–>密鑰設置
這里我查閱了一些資料,看到過有這樣幾種錯誤情況:
key 看錯了,這里應該寫商戶的key,而這個key 是用戶手動設置的,長32位。注意:自己保存一份,因為設置好了之后是沒法打開查看的。
還有一種錯誤,我覺得很離譜啊,body里面不能有中文,然而,我把body中的文字改為英文,發現并不能改變現狀,其實用中文是可以的。
…
總之,找到的這些錯誤,通通對我的情況沒用!
然后這又需要“頓悟”,原來stringA字符串我用了換行符把很長的字符隔開,這導致換行符被轉換為Ascall碼中的 n 寫進了簽名里面,所以,sign錯誤,所以要么,把換行符通通去掉,要么用“”連接,舍棄。我把換行都去掉之后,就沒有簽名錯誤了。
當當當當 ~
終于完成了第一步,后臺成功的返回了我們需要的prepay_id
這里為了安全,對于返回sign,和發送的sign進行對比,完全相等之后,才能把結果返回給前臺。
步驟二:調用微信js-sdk接口
微信支付
發起一個微信支付請求
前臺收到的是xml數據,要先解析一下,得到prepay_id
然后調用微信支付js-sdk,為了大家少走一些彎路,我先來正確的寫法,關鍵步驟如下:
var {prepay_id,appid} = getInfo(res.data); //從后臺數據中獲取appid 和 prepay_id nonceStr = getRanId(32); timeStamp = new Date().getTime(); var stringA = "appId="+appid+"&nonceStr="+nonceStr+"&package=prepay_id="+prepay_id+"&signType=MD5&timeStamp="+timeStamp; var stringSignTemp = stringA+"&key=****#####jiaoyuguihuayuan----***"; paySign = md5(stringSignTemp).toUpperCase(); window.wx.chooseWXPay({ timestamp: timeStamp, // 支付簽名時間戳,注意微信jssdk中的所有使用timestamp字段均為小寫。但最新版的支付后臺生成簽名使用的timeStamp字段名需大寫其中的S字符 nonceStr: nonceStr, // 支付簽名隨機串,不長于 32 位 package: "prepay_id=" + prepay_id, // 統一支付接口返回的prepay_id參數值,提交格式如:prepay_id=***) signType: "MD5", // 簽名方式,默認為"SHA1",使用新版支付需傳入"MD5" paySign: paySign, // 支付簽名 success: function (res) { // 支付成功后的回調函數 console.log(res) }, fail: function(err){ console.log(err) }});
備注:prepay_id 通過微信支付統一下單接口拿到,paySign 采用統一的微信支付 Sign 簽名生成方法,注意這里 appId 也要參與簽名,appId 與 config 中傳入的
appId 一致,即最后參與簽名的參數有appId, timeStamp, nonceStr,
package, signType。
注意,我要講個坑點~
調用js-sdk時,簽名中的字段都是小駝峰的寫法,timeStamp是這樣寫的,但是wx.config中,timestamp 是全小寫的,所以,親們,千萬不要搞錯了,我在這里就被坑了好一會呢。
寫完簽名之后,當你用微信web開發者工具去測試的話,就會看到,“不支持模擬”這樣的提示。這個時候,不要猶豫,直接上真機去測試,這并不是我們的程序出現了問題。
小tips: 在真機上,我們是沒有辦法看到console出的一些調試信息,所以,要想個辦法,可以用alert,也可以把調試信息打印在屏幕上面,我選擇打印在屏幕上。這里要說一些,微信給的文檔沒有那么齊全,有一些是要試試才指導的,比如wx.config中的success和fail函數,參數信息怎么打印,其實是res.errMsg和err.errMsg.
上面我說的這些你都注意到了,但是微信支付的控件你依然調動不起來的話,可能是微信商戶平臺的開發配置出現了問題,在產品中心-開發配置-支付配置-公眾號支付
中進行配置,配置的時候,注意一定要到最后一級目錄,比如我要在cms.123.456/book/list/index.html頁面中去進行微信支付,那么你的配置應該是 cms.123.456/book/list/
好了,開發中基本上所有的坑都提到了,這是建立在你配置沒有出錯的情況下。接下來,看看到底能不能真的支付。
完成大功告成,讓我想起了,最近流行的一句話,你這磨人的小妖精,微信支付!
希望能給你們帶來幫助~
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/93038.html
摘要:這是我第一次接觸微信支付,發現網上還是有很多同學在求助,了怎么辦是什么情況為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 凡是和錢打交道的事,沒有一樣是容易的。這是我第一次接觸微信支付,發現網上還是有很多同學在求助,XXX了怎么辦?XXX是什么情況?為了幫助更多的小伙伴脫離苦海,我決定寫下這次的踩坑之旅,給更多的人幫助。 介紹 微信支付方式分為刷卡支付、公眾號...
摘要:原文見我的博客,點擊進入使用開發微信公眾號下站點的填坑之旅本文為我創業過程中,開發項目的填坑之旅。作為一個技術宅男,我的項目是做一個微信公眾號,前后端全部自己搞定,不浪費國家一分錢。 原文見我的博客,點擊進入使用vue開發微信公眾號下SPA站點的填坑之旅 本文為我創業過程中,開發項目的填坑之旅。作為一個技術宅男,我的項目是做一個微信公眾號,前后端全部自己搞定,不浪費國家一分錢^_^。 ...
摘要:附微信支付流程微信支付流程和小程序的支付流程基本一致,需要注意兩點需要在微信商戶平臺配置支付目錄,只有跳轉到了支付目錄的地址,才能發起微信支付。 我所在公司需要開發一款商城小程序,里面需要用到微信支付,我負責里面的下單功能,從小程序端到后臺的支付流程都是我自己開發的,由于我們組沒有人有開發微信支付的經驗,很多東西都還不怎么明白,但是沒辦法,只能我自己琢磨,寫完之后總感覺有bug,但是不...
摘要:直到今天,突然看到一個有意思的微信小游戲。后來試了幾次之后才發現,這個小游戲比較刁,不僅做了微信的登錄授權,而且做了手機端訪問的判斷,更甚至竟然用的還是協議的網頁。調用的目標發生了異常。 記一次使用Fiddler抓包工具抓取Https協議數據的踩坑過程 前言 記得從剛入門前端第一天開始,當時的師傅就跟我介紹了一個可以抓取一些必須要在微信瀏覽器打開的鏈接的工具Fiddler,主要用來抓取...
閱讀 2027·2023-04-26 01:33
閱讀 1659·2023-04-26 00:52
閱讀 1035·2021-11-18 13:14
閱讀 5393·2021-09-26 10:18
閱讀 2901·2021-09-22 15:52
閱讀 1488·2019-08-29 17:15
閱讀 3016·2019-08-29 16:11
閱讀 1038·2019-08-29 16:11