Android 支付寶與微信支付

標(biāo)簽:【Android】第三方

目錄

[TOC]

目錄

開(kāi)始前要知道的:
調(diào)用第三方的支付真的不難膏孟!
建議大家開(kāi)發(fā)時(shí)鹃锈,先把兩張流程圖仔細(xì)看一遍,相信對(duì)大家一定有幫助宪萄;最后就是艺谆,多翻看開(kāi)發(fā)文檔!

一雨膨、支付寶支付

1. 支付寶支付流程圖

支付寶支付流程.png

2. 集成前準(zhǔn)備

  1. 注冊(cè)擂涛、登錄 螞蟻金服開(kāi)放平臺(tái) 【運(yùn)營(yíng)搞】
  2. 創(chuàng)建應(yīng)用,添加APP支付功能
  3. 找到APP支付開(kāi)發(fā)文檔聊记,下載 SDK&Demo

3. 開(kāi)始集成

1. 導(dǎo)包

在SDK中找到j(luò)ar包,導(dǎo)入自己的工程


支付寶jar包.png

2. 配置清單文件

<!--權(quán)限-->
<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" />
 <!-- 支付寶支付 -->
<activity
    android:name="com.alipay.sdk.app.H5PayActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind"
    android:windowSoftInputMode="adjustResize|stateHidden">
</activity>
<activity
    android:name="com.alipay.sdk.auth.AuthActivity"
    android:configChanges="orientation|keyboardHidden|navigation"
    android:exported="false"
    android:screenOrientation="behind">
</activity>

3. 請(qǐng)求接口獲取簽名恢暖,調(diào)用SDK啟動(dòng)支付寶支付

解釋一下:這里獲取簽名信息排监,就是請(qǐng)求后臺(tái)接口,上傳商品ID杰捂,單價(jià)舆床,數(shù)量等,我這里只傳遞給后臺(tái)一個(gè)訂單ID嫁佳,是因?yàn)槲以谇懊嫣峤挥唵螘r(shí)已經(jīng)將訂單信息傳遞

private static final int SDK_PAY_FLAG = 1;  //支付寶支付消息標(biāo)識(shí)


