android中關於微信支付流程的總結


微信

一、前期准備

  • 在開放平台的“開發者引用登記界面”申請AppID,開通支付功能。只有在開放平台上通過審核並開通支付功能的應用才能集成微信支付的功能。
  • 下載微信終端開發工具包【網址:https://open.weixin.qq.com/cgi-bin/showdocument?action=dir_list&t=resource/res_list&verify=1&id=open1419319167&token=&lang=zh_CN
  • 或在微信支付商戶平台開發文檔頁面下載工具包和demo:https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1
  • 將工具包中libs目錄下的libammsdk.jar復制到你的libs目錄下,

    • 【eclipse項目】右擊選中“Configure Build Path…”—>“Add jars…”導入到工程中。如圖:
    • 【AndroidStudio項目】選中項目,按“F4”調出“Project Sructure”窗口,添加jar包到項目中。如圖:
      這里寫圖片描述

  • 在清單文件中添加權限:

            <uses-permission android:name="android.permission.INTERNET"/> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  • 添加混淆規則。在混淆配置文件proguard.cfg中,增加如下代碼,否則,將導致無法彈出發送第三方消息的確認框。


    -keep class com.tencent.mm.sdk.** {

    *;

    }

二、項目集成【微信支付目前的做法,凡是涉及簽名的操作均交由后台服務器去做】

  • 與微信建立通信聯系:在代碼中向微信APP注冊你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合適的地方進行注冊。筆者比較喜歡在調用微信支付的時候才進行注冊。

    final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
    msgApi.registerApp(Constants.APP_ID);
  • 將用戶選擇的訂單信息發送給后台服務器,由后台服務器調用微信支付API提供的統一下單接口等一系列和簽名相關的操作,簽名完成后,APP接收后台傳送回來的prepay_id、sign等數據。
  • 調用api.sendReq(req)發起支付。

    //從后台獲取返回的參數
    PayReq req = new PayReq();
    req.appId = json.getString("appid");
    req.partnerId = json.getString("partnerid");
    req.prepayId = json.getString("prepayid");
    req.nonceStr = json.getString("noncestr");
    req.timeStamp = json.getString("timestamp");
    req.packageValue = json.getString("package");
    req.sign = json.getString("sign");
    req.extData = "app data"; // optional
    // 發起支付。
    //在支付之前,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信
    api.sendReq(req);
  • 支付完成后,微信會同步返回一個支付結果給APP,並通過異步返回支付結果給后台服務器。
  • APP將支付結果發送給后台服務器,查詢支付結果, 獲取實際支付結果,並展示結果。

    附一張微信支付流程圖【摘自微信支付平台:)】

    這里寫圖片描述

三、項目集成【APP端請求統一下單接口、進行簽名,這是微信支付之前的做法,目前已經不支持,寫在這里只是為了紀念一下那段苦逼的日子】

  • 在調用微信支付的Activity的onCreate方法中實例化支付請求對象:

    req = new PayReq();
  • 與微信建立通信聯系:在代碼中向微信APP注冊你的APPId,可以在程序入口Activity的onCreate方法中,也可以在其他合適的地方進行注冊。筆者比較喜歡在調用微信支付的時候才進行注冊。

    final IWXAPI msgApi = WXAPIFactory.createWXAPI(context, null);
    msgApi.registerApp(Constants.APP_ID);
  • 調用統一下單接口,生成預支付訂單號prepay_id:
    (1). URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
    (2).開啟任務:

    GetPrepayIdTask getPrepayId = new GetPrepayIdTask();
    getPrepayId.execute();

    (3).在任務中調用統一下單接口,獲取prepay_id。

    private class GetPrepayIdTask extends
    AsyncTask<Void, Void, Map<String, String>> {

    private ProgressDialog dialog;

    @Override
    protected void onPreExecute() {

    dialog = ProgressDialog.show(context, getString(R.string.app_tip),
    getString(R.string.getting_prepayid));
    }

    @Override
    protected void onPostExecute(Map<String, String> result) {
    if (dialog != null) {
    dialog.dismiss();
    }
    resultunifiedorder = result;
    System.out.println("result=" + result);
    // 生成簽名參數
    genPayReq();
    // 調起支付接口
    sendPayReq();
    }

    @Override
    protected void onCancelled() {
    super.onCancelled();
    }

    @Override
    protected Map<String, String> doInBackground(Void... params) {

    // 統一下單接口
    String url = String
    //genProductArgs方法用來生成訂單詳細信息,在官方demo中有詳細代碼。
    String entity = genProductArgs();
    System.out.println("entity=" + entity);
    byte[] buf = Util.httpPost(url, entity);
    String content = new String(buf);
    System.out.println("content=" + content);
    Map<String, String> xml;
    try {
    xml = decodeXml(new String(content.getBytes("iso8859-1"),
    "utf-8"));
    return xml;
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
    return null;
    }
    }

    訂單詳細信息中需要注意的幾個參數:

    • notify_url:微信和我們后台建立鏈接的HTTP協議地址,在支付完成后,微信會通過這個地址向我們的后台服務器發送支付結果。
    • out_trade_no:這個參數是我們服務器生成的訂單編號。
    • spbill_create_ip:終端IP,我們服務器定好的。
    • total_fee:訂單金額,單位為分。
    • 返回訂單詳情時一定要注意中文編碼問題:String(xmlstring.toString().getBytes(), “ISO8859-1”)。
  • 任務執行完成后,將參數重新簽名。

    //在任務執行完成后調用這個方法。
    private void genPayReq() {
    req.appId = Constants.APP_ID;
    req.partnerId = Constants.MCH_ID;
    req.prepayId = resultunifiedorder.get("prepay_id");
    //參數值是固定的
    req.packageValue = "Sign=WXPay";
    req.nonceStr = genNonceStr();
    req.timeStamp = String.valueOf(genTimeStamp());
    List<NameValuePair> signParams = new LinkedList<NameValuePair>();
    signParams.add(new BasicNameValuePair("appid", req.appId));
    signParams.add(new BasicNameValuePair("noncestr", req.nonceStr));
    signParams.add(new BasicNameValuePair("package", req.packageValue));
    signParams.add(new BasicNameValuePair("partnerid", req.partnerId));
    signParams.add(new BasicNameValuePair("prepayid", req.prepayId));
    signParams.add(new BasicNameValuePair("timestamp", req.timeStamp));
    //再次簽名
    req.sign = genAppSign(signParams);
    }
  • 發起支付。

     msgApi.sendReq(req);
  • 回調支付結果
    在包名路徑下創建新的文件夾wxapi,並在此文件夾下創建WXPayEntryActivity類,注意:文件夾名稱和類名稱必須按照這樣命名,否則會導致無法回調。在類中實現onResp方法,支付完成后微信APP會返回到我們的APP上,並回調此方法。我們要做的就是在這個方法中接收通知,判斷返回碼,如果支付成功則將返回結果發送給后台服務器,查詢支付結果再向用戶展示實際支付結果。千萬要記住:不能以APP返回的結果作為用戶支付的結果,要以后台服務器接收的異步通知或從后台查詢得知的結果位准。

    這里寫圖片描述


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com