Android 微信支付從后臺到前端流程

一、引入微信支付

微信支付需要以下三個參數(shù),具體獲取過程參考官方說明。

  1. App ID:在微信開放平臺創(chuàng)建應(yīng)用,配置應(yīng)用包名和簽名
  2. API KEY: 微信商戶平臺設(shè)置
  3. 商戶號: 微信商戶平臺商戶號

添加依賴包:
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+

二、后臺統(tǒng)一下單

App 端通過接口將訂單參數(shù)傳給后臺,后臺調(diào)用微信統(tǒng)一下單接口,獲得預(yù)支付訂單id(prepayid), 簽名后將參數(shù)返回給App端。

組裝統(tǒng)一下單參數(shù):

 private Map<String, String> getParams() {
        HashMap<String, String> params = new HashMap<>();
        params.put("appid", Const.APP_ID);//App ID
        params.put("body", "Test Goods");//商品名稱
        params.put("mch_id", Const.MCH_ID);//商戶號
        params.put("nonce_str", WXPayUtil.generateNonceStr());//隨機(jī)字符串
        params.put("notify_url", Const.NOTIFY_URL);//支付結(jié)果回調(diào)地址
        params.put("out_trade_no", WXPayUtil.generateUUID());//訂單號
        params.put("spbill_create_ip", "127.0.0.1");//  用戶端實際ip
        params.put("total_fee", "1");//金額
        params.put("trade_type", "APP");//支付類型
        params.put("sign", sign(params));//簽名
        return params;
    }

向微信后臺發(fā)送統(tǒng)一下單請求,參數(shù)是xml格式的:

public void getOrder() {
        Map<String, String> params = getParams();
        String xml = null;
        try {
            xml = WXPayUtil.mapToXml(params);
        } catch (Exception e) {
            e.printStackTrace();
        }
        if (TextUtils.isEmpty(xml)) {
            Log.i(TAG, "getOrder: 組裝參數(shù)出錯");
            return;
        }

        Log.i("統(tǒng)一下單參數(shù):", xml);
        MediaType XML = MediaType.parse("application/xml; charset=utf-8");
        RequestBody requestBody = RequestBody.create(XML, xml);
        final Request request = new Request.Builder().url(Const.UNIFIED_ORDER).post(requestBody).build();
        new OkHttpClient().newCall(request).enqueue(this);

    }

微信后臺返回的數(shù)據(jù)也是xml格式,將參數(shù)簽名后(注意字段名),返回給App端:

 private JSONObjecttoClient(String xml) throws Exception {
        Map<String, String> map = WXPayUtil.xmlToMap(xml);
        HashMap<String, String> params = new HashMap<>();
        params.put("appid", map.get("appid"));
        params.put("noncestr", map.get("nonce_str"));
        params.put("prepayid", map.get("prepay_id"));
        params.put("partnerid", map.get("mch_id"));
        params.put("package", Const.PKG_VALUE);//固定值 Sign=WXPay
        params.put("timestamp", String.valueOf(WXPayUtil.getCurrentTimestamp()));
        params.put("sign", sign(params));//簽名
        return new JSONObject(params);
    }

三、App端調(diào)起支付

從后臺拿到返回數(shù)據(jù)后,發(fā)起支付:

private void invokeClient(JSONObject object) {
        try {
            IWXAPI api = WXAPIFactory.createWXAPI(this, object.getString("appid"));
            PayReq request = new PayReq();
            request.appId = object.getString("appid");
            request.nonceStr = object.getString("noncestr");
            request.partnerId = object.getString("partnerid");
            request.prepayId = object.getString("prepayid");
            request.packageValue = object.getString("package");
            request.timeStamp = object.getString("timestamp");
            request.sign = object.getString("sign");
            api.sendReq(request);
        } catch (JSONException e) {
            e.printStackTrace();
        }
    }

處理支付結(jié)果:

在包名目錄下新建wxapi包,將官方Demo中的WXPayEntryActivity 放進(jìn)去,并在manifest 中注冊:

 <activity
            android:name=".wxapi.WXPayEntryActivity"
            android:exported="true"
            android:launchMode="singleTop"
            android:theme="@android:style/Theme.Translucent.NoTitleBar" />

WXPayEntryActivity 界面也可以自定義,但包名和類名不可更改。重寫onResp(BaseResp resp) 方法,進(jìn)行結(jié)果處理:

@Override
    public void onResp(BaseResp resp) {
        Log.i(TAG, "返回碼:" + resp.errCode + ",返回信息:" + resp.errStr);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            switch (resp.errCode) {
                case BaseResp.ErrCode.ERR_OK://成功
                    Toast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();
                    break;
                case BaseResp.ErrCode.ERR_USER_CANCEL://用戶取消
                    Toast.makeText(this, "支付取消", Toast.LENGTH_SHORT).show();
                    break;
                case BaseResp.ErrCode.ERR_COMM://錯誤
                    Toast.makeText(this, "支付出錯", Toast.LENGTH_SHORT).show();
                    break;
            }
        }
        finish();
    }

四、其他

  • 配置debug key: 在微信開放平臺創(chuàng)建應(yīng)用時,填入的簽名要與你運(yùn)行的App 簽名一致,否則無法調(diào)起支付,調(diào)試時可以將debug key 設(shè)置為正式的簽名key.

  • 關(guān)于簽名方法:簽名參數(shù)需要排序,最后加上API Key,進(jìn)行MD5加密,方法可以自己寫,但建議直接復(fù)制官方Demo 中的 WXPayUtil 類,里面有所有你需要的方法,這樣出錯時只需要檢查參數(shù).

  • 客戶端調(diào)起失敗,返回-1:檢查App Id,Api Key,商戶號,一般來講這幾個不可能出錯,那就要仔細(xì)檢查參與簽名的各項參數(shù)了,包括參數(shù)的字段名稱.

  • 以上代碼全部是在Android 端完成的,理論上來說整個支付過程都可以在App 端完成(實際上也可以,親測),但官方建議簽名加密過程由后臺完成,安全性考慮。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容