// 支付寶支付點(diǎn)擊調(diào)用此方法挨队,獲取簽名
// 這一步,和后臺(tái)協(xié)商好傳遞哪些參數(shù)就行蒿往,主要就是根據(jù)一定規(guī)則拼接商品信息盛垦,返回簽名后的訂單信息
// 主要是后臺(tái)的工作
private void getSign() {
    HttpUtils.getOkHttpBuilder()
            .url(Constants.ALI_PAY)
            .addParams(Constants.ORDER_ID_PARAMS, orderId)
            .addParams(Constants.ACT_ORDER_TYPE, orderType)
            .tag(this.toString())
            .build()
            .connTimeOut(5000)
            .execute(new StringCallback() {
                @Override
                public void onError(Call call, Exception e) {
                    if (!call.isCanceled()) {//如果不是取消了網(wǎng)絡(luò)請(qǐng)求,再提示連接錯(cuò)誤
                        ToastUtil.showToast("網(wǎng)絡(luò)異常瓤漏,請(qǐng)稍后再試");
                    }
                }

                @Override
                public void onResponse(String response) {
                    GetSign getSign = JsonUtil.parseJsonToBean(response, GetSign.class);

                    if (getSign == null || getSign.head == null) {
                        ToastUtil.showToast("服務(wù)器繁忙腾夯,請(qǐng)重試");
                        return;
                    }
                    if (!getSign.head.success) {
                        ToastUtil.showToast(getSign.head.msg);
                        return;
                    }

                    if (!TextUtils.isEmpty(getSign.body.sign)) {
                       // 異步調(diào)用支付寶SDK接口
                        pay(getSign.body.sign);
                    }

                }
            });
}
// 異步調(diào)用支付寶SDK支付接口
private void pay(final String payInfo) {
    Runnable payRunnable = new Runnable() {
        @Override
        public void run() {
            PayTask aliPay = new PayTask((Activity) mActivity);
            String result = aliPay.pay(payInfo, true);

            Message msg = new Message();
            msg.what = SDK_PAY_FLAG;
            msg.obj = result;
            mHandler.sendMessage(msg);
        }
    };

    // 必須異步調(diào)用
    Thread payThread = new Thread(payRunnable);
    payThread.start();

}
// Handler
@SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
    @SuppressWarnings("unused")
    public void handleMessage(Message msg) {
        switch (msg.what) {
            case SDK_PAY_FLAG: {
                @SuppressWarnings("unchecked")
                PayResult payResult = new PayResult((Map<String, String>) msg.obj);

                LogUtil.ShowLog("payresult:"+payResult.toString());
                /**
                 對(duì)于支付結(jié)果颊埃,請(qǐng)商戶依賴服務(wù)端的異步通知結(jié)果。同步通知結(jié)果蝶俱,僅作為支付結(jié)束的通知班利。
                 */
                 // 同步返回需要驗(yàn)證的信息
                String resultInfo = payResult.getResult();
                String resultStatus = payResult.getResultStatus();
                 /*
                    9000——訂單支付成功
                    8000——正在處理中
                    4000——訂單支付失敗
                    5000——重復(fù)請(qǐng)求
                    6001——用戶中途取消
                    6002——網(wǎng)絡(luò)連接出錯(cuò)
                 */
                // 判斷resultStatus 
                if (TextUtils.equals(resultStatus, "9000")) {
                    // 該筆訂單是否真實(shí)支付成功,需要依賴服務(wù)端的異步通知榨呆。
                    ToastUtil.showToast("支付成功");
                    // 跳到成功頁(yè)
                    if ("3".equals(orderType)) {    //電話請(qǐng)教成功頁(yè)
                        Intent intent = new Intent(mActivity, BuyPhoneOrderSuccessActivity.class);
                        intent.putExtra(Constants.ORDER_ID, orderId);
                        intent.putExtra(Constants.ORDER_NO, orderNo);
                        intent.putExtra(Constants.PHONE_ORDER_SUCCESS, 1);
                        startActivity(intent);
                    } else {
                        mActivity.startActivity(new Intent(mActivity, ActOrderSuccessActivity.class).putExtra(Constants.ORDER_ID_PARAMS2, orderId));
                    }
                    finish();
                } else if(TextUtils.equals(resultStatus, "6001")) {
                    // 該筆訂單真實(shí)的支付結(jié)果罗标,需要依賴服務(wù)端的異步通知。
                    ToastUtil.showToast("支付取消");
                }else{
                    LogUtil.ShowLog("錯(cuò)誤碼:"+resultStatus);
                    ToastUtil.showToast("支付失敗");
                }
                break;
            }
        }
    };
};

以上积蜻,支付寶支付完成

二闯割、微信支付

1. 微信支付流程圖

微信支付流程.png

相比較而言,微信支付是要比支付寶麻煩一些浅侨,并且微信的開(kāi)發(fā)文檔個(gè)人也感覺(jué)寫(xiě)的比較亂纽谒,初次接觸會(huì)有些懵。

2. 集成前準(zhǔn)備

  1. 注冊(cè)如输、登錄微信開(kāi)發(fā)者平臺(tái)【運(yùn)營(yíng)搞】
  2. 注冊(cè)應(yīng)用鼓黔,得到APPID申請(qǐng)開(kāi)通微信支付,填寫(xiě)申請(qǐng)資料【運(yùn)營(yíng)搞】
  3. 找到 開(kāi)發(fā)者文檔 下載SDK

3.開(kāi)始集成

1. 導(dǎo)包

在SDK中找到j(luò)ar包不见,導(dǎo)入澳化,或直接添加依賴

compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:1.0.2' // 微信支付

2. 配置清單文件

<!--權(quán)限-->
<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"/>
 <!-- 微信支付 -->
