詳細介紹Android開發集成微信支付(二) --- 完整版本

今日推薦

經常閱讀博客是個好習慣
推薦鴻洋CSDN的博客

微信支付相關文章

詳細介紹Android開發集成微信支付(一) --- 僅客戶端版
詳細介紹Android開發集成微信支付(二) --- 完整版本

引言

本篇文章目的在于縮短集成微信支付的時間,讓您更快的接入微信支付,躲坑

我的CSDN博客地址 (由于csdn的圖片經常出現不顯示問題,以后就在簡書寫博客了)
GitHub由于近期較忙,正加急整理中,敬請期待...

常用鏈接

微信開放平臺 -- 注冊并創建應用
微信支付SDK下載集成 -- 如何集成sdk
微信開放平臺資源中心 -- 所有的資源
微信支付App開發文檔 -- 微信支付的開發文檔
微信支付業務流程 -- 里面有完成的支付流程
微信支付官方實例sample -- 下載官方示例
簽名驗證 -- 用于驗證一下你代碼生成的簽名是否正確
這里有一個獲取app簽名工具的鏈接(簽名工具下載地址) -- 用于獲取打包后App的應用簽名填寫到開放平臺上

目錄

  1. 開始前準備
    1.1 注冊微信開放平臺

  2. 理清業務流程

  3. 開始集成
    3.1 下載SDK和官方實例
    3.2 開始集成

開啟微信支付

這篇文章是一步一步的詳細介紹了如何集成微信支付(包括完整的客戶端和服務端該做的事情)如果你只是完成客戶端開發,請看詳細介紹Android開發集成微信支付(一) --- 僅客戶端版

ok ,Let's go!(這篇文章不只是代碼放在這,因為微信支付一直在改動,所以具體的每一步思路都在這,如果變動根據每一步去微信用最新的方式替換即可)

一: 開發前準備

1.1 注冊微信開放平臺

這一步的目的是在微信開放平臺注冊并創建應用,然后獲取微信支付需要用到的 APP_ID , Mch_Id(商戶號) , Mch_Key(商戶key,簽名的時候用)
首先我們點擊上面的常用鏈接中的微信開放平臺進入微信開放平臺的官網,也可以百度搜索微信開放平臺

微信開放平臺

接著點擊移動應用開發

創建應用

然后按照上圖的流程一步一步的創建好應用然后通過審核,然后獲取我們需要的各種ID

二:理清業務流程

首先微信開發文檔已經有了簡單的步驟介紹點擊查看

點擊常用鏈接的微信開放平臺資源中心,如下圖 包含了我們所有需要的東西


開放平臺資源中心

首先按照邏輯,我們應該先搞清楚微信支付的總體流程然后根據自己APP的業務需求制定適合自己的業務流程,然后才是下載SDK和集成代碼
首先我們 點擊進入開發文檔 查看業務流程 如下圖:

微信支付-業務流程

商戶系統和微信支付系統主要交互說明:
步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。
步驟2:商戶后臺收到用戶支付單,調用微信支付統一下單接口。參見【統一下單API】。
步驟3:統一下單接口返回正常的prepay_id,再按簽名規范重新生成簽名后,將數據傳輸給APP。參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay
步驟4:商戶APP調起微信支付。api參見本章節【app端開發步驟說明
步驟5:商戶后臺接收支付通知。api參見【支付結果通知API
步驟6:商戶后臺查詢支付結果。,api參見【查詢訂單API

總結一下就是:(商品類購買):
第一步:用戶在APP中選擇相應的商品和數量,提交給自己的后臺,然后后臺根據選擇的商品調用微信的統一下單API(這里需要第一次生成簽名),獲取prepay_id
第二步:后臺獲取到prepay_id之后需要再次生成一次簽名,(上面有詳細的簽名需要的字段)
第三步:后臺將簽名好的字段和客戶端需要調起微信需要的字段傳給客戶端
第四步:客戶端調起微信支付,并接收支付結果(本地回調,不可信),然后去后臺查詢支付結果,拿到微信支付的真實結果(后臺會收到微信的支付結果通知,也可以去調用微信的支付結果)

三:開始集成

具體的流程搞清楚了,現在我們開始一步一步來集成微信支付

3.1 下載微信支付SDK和官方實例代碼

首先我們先去下載SDK和官方實例 (記得之前微信的sdk還是要打包下載的,現在微信支付改版成為了托管到了JCenter上了,直接可以在gradle中添加依賴就可以了)

