Android app集成微信支付

  • 鉴于微信支付的文档入口不太容易找到、以及文档中有些逻辑不通或者容易产生歧义或者缺失一些信息的情况,记录下此次接入的流程和需要关注的一些点。
  • 使用的是app支付-> APP支付产品介绍
  • android 支付页面 启动模式_android 支付页面 启动模式

  • 首先阅读介绍等,了解一些基础的概念和建立共识,大体的在脑中组织微信支付的框架。
  • APP支付接入前准备注册申请id等。需要Android程序员提供的信息或者前提条件:
  1. 包名和签名(小写md5字符串,通过keytool或者jeb等逆向软件或者微信提供的apk获取)。
  2. 目前是2023/1/18,可能是从22年开始app必须先上架应用商店,才能申请微信支付。
  • 支付后端程序员可参考:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml。

APP支付开发指引

  • 参考:https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_2.shtml。但是这个文档中没有详细的接入Android sdk的部分,多是介绍服务端、iOS、Android下单的这个过程。
  • Android sdk接入指南 核心如下:

集成sdk

  • Android studio添加Maven Central仓库,引用sdk:‘com.tencent.mm.opensdk:wechat-sdk-android:+’。未找到明确的说明wechat-sdk-android-without-mta等一些版本的区别。
  • studio提示替换成版本号,但是根据提示替换后只是把"+“号给去掉了,反而引用不到sdk了。又不确定是否当前本地的就是最新版本,所以也没有填入具体版本号(可以通过Project Structure->Dependencis查询最新版本号)。找官方文档也是指定用”+"号:https://developers.weixin.qq.com/doc/oplatform/Mobile_App/Access_Guide/Android.html。(这个studio的警告可以忽略,只是提醒如果指定加号会自动获取最新版本,可能产生版本依赖的问题。)
  • 查看本地的C:\Users\xx.gradle\caches\modules-2\files-2.1\com.tencent.mm.opensdk\wechat-sdk-android\6.8.18\xmd5\wechat-sdk-android-6.8.18.aar: 带了proguard.txt,应该不用再手动配置混淆了。studio查看的不显示proguard.txt,但看混淆后的mapping文件,应该是引用了proguard.txt,即混淆配置了、生效了,不需要手动配置。 但是比官方文档中的混淆配置少了"com.tencent.mm.sdk":
-keep class com.tencent.mm.sdk.** {
    *;
}

不确定是文档较久还是微信的程序员配置漏了。

调用sdk发起请求(支付、分享等基本类似)

  • 第一步是注册到微信:其中的动态注册广播的意义不明,也未查询到详细的介绍,暂时未注册广播。
// APP_ID 替换为你的应用从官方网站申请到的合法appID
private static final String APP_ID = "wx88888888";

// IWXAPI 是第三方 app 和微信通信的 openApi 接口
private IWXAPI api;

private regToWx() {
    // 通过 WXAPIFactory 工厂,获取 IWXAPI 的实例
    api = WXAPIFactory.createWXAPI(this, APP_ID, true);

    // 将应用的 appId 注册到微信
    api.registerApp(APP_ID);

   //建议动态监听微信启动广播进行注册到微信
  registerReceiver(new BroadcastReceiver() {
   @Override
   public void onReceive(Context context, Intent intent) {

     // 将该 app 注册到微信
    api.registerApp(Constants.APP_ID);
   }
  }, new IntentFilter(ConstantsAPI.ACTION_REFRESH_WXAPP));

}
  • 需要自己添加xml适配支持Android11启动微信(描述的很模糊,不确定targetSdkVersion 30指的是微信还是app还是二者皆是,所以保险起见必须适配了)。
<!-- 微信sdk用于Android11及targetSdkVersion>=30, -->
    <queries>
        <package android:name="com.tencent.mm" />
    </queries>
  • 文档中发起请求的例子是分享,所以我把支付请求放在下面,先写接收微信回调的请求(接收微信的请求及返回值),这部分也是分享、支付是共用的。
<activity
    android:name=".wxapi.WXEntryActivity"
    android:label="@string/app_name"
    android:theme="@android:style/Theme.Translucent.NoTitleBar"
    android:exported="true"
    android:taskAffinity="填写你的包名"
    android:launchMode="singleTask">
</activity>

其中的name必须是:包名+.wxapi.WXEntryActivity,taskAffinity也必须是包名(此项未测试,猜测是必须)。否则不会触发回调。WXEntryActivity(demo中没有设置setContentView,即没有布局文件。且onResp和onReq最后都主动调用了finish。)实现IWXAPIEventHandler接口,但是好像只会触发回调onResp,不会触发onReq(暂不确定,因为没有走完完成的支付流程,只是打开微信后返回,触发了-2:用户取消的事件)。

可以参考demo:https://developers.weixin.qq.com/doc/oplatform/Downloads/Android_Resource.html,页面中的点击下载:https://res.wx.qq.com/op_res/dl_hmdniBHBL1Jh2zHwHaZ-FM8YE9hTH6H6U7NKwbshR0QSgb7vH5aL4zwhtGqEt

  • SDK拉起支付:根据https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter2_5_2.shtml#part-6。
IWXAPI api;

  PayReq request = new PayReq();
  
  request.appId = "wxd930ea5d5a258f4f";
  
  request.partnerId = "1900000109";
  
  request.prepayId= "1101000000140415649af9fc314aa427",;
  
  request.packageValue = "Sign=WXPay";
  
  request.nonceStr= "1101000000140429eb40476f8896f4c9";
  
  request.timeStamp= "1398746574";
  
  request.sign= "7FFECB600D7157C5AA49810D2D8F28BC2811827B";
  
  api.sendReq(request);
  • api通过上面的注册到微信获取。所需的参数通过调用服务端(由后端调用微信支付的api生成订单:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_1.shtml,后端再返回给app订单数据)提供的接口获取。
  • 参数的说明见:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_4.shtml。
  • 支付成功、失败、取消支付会回调WXEntryActivity(实现IWXAPIEventHandler接口)的onResp,回调中errCode值列表:

名称

描述

解决方案

0

成功

展示成功页面

-1

错误

可能的原因:签名错误、未注册APPID、项目设置APPID不正确、注册的APPID与设置的不匹配、其他异常等。

-2

用户取消

无需处理。发生场景:用户不支付了,点击取消,返回APP。

  • 不能以上面的回调值作为真正支付成功的凭据,需要服务端确定是否成功并通知客户端。