<activity
    android:name=".wxapi.WXPayEntryActivity"
    android:exported="true"
    android:launchMode="singleTop"/>

3. 調(diào)用支付

 // 微信支付點(diǎn)擊調(diào)用此方法,同支付寶支付稳吮,和后臺(tái)協(xié)商好傳遞的參數(shù)缎谷,這一步就是請(qǐng)求后臺(tái)的接口,拼接訂單信息灶似,生成一個(gè)加密的預(yù)支付訂單列林,主要工作都在后臺(tái)
private void wxPay(){
    final IWXAPI mWxApi = WXAPIFactory.createWXAPI(mContext, Constants.WX_APP_ID, true);
    // 將該app注冊(cè)到微信
    mWxApi.registerApp(Constants.WX_APP_ID);
    // 判斷是否安裝客戶端
    if(!mWxApi.isWXAppInstalled()&& !mWxApi.isWXAppSupportAPI()){
     ToastUtil.showToast("請(qǐng)您先安裝微信客戶端!");
     return;
 }
    HttpUtils.getOkHttpBuilder()
            .url(Constants.WX_PAY)
            .addParams(Constants.ORDER_ID_PARAMS, orderId)
            .addParams(Constants.ACT_ORDER_TYPE, orderType)
            .tag(this.toString())
            .build()
            .connTimeOut(5000)
            .execute(new StringCallback() {
                @Override
                public void onError(Call call, Exception e) {
                    if (!call.isCanceled()) {//如果不是取消了網(wǎng)絡(luò)請(qǐng)求酪惭,再提示連接錯(cuò)誤
                        ToastUtil.showToast("網(wǎng)絡(luò)異常希痴,請(qǐng)稍后再試");
                    }
                }
                @Override
                public void onResponse(String response) {
                    if(response==null){
                        ToastUtil.showToast("服務(wù)器異常,請(qǐng)稍后重試");
                    }

                    GetPreOrder getPreOrder = JsonUtil.parseJsonToBean(response, GetPreOrder.class);
                    if (getPreOrder == null || getPreOrder.head == null) {
                        ToastUtil.showToast("服務(wù)器異常春感,請(qǐng)稍后重試");
                        return;
                    }

                    if (!getPreOrder.head.success) {
                        ToastUtil.showToast(getPreOrder.head.msg);
                        return;
                    }

                    if (!TextUtils.isEmpty(getPreOrder.body.pre_order)) {
                        if (mWxApi != null) {
                            PayReq req = new PayReq();
                            req.appId = Constants.WX_APP_ID;// 微信開(kāi)放平臺(tái)審核通過(guò)的應(yīng)用APPID
                            try {
                                JSONObject jsonObject = new JSONObject(getPreOrder.body.pre_order);
                                req.partnerId = jsonObject.getString("partnerid");// 微信支付分配的商戶號(hào)
                                req.prepayId = jsonObject.getString("prepayid");// 預(yù)支付訂單號(hào)砌创,app服務(wù)器調(diào)用“統(tǒng)一下單”接口獲取
                                req.nonceStr = jsonObject.getString("noncestr");// 隨機(jī)字符串,不長(zhǎng)于32位
                                req.timeStamp = jsonObject.getString("timestamp");// 時(shí)間戳
                                req.packageValue = jsonObject.getString("package");// 固定值Sign=WXPay鲫懒,可以直接寫(xiě)死嫩实,服務(wù)器返回的也是這個(gè)固定值
                                req.sign = jsonObject.getString("sign");// 簽名,
                            } catch (JSONException e) {
                                e.printStackTrace();
                                LogUtil.ShowLog(e.toString());
                            }
                            // 調(diào)用微信SDK窥岩,發(fā)起支付甲献,回調(diào)WxPayEntryActivity
                            mWxApi.sendReq(req);
                        }
                    }

                }
            });
}