在build.gradle文件中,添加如下依賴即可:
dependencies {
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
}
或
dependencies {
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}
(其中,前者包含統計功能)

添加好依賴,就ok了
接著我們去下載官方實例代碼,1.是可以看里面的具體流程2.是可以直接拷貝里面的工具類和代碼
下載好之后解壓,并在AndroidStudio中open,打開之后發現只包含微信分享和一些其他的例子,并不包含微信支付(最新版的已經將微信支付的實例代碼去除,需要到微信APP支付Android開發文檔 里面下載)

解壓
示例的項目結構

打開之后可能會有報錯,我們不用管,因為我們不用運行,只是看一下里面有用的代碼,最新版微信的實例代碼已經將微信支付的實例去除,需要下載的話需要到微信APP支付Android開發文檔 -- SDK下載里面去Download
下載完成 打開是這樣的:

示例的項目結構

這里 wxapi/WXPayEntryActivity 是微信支付的回調頁面 ,這個頁面必須在 包名/wxapi 之下 所以直接把這個文件復制到我們工程中

MD5是一個工具類也復制到自己的項目中,需要用

public class MD5 {
    private MD5() {}    
    public final static String getMessageDigest(byte[] buffer) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("MD5");
            mdTemp.update(buffer);
            byte[] md = mdTemp.digest();
            int j = md.length;
            char str[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                str[k++] = hexDigits[byte0 >>> 4 & 0xf];
                str[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(str);
        } catch (Exception e) {
            return null;
        }
    }
  }

PayActivity中有調起微信支付的代碼可以參考

3.2 開始集成(寫代碼)

改集成也集成好了,流程也弄清楚了,實例代碼也復制好了,這樣就可以按照微信支付Android開發文檔一步一步的開始寫代碼就ok了
微信支付開發文檔

按照這個流程(因為這篇文章是所有的流程,所以全部都寫一遍):
商戶系統和微信支付系統主要交互說明:
步驟1:用戶在商戶APP中選擇商品,提交訂單,選擇微信支付。
步驟2:商戶后臺收到用戶支付單,調用微信支付統一下單接口。參見【統一下單API】。
步驟3:統一下單接口返回正常的prepay_id,再按簽名規范重新生成簽名后,將數據傳輸給APP。參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay
步驟4:商戶APP調起微信支付。api參見本章節【app端開發步驟說明
步驟5:商戶后臺接收支付通知。api參見【支付結果通知API
步驟6:商戶后臺查詢支付結果。,api參見【查詢訂單API

3.2.1 統一下單
首先初始化微信
/**
 * 初始化微信支付
 */
private void initWX() {
    if (wxApi == null) {
        wxApi = WXAPIFactory.createWXAPI(this, "你的微信APP_ID");
        wxApi.registerApp("你的微信APP_ID");
    }
}

查看統一下單API的文檔,查看具體的統一下單的鏈接地址,需要的參數

統一下單的鏈接地址:URL地址:https://api.mch.weixin.qq.com/pay/unifiedorder
post請求
參數是文檔里需要的,請求參數需要轉換為xml
舉例如下:

<xml>
<appid>wx2421b1c4370ec43b</appid>
<attach>支付測試</attach>
<body>APP支付測試</body>
<mch_id>10000100</mch_id>
<nonce_str>1add1a30ac87aa2db72f57a2375d8fec</nonce_str>
<notify_url>http://wxpay.wxutil.com/pub_v2/pay/notify.v2.php</notify_url>
<out_trade_no>1415659990</out_trade_no>
<spbill_create_ip>14.23.150.211</spbill_create_ip>
<total_fee>1</total_fee>
<trade_type>APP</trade_type>
<sign>0CB01533B8C1EF103065174F50BCA001</sign>
</xml>

定義一個統一下單JavaBean
public class WXPrePost {
    //必須帶的參數
    public String appid;//微信開放平臺審核通過的應用APPID
    public String mch_id;//微信支付分配的商戶號
    public String nonce_str;//隨機字符串,不長于32位。推薦隨機數生成算法
    public String sign;//簽名,詳見簽名生成算法
    public String body;//商品描述交易字段格式根據不同的應用場景按照以下格式:APP——需傳入應用市場上的APP名字-實際商品名稱,天天愛消除-游戲充值。
    public String out_trade_no;//商戶系統內部的訂單號,32個字符內、可包含字母, 其他說明見商戶訂單號
    public int total_fee;//訂單總金額,單位為分,詳見支付金額
    public String spbill_create_ip;//用戶端實際ip
    public String notify_url;//接收微信支付異步通知回調地址,通知url必須為直接可訪問的url,不能攜帶參數。
    public String trade_type;//支付類型

