Android接入支付SDK

lsyh0673 7年前
   <p>最近公司项目做到支付模块,之前也做过,没整理成博客,这次整理一下。</p>    <h2><strong>微信支付</strong></h2>    <h3><strong>前期准备</strong></h3>    <ol>     <li>注册账号,创建应用,开通微信支付。</li>     <li>查看APP支付文档: <a href="/misc/goto?guid=4959727101509037925" rel="nofollow,noindex">https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=8_1</a></li>     <li>了解支付流程: <p style="text-align:center"><img src="https://simg.open-open.com/show/ad01b32cdd653bd8e49754904d54df7c.jpg"></p> </li>    </ol>    <h3><strong>接入SDK</strong></h3>    <ol>     <li>引入libs,下载 <a href="/misc/goto?guid=4959727101593585161" rel="nofollow,noindex">https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=11_1</a> ,并将libammsdk.jar放到libs文件夹下。</li>     <li>配置签名<br> 在debug下直接配置key,这样就可以在debug下调试了。 <pre>  <code class="language-java">signingConfigs {       debug {           storeFile file("你的keystore文件路径")           storePassword "xxx"           keyAlias "xxx"           keyPassword "xxx"       }       release {           storeFile file("你的keystore文件路径")           storePassword "xxx"           keyAlias "xxx"           keyPassword "xxx"       }  }  buildTypes {       debug {           signingConfig signingConfigs.debug       }       release {           signingConfig signingConfigs.release       }   }</code></pre> </li>     <li>创建WXPayEntryActivity<br> 在报名下创建如下图的Activity,demo里也有,WXPaEntryActivity是支付的回调,WXEntryActivity是微信登录和分享的回调。 <p style="text-align:center"><img src="https://simg.open-open.com/show/51dbf8b7716c7715aa1937a0d11be945.jpg"></p> </li>     <li>AndroidManifest.xml中注册 <pre>  <code class="language-java"><activity   android:name=".wxapi.WXPayEntryActivity"   android:exported="true"   android:launchMode="singleTop"   android:screenOrientation="portrait"   android:theme="@android:style/Theme.Translucent.NoTitleBar"   android:windowSoftInputMode="stateHidden"/></code></pre> </li>     <li>加入混淆 <pre>  <code class="language-java">-libraryjars libs/libammsdk.jar  -keep class com.tencent.** { *;}</code></pre> </li>    </ol>    <h3><strong>接口调用</strong></h3>    <pre>  <code class="language-java">/**   * 调用微信支付   * @param datas 微信支付数据   */  private void toWXPay(String datas) {      IWXAPI api = WXAPIFactory.createWXAPI(PayActivity.this, WX_APP_ID);      api.registerApp(WX_APP_ID);      try {          JSONObject jsonObject = new JSONObject(datas);          PayReq req = new PayReq();          req.appId = jsonObject.getString("appid");// 微信开放平台appid          req.nonceStr = jsonObject.getString("noncestr");// 随机字符串          req.packageValue = jsonObject.getString("package");// 支付内容          req.partnerId = jsonObject.getString("partnerid");// 财付通id          req.prepayId = jsonObject.getString("prepayid");// 微信预支付编号          req.sign = jsonObject.getString("sign");// 签名          req.timeStamp = jsonObject.getString("timestamp");// 时间戳          req.extData = "app data"; // optional          // 在支付之前,如果应用没有注册到微信,应该先调用IWXMsg.registerApp将应用注册到微信          api.sendReq(req);      } catch (JSONException e) {          e.printStackTrace();      }  }</code></pre>    <h3><strong>支付回调</strong></h3>    <pre>  <code class="language-java">public class WXPayEntryActivity extends Activity implements IWXAPIEventHandler {        private IWXAPI api;        @Override      public void onCreate(Bundle savedInstanceState) {          super.onCreate(savedInstanceState);          api = WXAPIFactory.createWXAPI(this, Config.WX_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) {          if (resp.getType() == ConstantsAPI.COMMAND_PAY_BY_WX) {              switch (resp.errCode) {                  case 0:                      Toast.makeText(this, "支付成功", Toast.LENGTH_SHORT).show();                      break;                  case -1:                      Toast.makeText(this, "支付失败,请检查", Toast.LENGTH_SHORT).show();                      break;                  case -2:                      Toast.makeText(this, "已取消支付", Toast.LENGTH_SHORT).show();                      break;                  default:                      Toast.makeText(this, "支付失败,请检查", Toast.LENGTH_SHORT).show();                      break;              }              finish();          }      }  }</code></pre>    <h3><strong>遇到的问题</strong></h3>    <ol>     <li> <p>未安装微信客户端的情况下使用,然后会发现提示 E/ActivityThread: Failed to find provider info for com.tencent.mm.sdk.plugin.provider ,因为微信没有html5页面能使用支付,所以我们必须要在使用支付之前做个判断,因为微信sdk有提供个参数可以判断,所以应该加上:</p> <pre>  <code class="language-java">private boolean isWXAppInstall() {       IWXAPI api = WXAPIFactory.createWXAPI(PayActivity.this, WX_APP_ID);       api.registerApp(WX_APP_ID);       boolean isWXAppInstalled = api.isWXAppInstalled() && api.isWXAppSupportAPI();       return isWXAppInstalled;  }  if (isWXAppInstall()) {   DialogUtil.showProDialog(PayActivity.this);   toWXPay(datas);  } else {   Toast.makeText(this, "未安装微信客户端", Toast.LENGTH_SHORT).show();  }</code></pre> </li>     <li> <p>Android7.0上会出现回调成功重复多次,这个待再次确认,可能是微信的bug。</p> </li>    </ol>    <h2><strong>支付宝支付</strong></h2>    <h3><strong>前期准备</strong></h3>    <ol>     <li>注册账号,创建应用,开通支付功能。</li>     <li>查看文档: <a href="https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7386797.0.0.Eky59h&treeId=59&articleId=103563&docType=1" rel="nofollow,noindex">支付文档</a></li>     <li>了解支付流程: <p style="text-align:center"><img src="https://simg.open-open.com/show/ae5e709ef9135edddbb31056db4117f2.jpg"></p> </li>    </ol>    <h3><strong>接入SDK</strong></h3>    <ol>     <li>引入libs,下载 <a href="https://doc.open.alipay.com/docs/doc.htm?spm=a219a.7629140.0.0.Q5gnm8&treeId=193&articleId=104509&docType=1" rel="nofollow,noindex">支付宝SDK及DEMO</a> ,并将alipaySdk-xx.jar包放到libs文件夹下</li>     <li>AndroidManifest.xml中注册 <pre>  <code class="language-java"><activity   android:name="com.alipay.sdk.app.H5PayActivity"   android:configChanges="orientation|keyboardHidden|navigation"   android:exported="false"   android:screenOrientation="behind"/>  <activity   android:name="com.alipay.sdk.auth.AuthActivity"   android:configChanges="orientation|keyboardHidden|navigation"   android:exported="false"   android:screenOrientation="behind"/></code></pre> </li>     <li>加入权限 <pre>  <code class="language-java"><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" /></code></pre> </li>     <li>加入混淆 <pre>  <code class="language-java">-libraryjars libs/alipaySdk-xx.jar  -keep class com.alipay.android.app.IAlixPay{*;}  -keep class com.alipay.android.app.IAlixPay$Stub{*;}  -keep class com.alipay.android.app.IRemoteServiceCallback{*;}  -keep class com.alipay.android.app.IRemoteServiceCallback$Stub{*;}  -keep class com.alipay.sdk.app.PayTask{ public *;}  -keep class com.alipay.sdk.app.AuthTask{ public *;}</code></pre> <h3><strong>接口调用</strong></h3> 支付宝的demo已经写得很明了易懂了,这里简单列出接口调用的主要代码,其他代码请看支付宝DEMO。 <pre>  <code class="language-java">/**  * 调取支付宝SDK  *  * @param payInfo 支付信息  */  private void alipay(final String payInfo) {   Runnable payRunnable = () -> {       PayTask alipay = new PayTask(PayActivity.this);       String result = alipay.pay(payInfo, true);       Message msg = new Message();       msg.what = SDK_PAY_FLAG;       msg.obj = result;       mHandler.sendMessage(msg);   };   Thread payThread = new Thread(payRunnable);   payThread.start();  }  /**  * 支付宝支付回调处理  */  @SuppressLint("HandlerLeak")  private Handler mHandler = new Handler() {   @SuppressWarnings("unused")   public void handleMessage(Message msg) {       switch (msg.what) {           case SDK_PAY_FLAG: {               PayResult payResult = new PayResult((String) msg.obj);               String resultInfo = payResult.getResult();// 同步返回需要验证的信息               String resultStatus = payResult.getResultStatus();               // 判断resultStatus 为“9000”则代表支付成功,具体状态码代表含义可参考接口文档               if (TextUtils.equals(resultStatus, "9000")) {                   Toast.makeText(PayActivity.this, "支付成功", Toast.LENGTH_SHORT).show();               } else {                   if (TextUtils.equals(resultStatus, "8000")) {                       Toast.makeText(PayActivity.this, "支付结果确认中", Toast.LENGTH_SHORT).show();                   } else {                       // 其他值就可以判断为支付失败,包括用户主动取消支付,或者系统返回的错误                       Toast.makeText(PayActivity.this, "支付失败", Toast.LENGTH_SHORT).show();                   }               }               break;           }           default:               break;       }   }  };</code></pre> <h3><strong>遇到的问题</strong></h3> </li>     <li>很容易遇到的问题就是支付参数遗漏,可以直接 查看文档</li>     <li>还会可能遇到支付错误,可以直接 查看文档</li>    </ol>    <p> </p>    <p>来自:http://www.jianshu.com/p/fcd1c36f6230</p>    <p> </p>