創(chuàng)建WxPayEntryActivity
在你的包名相應(yīng)目錄下新建一個(gè)wxapi目錄,并在該wxapi目錄下新增一個(gè)WxPayEntryActivity類(lèi)谦秧,可以直接復(fù)制Demo中的進(jìn)行修改

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;

import com.tencent.mm.opensdk.constants.ConstantsAPI;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import org.greenrobot.eventbus.EventBus;

/**
 * 微信支付回調(diào)
 *
 * @author StriveStay
 * @date 2017/3/3
 */
public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    
    private IWXAPI api;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        api = WXAPIFactory.createWXAPI(this, Constants.WX_APP_ID,true);
        api.handleIntent(getIntent(), this);
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        setIntent(intent);
        api.handleIntent(intent, this);
    }

    @Override
    public void onReq(BaseReq req) {
    }

    @Override
    public void onResp(BaseResp resp) {
        /*
          0 支付成功
         -1 發(fā)生錯(cuò)誤 可能的原因:簽名錯(cuò)誤竟纳、未注冊(cè)APPID撵溃、項(xiàng)目設(shè)置APPID不正確、注冊(cè)的APPID與設(shè)置的不匹配锥累、其他異常等缘挑。
         -2 用戶取消 發(fā)生場(chǎng)景:用戶不支付了,點(diǎn)擊取消桶略,返回APP语淘。
         */

        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            // 根據(jù)返回碼
            int code = resp.errCode;
            switch (code) {
                case 0:
                    // 去本地確認(rèn)支付結(jié)果
                    EventBus.getDefault().post(new WxPayEvent(true));
                    finish();
                    break;
                case -2:
                    ToastUtil.showToast("支付已取消");
                    finish();
                    break;
                default:
                    ToastUtil.showToast("支付失敗");
                    finish();
                    break;
            }
        }
    }
}

下面是和第一段代碼在一個(gè)Activity中的

/**
 * 接收微信支付回調(diào)成功后發(fā)出的通知消息,
 * 去本地服務(wù)器去確認(rèn)支付結(jié)果
 * @param event
 */
@Subscribe
public void onMessageEvent(WxPayEvent event){
    if(event!=null && event.isSuccess){
        String userId = SharePrefUtil.getString(this, SharePrefUtil.KEY.USER_ID, "");
        HttpUtils.getOkHttpBuilder()
                .url(Constants.WX_PAY_RESULT)
                .addParams(Constants.USER_ID,userId)
                .addParams(Constants.ORDER_ID_PARAMS,orderId)
                .addParams(Constants.ACT_ORDER_TYPE,orderType)
                .tag(this.toString())
                .build()
                .connTimeOut(5000)
                .execute(new StringCallback() {
                    @Override
                    public void onError(Call call, Exception e) {
                        showLoading(false);
                        showNoNetWork(true);
                        ToastUtil.showToast("網(wǎng)絡(luò)異常际歼,請(qǐng)稍后再試");
                        LogUtil.ShowLog(e.toString());
                    }

                    @Override
                    public void onResponse(String response) {
                        LogUtil.ShowLog(response);
                        if(response!=null){
                            WxPayResult wxPayResult = JsonUtil.parseJsonToBean(response,WxPayResult.class);

                            if(wxPayResult==null || wxPayResult.head==null || wxPayResult.body==null){
                                ToastUtil.showToast("網(wǎng)絡(luò)異常惶翻,請(qǐng)稍后再試");
                                return;
                            }
                            if(!wxPayResult.head.success){
                                ToastUtil.showToast(wxPayResult.head.msg);
                                return;
                            }

                            // 和后臺(tái)商定的order_status
                            switch (wxPayResult.body.order_status){
                                case "1":
                                    ToastUtil.showToast("支付失敗");
                                    break;
                                case "2":
                                    ToastUtil.showToast("支付成功");
                                    startActivity(new Intent(OnlinePayActivity.this,ActOrderSuccessActivity.class).putExtra(Constants.ORDER_ID_PARAMS,orderId));
                                    finish();
                                    break;
                                case "3":
                                    ToastUtil.showToast("支付已取消");
                                    break;
                            }

                        }
                    }
                });
    }
}