    //非必須攜帶的參數
    public String device_info;//終端設備號(門店號或收銀設備ID),默認請傳"WEB"
    public String detail;//商品名稱明細列表
    public String attach;//附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據
    public String fee_type;//符合ISO 4217標準的三位字母代碼,默認人民幣:CNY,其他值列表詳見貨幣類型
    public String time_start;//訂單生成時間,格式為yyyyMMddHHmmss,如2009年12月25日9點10分10秒表示為20091225091010。其他詳見時間規則
    public String time_expire;//訂單失效時間,格式為yyyyMMddHHmmss,如2009年12月27日9點10分10秒表示為20091227091010。其他詳見時間規則 注意:最短失效時間間隔必須大于5分鐘
    public String goods_tag;//商品標記,代金券或立減優惠功能的參數,說明詳見代金券或立減優惠
    public String limit_pay;//no_credit--指定不能使用信用卡支付
}
初始化統一下單的參數
    // 統一下單
    String url = "https://api.mch.weixin.qq.com/pay/unifiedorder";
    WXPrePost post = new WXPrePost();
    post.appid = "你的APP_ID";
    post.mch_id = "你的商戶號";
    post.nonce_str = genNonceStr();//隨機字符串  **1
    post.body = "介紹";
    post.detail = "打賞";
    post.out_trade_no = getTradeNo(); //商戶訂單號 **2
    post.total_fee = 1;//單位是分
    post.spbill_create_ip = getLocalIpAddress();//ip地址  **3
    post.notify_url = "http://www.weixin.qq.com/wxpay/pay.php";//這里是后臺接受支付結果通知的url地址
    post.trade_type = "APP";
    post.sign = genPackageSign(post);//簽名  **4

**1 : 隨機字符串,不長于32位。推薦隨機數生成算法
微信支付API接口協議中包含字段nonce_str,主要保證簽名不可預測。我們推薦生成隨機數算法如下:調用隨機數函數生成,將得到的值轉換為字符串。

private String genNonceStr() {
    Random random = new Random();
    //這里就用到了微信實例代碼中的MD5那個類
    return MD5.getMessageDigest(String.valueOf(random.nextInt(10000)).getBytes());
}

*2 商戶訂單號
商戶系統內部訂單號,要求32個字符內,只能是數字、大小寫字母_-|
@ ,且在同一個商戶號下唯一。詳見商戶訂單號
商戶支付的訂單號由商戶自定義生成,微信支付要求商戶訂單號保持唯一性(建議根據當前系統時間加隨機序列來生成訂單號)。重新發起一筆支付要使用原訂單號,避免重復支付;已支付過或已調用關單、撤銷(請見后文的API列表)的訂單號不能重新發起支付。

 public String getTradeNo() {
    return "這里可以是app名字" + genTimeStamp();
}
private long genTimeStamp() {
    return System.currentTimeMillis() / 1000;
}

**3 ip地址 (可以不獲取,直接給個默認,如果項目不要求的話)

public String getLocalIpAddress() {
    StringBuilder IFCONFIG = new StringBuilder();
    try {
        for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements(); ) {
            NetworkInterface intf = en.nextElement();
            for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements(); ) {
                InetAddress inetAddress = enumIpAddr.nextElement();
                if (!inetAddress.isLoopbackAddress() && !inetAddress.isLinkLocalAddress() && inetAddress.isSiteLocalAddress()) {
                    IFCONFIG.append(inetAddress.getHostAddress().toString() + ",");
                    break;
                }

            }
        }
        String[] split = IFCONFIG.toString().split(",");
        if (split != null && split.length > 0) {
            String ip = split[0];
            if (ip != null && ip.length() > 0) {
                return ip;
            } else {
                return "127.0.0.1";
            }
        } else {
            return "127.0.0.1";
        }
    } catch (SocketException ex) {
        return "127.0.0.1";

    }
}

