Android應用接入微信支付實現支付功能

Android應用接入微信支付實現支付功能

記得很早以前公司項目中添加過移動支付這一塊, 包括 微信,支付寶,銀聯等第三方的整合。 但是後來懶於總結就沒留下什麼, 最近公司項目打算添加,所以打算簡單總結一下,記上一筆以備將來使用。 畢竟第三方的支付SDK , 一般定下了以後三五年不會改變。 閒話少說,開幹。 集成第三方SDK沒什麼難度,只要我們用心閱讀文檔和開發引導,集成起來再留點神,一切都不是問題。

申請準備材料

首先說一下,微信支付需要在開放平臺進行註冊,申請商戶資質。不是公衆平臺,另外這兩個平臺卻用了同一套賬號體系也就是說,有一個郵箱你註冊公衆平臺,開放平臺就不行了。
先給個官網鏈接https://pay.weixin.qq.com/index.php.

申請商戶的準備工作,需要申請商戶資質的材料也不會特殊,大概都需要以下幾種:

  • 單位營業執照彩色掃描件或數碼照片
  • 對公銀行賬戶(基本賬戶、一般賬戶均可)
  • 法定代表人的身份證彩色掃描件或數碼照片
    若爲代理人(即法人以外的公司代表)申請認證,需額外提供以下兩項材料
  • 代理人的身份證彩色掃描件或數碼照片
  • 委託書,委託書上必須蓋有單位公章或財務專用章(合同專用章、業務專用章等無效)下載委託書模版
  • 開發者資質審覈需要299元RMB/年.

申請過程按照微信官網提示進行操作即可,就不在贅述了。

SDK配置

集成過程很簡單,現在一般都使用gradle看一下配置

//下面依賴根據業務需要,任選其一
dependencies {
   //包含統計功能
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
   //不包含統計功能,不使用統計功能的話這個就足夠使用了。
   compile 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:+'
}

如果還是用eclipse的話, 就記得把libammsdk.jar 放到libs目錄中, 記得addToBuildPath

下邊是權限配置

<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"/>

下邊就看一下Manifest.xml 文檔配置。

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

這個文件就是支付完成之後微信通過Aidl回調傳送結果的類,所以exported屬性爲true。 另外這個文件的放置目錄一定要準確包名的路徑和AndroidManifest.xml文件中WXPayEntryActivity配置一致 ,微信回調找不到class 就會checkargs出錯,調不起微信。

接下來就看一下代碼吧:
官網SDKDemo下載解壓導入eclipse之後可以看到。一個很簡單的調用過程。
檢查當前的微信版本是否支持.發起req的時候一定要檢測一下sdk是否支持.

    Button checkPayBtn = (Button) findViewById(R.id.check_pay_btn);
        checkPayBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                boolean isPaySupported = api.getWXAppSupportAPI() >= Build.PAY_SUPPORTED_SDK_INT;
                Toast.makeText(PayActivity.this, String.valueOf(isPaySupported), Toast.LENGTH_SHORT).show();
            }
        });

下邊看一下發起支付請求的主調用方法

            try {
                Log.d("get server pay params:", content);
                JSONObject json = new JSONObject(content);
                if (null != json && !json.has("retcode")) {
                    PayReq req = new PayReq();
                    req.appId = Constants.APP_ID; 
                    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
                     Toast.makeText(PayActivity.this, "正常調起支付", Toast.LENGTH_SHORT).show();
                     api.sendReq(req);
                } else {
                    Log.d("PAY_GET", "返回錯誤" + json.getString("retmsg"));
                    Toast.makeText(PayActivity.this, "返回錯誤" + json.getString("retmsg"), Toast.LENGTH_SHORT).show();
                }

            } catch (Exception e) {
                Log.e("PAY_GET", "異常:" + e.getMessage());
                Toast.makeText(PayActivity.this, "異常:" + e.getMessage(), Toast.LENGTH_SHORT).show();
            }

在支付之前,如果應用沒有註冊到微信,應該先調用IWXMsg.registerApp將應用註冊到微信:

    api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
    api.registerApp(Constants.APP_ID);

createWXAPI這個方法,有個參數checkSignature,是否要檢查簽名。前期調試很好使,上線時候記得關掉。

下邊看一下支付完成之後的微信的回調

 public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {
    private static final String TAG = "MicroMsg.SDKSample.WXPayEntryActivity";
    private IWXAPI api;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.pay_result);
        api = WXAPIFactory.createWXAPI(this, Constants.APP_ID);
        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) {
        Log.d(TAG, "onPayFinish, errCode = " + resp.errCode);
        if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {
            AlertDialog.Builder builder = new AlertDialog.Builder(this);
            builder.setTitle("R.string.app_tip");
            builder.setMessage(getString(R.string.pay_result_callback_msg, String.valueOf(resp.errCode)));
            builder.show();
        }
    }

}

這裏有個方法可以根據onResp方法的BaseResp參數來判斷支付結果。 errCode =0 就是沒錯,支付成功。 -2 用戶取消支付, -1 支付出錯。

  • 這裏有個坑,我覺得有必要說一下,一般支付完畢之後可以告訴用戶是否成功, 如果產品讓添加一下支付的介面呢, 比如添加一下UI, 這時候就需要根據結果來初始化UI, 這裏的聲明週期方法 就是 onResp –> onNewIntent –> onCreate , 所以需要聲明一個字段提前保存支付狀態。然後再根據結果再onCreate中進行初始化UI元素,以及其他操作。

整體流程分析

說起流程分析最適合的就是弄個sequence, 看圖
微信支付流程圖
紅色的主體是我們自己的APP的和Server 。
這裏注意14步,支付驗證授權,完成支付交易之後,這裏觸發的是一個並行的流程。
* 微信後臺通知微信APP ,然後再回調我們的APP通知結果
* 微信後臺異步通知我們的後臺Server,我們Server再進行接收保存等處理。
另一個地方是對於支付的結果,我們自己可以查詢自己Server之前保存的結果,也可以Server調用微信的後臺API來查詢支付結果,這裏不再贅述。

注意事項

  • APPId一定要配置成自己的APPID,別忘改了。
  • 在SDK集成封裝完成之後,一定要用正式簽名來打包。否則就會出errorCode -1
  • WXPayEntryActivity這個類要放到wxapi的package下,並聲明export=true ,這個一般複製demo的話也不容易出錯。
  • 我們的支付結果一般認爲使用sdk提供的onResp回調就行了,可是移動端畢竟有很多不可控因素,所以在一些特殊的場合(斷網或者弱網,斷電,kill進程,等等)還是依賴我們自己Server的回調確認比較好。

總結

說到官網API不得不說和支付寶的根本沒法比,
首先就說Demo,支付寶提供的demo兩種版本,eclipse & gradle。 微信sdkdemo 只放的有eclipse 代碼已經很久沒有維護了,網絡請求還在主線程中寫着。
再說支付結構來說,微信是使用aidl進程間通信來回調WXPayEntryActivity這個類,使用上限制比較多,比如包名,簽名,類放置位置,甚至在調起微信的過程還得請求驗籤。 支付寶很簡單,靠的是強大的RSA2加密算法把自己的SDK嵌入到了調用者的APP中,調用十分方便,整潔。

另附完整支付寶微信集成源碼:https://github.com/samuelhehe/PayDemo

關於支付寶的集成看我的另一篇文章Android應用接入支付寶實現支付功能

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章