微信支付-我遇到的那些问题
生活随笔
收集整理的這篇文章主要介紹了
微信支付-我遇到的那些问题
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
現(xiàn)在,越來越多公司,選擇借微信的勢來發(fā)展自己的平臺,進入工作沒多久,我也被告知了要對接微信支付的需求。原本以為這樣的對接,跟著文檔走,應該沒多大的難度的,可是后來,我才發(fā)現(xiàn),原來我太天真了。在此,留下印記,說說我在微信支付上面遇到的那些問題。 ? ? ?1、關(guān)于微信支付 ? ? ?首先說下微信支付。隨著微信的紅火,微信支付在第三方支付也占了一大塊地盤,越來越多的公司在自己的APP或者網(wǎng)站上集成了微信支付。從微信支付的官網(wǎng)https://pay.weixin.qq.com/index.php/home/login?return_url=/?可以看出,微信支付主要分為四大塊,公眾號支付、APP支付、掃碼支付(網(wǎng)站)、刷卡支付。工作上,我接觸到了前三種,遇到了各種各樣的問題。 ? ? ?2、關(guān)于官方文檔 ? ? ?對于開發(fā)者來說,對接這種第三方支付,看其官方文檔尤其重要。開發(fā)者可以通過官網(wǎng),查到對應不同支付模塊的官方文檔,但是,請大家注意,該文檔有待完善,完全照著文檔做,可能實現(xiàn)不了你的功能 ?3、微信支付流程 微信支付的流程,在微信支付官網(wǎng)上也有所顯示,這里更加泛化的說一下,其實微信支付需要的是集成了微信SDK的客戶端,客戶先通過客戶端瀏覽完成訂單,然后后臺首先在業(yè)務系統(tǒng)生成了訂單,訂單生成后,業(yè)務系統(tǒng)請求微信服務器,進行統(tǒng)一下單。統(tǒng)一下單完成后,微信返回相關(guān)信息,后臺就可以形成相應的支付二維碼或者是封裝出可以調(diào)起微信支付需要的信息。接下來,用戶只要通過掃一掃或者點擊確認支付,便可以調(diào)出微信支付。支付成功后,微信會給用戶發(fā)送信息,同時也會對業(yè)務系統(tǒng)指定的地址發(fā)送對應的回調(diào)信息,將支付結(jié)果告知微信。同時,微信支付信息也可以通過后臺直接請求微信支付來進行確認。 ? ? ? 4、微信支付相關(guān) ? ? ? ? ??首先,微信支付有一個最重要的過程,就是統(tǒng)一下單,簡單的說,開發(fā)者需要將業(yè)務系統(tǒng)中的訂單信息發(fā)送給微信,讓微信后臺形成在微信那邊的一個支付訂單。在向微信請求的時候,傳送的數(shù)據(jù)為xml格式,微信要求xml傳送的數(shù)據(jù)需要進行一次加密,然后將加密的字符串附加在xml中一起傳輸?shù)椒掌鞫?#xff0c;服務器端驗證通過之后才能進行下訂單操作。具體的算法說明地址https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=4_3 ? ? ? ? ? 以下,是基于java實現(xiàn)的加密算法: 1 /**
2 * 微信支付加密工具,需要加入key
3 */
4 public static String signature(Map<String, String> map, String key) {
5 Set<String> keySet = map.keySet();
6 String[] str = new String[map.size()];
7 StringBuilder tmp = new StringBuilder();
8 // 進行字典排序
9 str = keySet.toArray(str);
10 Arrays.sort(str);
11 for (int i = 0; i < str.length; i++) {
12 String t = str[i] + "=" + map.get(str[i]) + "&";
13 tmp.append(t);
14 }
15 if (StringUtils.isNotBlank(key)) {
16 tmp.append("key=" + key);
17 }
18 String tosend = tmp.toString();
19 MessageDigest md = null;
20 byte[] bytes = null;
21 try {
22
23 md = MessageDigest.getInstance("MD5");
24 bytes = md.digest(tosend.getBytes("utf-8"));
25 } catch (Exception e) {
26 e.printStackTrace();
27 }
28
29 String singe = byteToStr(bytes);
30 return singe.toUpperCase();
31
32 } 微信支付第一個問題,數(shù)據(jù)加密的key。這個坑在于不細心,微信支付有很多key,包括我們微信綁定時候自己輸入的key,還有微信給的隨機字符key,而這里,在用于加密的key,并不是我們微信公眾號中的 AppSecret,而是在微信支付商戶后臺設(shè)置的key,設(shè)置的位置為: key設(shè)置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設(shè)置-->API安全-->密鑰設(shè)置 如果不是使用該Key,哪怕是你的算法寫對了,數(shù)據(jù)傳到用戶那里,依然返回的是簽名錯誤。 ? ? ?PS:微信官方給出了一個驗證簽名準確性的工具,該工具地址為https://pay.weixin.qq.com/wiki/tools/signverify/,AnyWay,正如剛才說了,如果key設(shè)置的不正確,比如說使用了AppSecret ,那么,你會發(fā)現(xiàn),該工具的出的加密字符串和自己得出的一模一樣,然后當你發(fā)送給微信服務端的時候,永遠返回的是錯誤。 ? ? 微信支付第二個問題,post編碼問題。當組裝好數(shù)據(jù)后,需要通過POST的形式向微信服務器發(fā)送數(shù)據(jù)。可是,問題來了,微信的數(shù)據(jù)封裝的完全正確,key也設(shè)置正確了,在官方的驗證工具上驗證出來也是正確的,可是,微信總是提示簽名錯誤。這個問題出現(xiàn)在post請求的編碼問題上,遇到這個問題的情況是,在封裝數(shù)據(jù)的時候,xml里面加入了中文,然后每次請求就會報錯,可是如果中文去掉,下單成功。最后才發(fā)現(xiàn),原來POST的時候,沒有設(shè)置編碼,設(shè)置成為UTF8之后就沒事了。可是,返回的簽名錯誤,也真心難排查啊 ? ? ? 微信支付第三個問題,js-sdk調(diào)起支付控件。這一步時講在微信里面H5調(diào)起支付控件的。需要注意的是要在H5上面調(diào)出支付控件,第一件事需要在微信公眾要后臺添加指定域名允許該域名調(diào)起控件,否則,是不能調(diào)起的。設(shè)置的教程在這:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=7_3?。 ?????設(shè)置完成之后,接下來是通過js調(diào)起,在此吐槽一下,我第一次做的時候,是直接copy的官方的js下來改的,可是。。。。。。。官方的JS上面全角半角的字符混合,導致的別說是他的JS了,就是我自己寫的JS最后都沒調(diào)出來。。。。。然后,關(guān)于提示,,蘋果版還好,安卓版的微信,如果調(diào)不出控件,它一點反應都不會有的。。相對而言,蘋果版會有一個彈框提示,所以后期,只要出現(xiàn)問題,都先用蘋果測測看看出了什么錯。 ? ? ? 微信支付第四個問題,app端數(shù)據(jù)封裝。能夠統(tǒng)一下單了,這樣一來就是對數(shù)據(jù)封裝返回給前端了,這一部,還是需要進行簽名,按理來說,前面和前面采用的是同樣的方法,應該問題不大才對。確實,在web端和掃碼支付都沒多大問題,可是,app端問題來了。我在公司剛開始和安卓的同事調(diào)這個的時候,本來以為一個下午能搞定了。可是,卻不如我們所想。我們?nèi)坎捎玫氖枪俜浇o的要求進行封裝的數(shù)據(jù),我后臺統(tǒng)一下單完成之后,給到安卓,結(jié)果安卓死活調(diào)不出支付控件,而且一直都返回-1的結(jié)果,該結(jié)果,可以說一點用處都沒有。安卓端的同時調(diào)了好久,一直沒有找到解決方案,值得一說的是,它官方給的Demo是可以調(diào)出結(jié)果界面,可是也是調(diào)不出支付控件的。而且,他的java文件,utf-8和GBK兩種編碼混在一起的。最后說一下,為啥app調(diào)不出支付控件。 圖1 1 //網(wǎng)頁調(diào)起的時候
2 String time = Long.toString(System.currentTimeMillis());
3 back.put("appId", mchappid);
4 back.put("timeStamp", time);
5 back.put("nonceStr", "5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
6 back.put("package", "prepay_id=" + order.getPrepay_id());
7 back.put("signType", "MD5");
8 String sign2 = SignatureUtils.signature(back, wx_key);
9
10 JSONObject jsonObject = new JSONObject();
11 jsonObject.put("appId", mchappid);
12 jsonObject.put("timeStamp", time);
13 jsonObject.put("nonceStr", "5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
14 jsonObject.put("package", "prepay_id=" + order.getPrepay_id());
15 jsonObject.put("signType", "MD5");
16 jsonObject.put("paySign", sign2);
17
18 result.put("status", "success");
19 result.put("msg", "下單成功");
20 result.put("obj", jsonObject);
21 return result; 1 //APP調(diào)起的時候,請注意,安卓端不能用駝峰法,所有的key必須使用小寫
2 String time = Long.toString(System.currentTimeMillis());
3 back.put("appid", app_mchappid);
4 back.put("timestamp", time);
5 back.put("partnerid", app_mchid);
6 back.put("noncestr", "5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
7 back.put("prepayid", order.getPrepay_id());
8 back.put("package", "Sign=WXPay");
9 String sign2 = SignatureUtils.signature(back, wx_key);
10
11 JSONObject jsonObject = new JSONObject();
12 jsonObject.put("appid", app_mchappid);
13 jsonObject.put("timestamp", time);
14 jsonObject.put("partnerid", app_mchid);
15 jsonObject.put("noncestr", "5K8264ILTKCH16CQ2502SI8ZNMTM67VS");
16 jsonObject.put("prepayid", order.getPrepay_id());
17 //jsonObject.put("package", "Sign=WXPay");
18 jsonObject.put("sign", sign2);
19 result.put("status", "success");
20 result.put("msg", "下單成功");
21 result.put("obj", jsonObject);
22 return result;
至今為止遇到的問題大致如上,做下筆記,同時希望對同為開發(fā)的朋友有用 最后,附上本人在github上的一個基于java的微信支付后臺Demo?https://github.com/Seanid/wechatPay
?
如圖,圖1為微信官方文檔中安卓調(diào)起支付控件的示例代碼,接下來為web端調(diào)起支付控件時候進行加密的算法,最后為解決問題后返回給APP數(shù)據(jù)時候數(shù)據(jù)封裝的代碼。問題所在就是在于,它數(shù)據(jù)的封裝不像官網(wǎng)所說的使用駝峰法,app的時候,需要把所有的字符小寫,,,小寫,,,,,,,。還有,官方說的packageValue是錯的,要用package,就是因為這些錯,加密出來的數(shù)據(jù)是錯的,所以app端才調(diào)不出支付控件。在此,為我那個調(diào)到奔潰的同事默哀。至今為止遇到的問題大致如上,做下筆記,同時希望對同為開發(fā)的朋友有用 最后,附上本人在github上的一個基于java的微信支付后臺Demo?https://github.com/Seanid/wechatPay
轉(zhuǎn)載于:https://www.cnblogs.com/Seanit/p/5136551.html
總結(jié)
以上是生活随笔為你收集整理的微信支付-我遇到的那些问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Matlab使用技巧:Rapid Cod
- 下一篇: spring websocket Con