**4 獲取簽名,詳見簽名生成算法 生成完之后 點擊這里驗證簽名 生成的簽名是否正確
簽名生成的通用步驟如下:
第一步,設所有發送或者接收到的數據為集合M,將集合M內非空參數值的參數按照參數名ASCII碼從小到大排序(字典序),使用URL鍵值對的格式(即key1=value1&key2=value2…)拼接成字符串stringA。
特別注意以下重要規則:
◆ 參數名ASCII碼從小到大排序(字典序);
◆ 如果參數的值為空不參與簽名;
◆ 參數名區分大小寫;
◆ 驗證調用返回或微信主動通知簽名時,傳送的sign參數不參與簽名,將生成的簽名與該sign值作校驗。
◆ 微信接口可能增加字段,驗證簽名時必須支持增加的擴展字段
第二步,在stringA最后拼接上key得到stringSignTemp字符串,并對stringSignTemp進行MD5運算,再將得到的字符串所有字符轉換為大寫,得到sign值signValue。
key設置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置

/**
 * 生成簽名
 *
 * @param params
 */
private String genPackageSign(WXPrePost params) {
    //拼接排序list
    List<NameValuePair> packageParams = new LinkedList<>();
    packageParams.add(new BasicNameValuePair("appid", "你的APP_ID"));
    packageParams.add(new BasicNameValuePair("body", params.body));
    packageParams.add(new BasicNameValuePair("detail", params.detail));
    packageParams.add(new BasicNameValuePair("mch_id", "你的商戶號"));
    packageParams.add(new BasicNameValuePair("nonce_str", params.nonce_str));
    packageParams.add(new BasicNameValuePair("notify_url", params.notify_url));
    packageParams.add(new BasicNameValuePair("out_trade_no", params.out_trade_no));
    packageParams.add(new BasicNameValuePair("spbill_create_ip", params.spbill_create_ip));
    packageParams.add(new BasicNameValuePair("total_fee", params.total_fee + ""));
    packageParams.add(new BasicNameValuePair("trade_type", params.trade_type));
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < packageParams.size(); i++) {
        sb.append(packageParams.get(i).getName());
        sb.append('=');
        sb.append(packageParams.get(i).getValue());
        sb.append('&');
    }
    sb.append("key=");
    sb.append("商戶key");//key設置路徑:微信商戶平臺(pay.weixin.qq.com)-->賬戶設置-->API安全-->密鑰設置
    //這里又用到了從實例代碼復制的MD5 可以去上面copy
    String packageSign = MD5.getMessageDigest(sb.toString().getBytes()).toUpperCase();
    return packageSign;
}
ps:

**如上已經生成了統一下單需要的簽名,生成完成之后可以去點擊這里驗證簽名 生成的簽名是否正確
**

上面可能會遇到問題:由于代碼寫完的時候是支持NameValuePair,前幾天升級之后,發現Android已經去掉了Apache的相關類,其中就有NameValuePair,這里解決方式有兩種:
一是 : 在Gradle中添加這兩個就可以接著使用NameValuePair
compile 'org.apache.httpcomponents:httpcore:4.4.1'
compile 'org.apache.httpcomponents:httpclient:4.5'
二是: 可以通過ContentValues 簡單實現一個類似的類,然后提供一個查詢的方法可以看這里

上面列表中參數的名稱像appid,body,mch_id一定要按照上面寫,大小寫也需要一樣,和官方文檔中一致才可以

將參數轉換為xml 并post請求統一下單

這里給一個將參數轉換為xml的方法,內部的參數用List<NameValuePair>封裝

private String toXml(List<NameValuePair> params) {
    StringBuilder sb = new StringBuilder();
    sb.append("<xml>");
    for (int i = 0; i < params.size(); i++) {
        sb.append("<" + params.get(i).getName() + ">");
        sb.append(params.get(i).getValue());
        sb.append("</" + params.get(i).getName() + ">");
    }
    sb.append("</xml>");
    return sb.toString();
}

參數列表在這里獲取

@NonNull
private List<NameValuePair> getFirstSignParams(WXPrePost params) {
    List<NameValuePair> packageParams = new LinkedList<>();
    packageParams.add(new BasicNameValuePair("appid", "你的APP_ID"));
    packageParams.add(new BasicNameValuePair("body", params.body));
    packageParams.add(new BasicNameValuePair("detail", params.detail));
    packageParams.add(new BasicNameValuePair("mch_id", "你的商戶號"));
    packageParams.add(new BasicNameValuePair("nonce_str", params.nonce_str));
    packageParams.add(new BasicNameValuePair("notify_url", params.notify_url));
    packageParams.add(new BasicNameValuePair("out_trade_no", params.out_trade_no));
    packageParams.add(new BasicNameValuePair("spbill_create_ip", params.spbill_create_ip));
    packageParams.add(new BasicNameValuePair("total_fee", params.total_fee + ""));
    packageParams.add(new BasicNameValuePair("trade_type", params.trade_type));
    packageParams.add(new BasicNameValuePair("sign", params.sign));
    return packageParams;
}