以上,微信支付完成鹅心。

三吕粗、 補(bǔ)充

1. 微信支付要運(yùn)行release版本,正式簽名旭愧,才能調(diào)起微信支付SDK

為了方便,可以如下設(shè)置

1. 在項(xiàng)目的build.gradle中添加singleConfigs配置簽名信息

signingConfigs {
  release {//發(fā)布版本的簽名配置
      storeFile file(props['KEYSTORE_FILE'])
      keyAlias props['KEY_ALIAS']
      storePassword props['KEYSTORE_PWD']
      keyPassword props['KEY_PWD']
  }
}

2. 在project structure中配置

設(shè)置.png

這樣就可以平時(shí)直接點(diǎn)擊運(yùn)行按鈕颅筋,運(yùn)行出的也是release版本,方便調(diào)試

2. 添加沒(méi)有安裝微信客戶端的校驗(yàn)

 if(!mWxApi.isWXAppInstalled()&& !mWxApi.isWXAppSupportAPI()){
            ToastUtil.showToast("請(qǐng)您先安裝微信客戶端输枯!");
            return;
        }

isWXAppInstalled和isWXAppSupportAPI來(lái)判斷微信客戶端是否安裝及安裝的版本是否支持微信開(kāi)放平臺(tái)

已添加到上面調(diào)用微信支付的代碼中

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末议泵,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子桃熄,更是在濱河造成了極大的恐慌先口,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,348評(píng)論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件瞳收,死亡現(xiàn)場(chǎng)離奇詭異碉京,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)螟深,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,122評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)收夸,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人血崭,你說(shuō)我怎么就攤上這事±遄疲” “怎么了夹纫?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,936評(píng)論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)设凹。 經(jīng)常有香客問(wèn)我舰讹,道長(zhǎng),這世上最難降的妖魔是什么闪朱? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,427評(píng)論 1 283
  • 正文 為了忘掉前任月匣,我火速辦了婚禮钻洒,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘锄开。我一直安慰自己素标,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,467評(píng)論 6 385
  • 文/花漫 我一把揭開(kāi)白布萍悴。 她就那樣靜靜地躺著头遭,像睡著了一般。 火紅的嫁衣襯著肌膚如雪癣诱。 梳的紋絲不亂的頭發(fā)上计维,一...
    開(kāi)封第一講書(shū)人閱讀 49,785評(píng)論 1 290
  • 那天,我揣著相機(jī)與錄音撕予,去河邊找鬼鲫惶。 笑死,一個(gè)胖子當(dāng)著我的面吹牛实抡,可吹牛的內(nèi)容都是我干的欠母。 我是一名探鬼主播,決...
    沈念sama閱讀 38,931評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼澜术,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼艺蝴!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起鸟废,我...
    開(kāi)封第一講書(shū)人閱讀 37,696評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤猜敢,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后盒延,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體缩擂,經(jīng)...
    沈念sama閱讀 44,141評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,483評(píng)論 2 327
  • 正文 我和宋清朗相戀三年添寺,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了胯盯。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,625評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡计露,死狀恐怖博脑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情票罐,我是刑警寧澤叉趣,帶...
    沈念sama閱讀 34,291評(píng)論 4 329
  • 正文 年R本政府宣布,位于F島的核電站该押,受9級(jí)特大地震影響疗杉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蚕礼,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,892評(píng)論 3 312
  • 文/蒙蒙 一烟具、第九天 我趴在偏房一處隱蔽的房頂上張望梢什。 院中可真熱鬧,春花似錦朝聋、人聲如沸嗡午。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,741評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)翼馆。三九已至,卻和暖如春金度,著一層夾襖步出監(jiān)牢的瞬間应媚,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,977評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工猜极, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留中姜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評(píng)論 2 360
  • 正文 我出身青樓跟伏,卻偏偏與公主長(zhǎng)得像丢胚,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子受扳,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,492評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容