Android微信支付流程及返回碼-1之坑

版權聲明:本文來自 Crocutax 的博客 , 轉載請注明出處 http://crocutax.com

之前做微信支付的時候,直接是以庫形式引入項目的,雖然一直覺得微信支付的開發(fā)文檔不太理想,但是印象中也沒有遇到什么大坑。

今天項目組的一個小伙伴突然告訴我微信支付一直失敗,根本調不起來支付頁面,onResp() 中的返回碼一直是-1,而且他好像已經(jīng)搞了好幾個小時了。于是我pull了一下項目代碼開始排查問題。最終發(fā)現(xiàn)問題有兩個:

  • 微信開放平臺上傳的簽名問題
  • Manifest文件中WXPayEntryActivity 的配置問題。

由于在處理這兩個問題的過程中,順便又回顧了一遍微信支付的流程,以前也沒有真正記錄下來過,所以這里記錄一下。

這里先把微信支付的返回碼貼一下,看看他們是有多么敷衍:

  • 0 成功,展示成功頁面
  • -1 錯誤,可能的原因:簽名錯誤、未注冊APPID、項目設置APPID不正確、注冊的APPID與設置的不匹配、其他異常等。
  • -2 用戶取消,無需處理。發(fā)生場景:用戶不支付了,點擊取消,返回APP。

相信絕大部分同學在處理微信支付這塊的時候,遇到的都是返回-1,然而看看關于-1的解釋,完全不給力。尤其是一個其他異常,真省事。。。 其實除了appId和簽名以外,還有很多其他原因會導致返回-1,這些都被微信劃為了其他異常而一筆帶過。

整體集成流程可以查看 微信支付App端開發(fā)步驟 ,反正他們不會告訴你有坑的,還是要自己踩-_-!

獲取AppID

微信開放平臺 申請開發(fā)應用,獲取APP的唯一標識APPID,比較簡單。之后通過 管理中心-應用詳情 即可查看自己的AppID。

向開放平臺提交包名和簽名

自己應用的包名就不用說了,比如com.weixin.test

簽名的話,要用到 簽名工具 ,是微信自己做的一個app,只有17KB,安裝在手機上,輸入已經(jīng)安裝在手機上的自己應用的包名,即可獲取該包名對應的簽名數(shù)據(jù)。

吐槽一下:簽名工具做的也太丑陋 + 不友好了,誰用誰知道。

注意

這里獲取簽名的時候,務必使用release版安裝在手機上,然后去獲取簽名,因為真正最終上線運營的時候是release版。debug和release兩個jks不一致,會導致最終簽名不一致,這種不一致會導致微信支付調用失敗。

如果嫌release簽名調試不方便,有兩種方法:

  1. 先向開放平臺提交debug版簽名,等待開發(fā)調試完畢,再換成release簽名
  2. 向開放平臺提交release版簽名,在gradle中配置一下,debug版本build時候也使用release的jks即可。

今天項目中遇到的其中一個坑就是在這里,簽名錯誤,完全跟技術無關。這種問題,再debug 3天也發(fā)現(xiàn)不了。

調用微信支付

微信支付的邏輯,大部分是有服務器端完成的,客戶端只需要在3個節(jié)點上進行處理:

1.通知服務器向微信下單

這個服務器就是自己的后臺,我們給后臺傳遞必要的參數(shù),比如商品id,價格等,由后臺向微信服務器下訂單,下單成功后,后臺會將訂單信息如prepayId等回調給我們。這里就是一個Android客戶端-后臺服務器 Request和Response的過程。

2.在服務器回調中調用微信支付

在后臺向微信服務器下單成功后,會將微信支付中需要使用到的一些字段數(shù)據(jù)回傳給我們,我們拿著該字段去調起微信支付即可。

//首先在調用之前,需要先在代碼中進行微信API注冊
IWXAPI wxApi= WXAPIFactory.createWXAPI(context, null);
// 將該app注冊到微信
wxApi.registerApp("your AppID");

//創(chuàng)建一個支付請求對象
PayReq request = new PayReq();

//開始數(shù)據(jù)封裝,這里一共有7個字段,都是必傳的
request.appId = "wxd930ea5d5a258f4f";
request.partnerId = "1900000109";
request.prepayId= "1101000000140415649af9fc314aa427",;
request.packageValue = "Sign=WXPay";
request.nonceStr= "1101000000140429eb40476f8896f4c9";
request.timeStamp= "1398746574";
request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
//發(fā)起請求
api.sendReq(req);