然后我們將上面初始化完成的WxPrePost 傳給這個方法然后調用toXml就可以獲取到統一下單的xml參數了
Next:有了統一下單的xml參數,我們就可以直接post請求url 將xml參數傳過去,返回一個String類型的字符串也是xml,解析即可獲取prepay_id,返回結果如下:

統一下單返回結果.png

只有return_code和result_code都為SUCCESS的時候才會有prepay_id,簡單的判斷一下然后解析xml
獲取我們需要的參數

public Map<String, String> decodeXml(String content) {

    try {
        Map<String, String> xml = new HashMap<>();
        XmlPullParser parser = Xml.newPullParser();
        parser.setInput(new StringReader(content));
        int event = parser.getEventType();
        while (event != XmlPullParser.END_DOCUMENT) {
            String nodeName = parser.getName();
            switch (event) {
                case XmlPullParser.START_DOCUMENT:
                    break;
                case XmlPullParser.START_TAG:
                    if (!"xml".equals(nodeName)) {
                        xml.put(nodeName, parser.nextText());
                    }
                    break;
                case XmlPullParser.END_TAG:
                    break;
            }
            event = parser.next();
        }
        return xml;
    } catch (Exception e) {
    }
    return null;
}

我們將解析出來的xml放入map中,然后遍歷一下獲取我們再次簽名需要的prepay_id , nonce_str , appid

            //判斷是否成功
            //...
            //再次簽名(參與簽名的字段有 :Appid partnerId prepayId nonceStr TimeStamp package)
            String appId = "";
            String prepayId = "";
            String nonceStr = "";
            for (Map.Entry<String, String> entry : stringMap.entrySet()) {
                if ("appid".equals(entry.getKey())) {
                    appId = entry.getValue();
                } else if ("prepay_id".equals(entry.getKey())) {
                    prepayId = entry.getValue();
                } else if ("nonce_str".equals(entry.getKey())) {
                    nonceStr = entry.getValue();
                }
            }
            //有可能會有解析失敗的情況 ,需要判斷
            //...

到這里統一下單就結束了,接下來就是再次簽名獲取調起微信支付的參數

3.2.2 第二次簽名

上一步已經獲取到了再次簽名的參數,接下來再次簽名,按照相同的簽名規則

參與簽名的字段名為appId,partnerId,prepayId,nonceStr,timeStamp,package。注意:package的值格式為Sign=WXPay

看一下上面的參數appId partnerId(商戶號),prepayId,nonceStr ,package 都已經有了 就差一個時間戳timeStamp

String TimeStamp = String.valueOf(genTimeStamp());
private long genTimeStamp() {
    return System.currentTimeMillis() / 1000;
}

獲取到所有參數之后,接著封裝到列表之后,進行第二次簽名

//獲取參數列表
private List<NameValuePair> getSecondSignParams(String appId, String prepayId, String nonceStr, String timeStamp) {
    //appId,partnerId,prepayId,nonceStr,timeStamp,package
    List<NameValuePair> packageParams = new LinkedList<>();
    packageParams.add(new BasicNameValuePair("appid", appId));
    packageParams.add(new BasicNameValuePair("noncestr", nonceStr));
    packageParams.add(new BasicNameValuePair("package", "Sign=WXPay"));
    packageParams.add(new BasicNameValuePair("partnerid", "你的商戶號"));
    packageParams.add(new BasicNameValuePair("prepayid", prepayId));
    packageParams.add(new BasicNameValuePair("timestamp", timeStamp));
    return packageParams;
}

//第二次簽名
private String genSecondPackageSign(List<NameValuePair> params) {
    //拼接排序list
    StringBuilder sb = new StringBuilder();

    for (int i = 0; i < params.size(); i++) {
        sb.append(params.get(i).getName());
        sb.append('=');
        sb.append(params.get(i).getValue());
        sb.append('&');
    }
    sb.append("key=");
    sb.append("商戶密鑰");//上面已經獲取
    String packageSign = getMessageDigest(sb.toString().getBytes()).toUpperCase();
    return packageSign;
}

//ok  獲取簽名
String secondPackageSign = genSecondPackageSign(getSecondSignParams(appId, prepayId, nonceStr, TimeStamp));

別忘了獲取簽名之后去驗證一下(驗證鏈接在上面),到這里調起微信需要的所有參數都已經獲取到了

3.2.3 調起微信 *

已經最后一步了,我們馬上就可以去驗證是不是能夠成功的調起微信并接收到微信支付的本地回調
調起微信支付,需要在開放平臺設置包名和簽名(這也是微信支付最大的一個坑,大部分人調不起微信基本都是這里的問題)
首先先看官方文檔 的詳細步驟

這里有一個獲取簽名工具的鏈接(簽名工具下載地址 安裝到手機上獲取自己app的簽名(打包之后安裝到手機上)

這里只能是你在開放平臺上填的簽名的app才可以調起微信,比如我打包之后用上面的簽名工具獲取app的簽名填入開放平臺,所以想要測試微信支付需要打包安裝到手機上才可以調起微信,如果發現沒有調起微信就這樣操作,雖然麻煩點,但是可以解決

//調起支付
            try {
                //一下所有的參數上面均獲取到了
                PayReq req = new PayReq();
                req.appId = "你的APP_ID";
                req.partnerId = "你的商戶號";
                req.prepayId = "你的prepayId";
                req.nonceStr = "你的nonceStr";
                req.timeStamp = "你的TimeStamp";

                req.packageValue = "Sign=WXPay";
                req.sign = "你的簽名";
                req.extData = "app data"; // optional
                // 在支付之前,如果應用沒有注冊到微信,應該先調用IWXMsg.registerApp將應用注冊到微信
                wxApi.sendReq(req);

            } catch (Exception e) {
                Log.e("PAY_GET", "異常:" + e.getMessage());
            }

到這里正常情況下肯定可以調起微信支付 ,如果出現了問題 1.簽名問題(去上面驗證下自己的簽名) 2.應用簽名問題請參考(3.2.3 調起微信 也就是上面)

3.3.4 接受微信支付的回調

到這一步說明你的微信已經成功調起,這里接受微信支付的回調

我們需要在應用的包名下建立wxapi的包名然后將實例中的WXPayEntryActivity.java復制過來
記住一定是項目的包名下建立wxapi包然后復制過來

微信回調項目目錄

然后再AndroidManifest中添加

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

在WXPayEntryActivity中就可以接受回調了

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //這里可以不給布局,也可以給個透明或者loading框 根據項目的需求
    setContentView(R.layout.act_pay);
    api = WXAPIFactory.createWXAPI(this, APP_ID);
    api.handleIntent(getIntent(), this);
}

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

以上兩個微信已經寫好,接下來是微信回調的方法

@Override
public void onResp(BaseResp resp) {
    Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);

    if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
        //根據下面的errCode表中 switch一下即可 
        //如果是0的話,就是成功,然后這里去服務器查詢具體的支付結果,注意服務器查詢的支付結果才是可靠地支付結果
    }
}
回調結果碼

支付回調可能遇到的問題:
1.如果項目中存在兩種即以上的支付(比如:商城購買 和 普通的打賞支付 或者其他),兩種支付完成后都會回調onResp但是之后的邏輯不一樣,所以我們需要手動的區分兩種支付(比如在支付前可以存一個變量標識)
2.支付成功回調之后,也就是errCode = 0 的時候,我們需要去服務器查詢結果,一般會需要給他們訂單號去查詢,但是微信回調之后不會給你訂單號,所以也需要你去本地存一下(或者其他更好的方式)

到這里微信支付就集成完了,當然代碼很粗糙可以在具體的細節細化,當然有其他更好的方式也可以提意見優化

希望這篇文章可以幫助到需要的人,如果還有其他問題或者補充可以聯系我~~~

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • Android 自定義View的各種姿勢1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 173,242評論 25 708
  • 準備工作: 需要公司的營業執照,稅務信息,等老板的身份證信息等,我記得,用這些材料,去支付寶注冊一個商家賬戶(審核...
    Hevin_Chen閱讀 6,822評論 0 9
  • 前言:本篇文章目的在于梳理知識,鞏固思想,學習總結。有什么好的建議,都可以留言。互相促進!總觀,微信支付,也沒心思...
    麥穗0615閱讀 10,087評論 8 70
  • 古典專欄14-2《一個幸福公式,測測自己》讀后反思 一、筆記 第一種人:自我實現型 既關注未來的意義和價值,也關注...
    丹丹自語閱讀 538評論 0 1
  • 圖文/水刀八木 身著彩橙衣,信步踏春門; 平生少思量,好問拂曉人。 果皮原料:橙皮 ..................
    落筆軒閱讀 626評論 8 3