這里對幾個字段進行特殊說明:

  • appId : 直接定義為常量即可
  • packageValue :直接使用"Sign=WXPay",這是一個固定的值。
  • sign:如果服務器端已經(jīng)做過了簽名生成,那么這里直接拿著賦值給PayReq 對象即可;如果服務器端沒有做,那么還需要在本地進行簽名生成之后,再賦值。

這個本地簽名生成其實就是將上面的除了sign 以外的6個字段,拼接成key-value形式的字符串,再進行MD5加密,代碼如下:

//開始將6個字段進行數(shù)據(jù)封裝
List<WXModel> list = new LinkedList<>();
list.add(new WXModel("appid", payReq.appId));
list.add(new WXModel("noncestr", payReq.nonceStr));
list.add(new WXModel("package", payReq.packageValue));
list.add(new WXModel("partnerid", payReq.partnerId));
list.add(new WXModel("prepayid", payReq.prepayId));
list.add(new WXModel("timestamp", payReq.timeStamp));
payReq.sign = genAppSign(list);
//...發(fā)起請求即可

/**
 * 生成簽名
 */
private String genAppSign(List<WXModel> list) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < list.size(); i++) {
        sb.append(list.get(i).key);
        sb.append('=');
        sb.append(list.get(i).value);
        sb.append('&');
    }
    sb.append("key=");
    sb.append(Constant.WX_APP_KEY);
    String appSign = MD5Utils.getMessageDigest(sb.toString().getBytes()).toUpperCase();
    return appSign;
}

注意

  • 簽名工作一般由后臺完成,在生成簽名時,務必注意key的拼寫問題,比如必須拼appid而不是appId,必須拼prepayid而不是prepayId,這里跟上面PayReq 對象中字段的命名方式不一樣,用錯了也是照樣返回-1。自己曾經(jīng)作為server端忽略了這一點,坑了移動端的同事一把,耽誤了好幾個小時-_-!
  • 簽名所使用的是 微信商戶平臺API密鑰,而不是微信開放平臺AppSecret。 API密鑰在商戶平臺后臺-->API安全-->先安裝操作證書,后設置密鑰。見下圖:
微信支付密鑰.png

3.WXPayEntryActivity中接收回調

在該類的onResp() 方法中拿到微信支付的回調,然后去跟服務器再度確認支付結果。官方解釋如下:

在WXPayEntryActivity類中實現(xiàn)onResp函數(shù),支付完成后,微信APP會返回到商戶APP并回調onResp函數(shù),開發(fā)者需要在該函數(shù)中接收通知,判斷返回錯誤碼,如果支付成功則去后臺查詢支付結果再展示用戶實際支付結果。注意一定不能以客戶端返回作為用戶支付的結果,應以服務器端的接收的支付通知或查詢API返回的結果為準。

OK,到這里其實并不是就完事了。想正常接到支付成功的回調,除了上面一系列的AppId、應用簽名、微信支付請求等流程不能出錯外,這個類也得好好配置下才行,否則返回碼-1依然在等待著你。。。

類的位置

WXPayEntryActivity 類必須放在 包名.wxapi 下,比如com.weixin.test.wxapi.WXPayEntryActivity ,包名或類名不一致會造成無法回調。

Manifest文件中的聲明

WXPayEntryActivity 不是一個普通的類,而是要繼承Activity的一個View界面,所以必須在Manifest文件中聲明。那么這里坑又來了,如果僅僅只是在Manifest中聲明一下,在測試的時候會發(fā)現(xiàn),依然是返回-1。

需要這么配置才可以:

<activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop">

    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="your AppId"/>
    </intent-filter>

 </activity>

清空緩存

最后再說一個坑,如果經(jīng)過一系列的配置,發(fā)現(xiàn)完全都配置好了,可是微信支付依然返回-1。而此時我們可能又會回頭排查各個節(jié)點的問題,是配置問題?是自己的數(shù)據(jù)傳遞問題?到底哪里的bug?

其實這時候,清空下自己的應用緩存就可以了,通過 設置-應用管理-your app-清空緩存,進行緩存清理過后,立竿見影拿到成功的回調!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,908評論 6 541
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 99,324評論 3 429
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 178,018評論 0 383
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,675評論 1 317
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,417評論 6 412
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 55,783評論 1 329
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,779評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,960評論 0 290
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 49,522評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,267評論 3 358
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,471評論 1 374
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 39,009評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 44,698評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,099評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,386評論 1 294
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,204評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,436評論 2 378

推薦閱讀更多精彩內容