# 微信支付集成文档 ## 一、概述 ### 1.1 文档说明 本文档详细说明项目中微信支付的集成方式、配置方法、调用流程和注意事项。 ### 1.2 微信支付功能 - **支付方式**: 微信支付(WeChat Pay) - **SDK版本**: wechat-sdk-android-without-mta-1.0.2 - **集成状态**: 已集成,但部分代码需要完善 ### 1.3 微信配置信息 - **微信AppID**: wxaa49732bd3a29bec - **微信AppSecret**: 038324288450b5dcb610915fea7fb1af - **包名**: com.ruilaizi.service ## 二、依赖配置 ### 2.1 Gradle依赖 在 `app/build.gradle` 文件中已配置以下依赖: ```gradle dependencies { // 微信SDK(本地JAR) implementation files('libs/wechat-sdk-android-without-mta-1.0.2.jar') implementation files('libs/ShareSDK-Wechat-Core-2.8.3.jar') // 其他相关依赖 implementation 'com.squareup.retrofit2:retrofit:2.4.0' implementation 'com.squareup.retrofit2:adapter-rxjava2:2.3.0' implementation 'io.reactivex.rxjava2:rxjava:2.2.6' implementation 'io.reactivex.rxjava2:rxandroid:2.1.1' } ``` ### 2.2 本地JAR文件位置 ``` app/libs/ ├── wechat-sdk-android-without-mta-1.0.2.jar └── ShareSDK-Wechat-Core-2.8.3.jar ``` ## 三、AndroidManifest配置 ### 3.1 支付回调Activity配置 **重要**: 微信支付回调Activity必须配置在AndroidManifest.xml中,且包名路径必须为:`包名.wxapi.WXPayEntryActivity` **当前状态**: ⚠️ **WXPayEntryActivity未在AndroidManifest.xml中注册,需要添加配置** 需要在 `app/src/main/AndroidManifest.xml` 的 `` 标签内添加: ```xml ``` ### 3.2 权限配置 微信支付需要以下权限(已在AndroidManifest.xml中配置): ```xml ``` ## 四、核心代码实现 ### 4.1 微信支付回调Activity **文件路径**: `app/src/main/java/com/ruilaizi/service/wxapi/WXPayEntryActivity.java` **代码结构**: ```java package com.ruilaizi.service.wxapi; import com.ruilaizi.service.base.BaseActivity; 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; /** * 微信支付回调页 */ public class WXPayEntryActivity extends BaseActivity implements IWXAPIEventHandler { private IWXAPI api; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); initData(); } private void initData() { // ⚠️ 注意:当前代码中api初始化被注释,需要修复 // api = WXAPIFactory.createWXAPI(this, WXEntryActivity.WEIXIN_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) { // 微信发送的请求将回调到onReq方法 } @Override public void onResp(BaseResp resp) { // 支付结果回调 if (resp.errCode == 0) { toast("支付成功"); } else if (resp.errCode == -1) { toast("支付失败"); } else if (resp.errCode == -2) { toast("取消支付"); } // 发送广播通知支付结果 Intent intent = new Intent(); intent.setAction("com.antiphon.BroadcastReceiver"); intent.putExtra("payCode", resp.errCode); sendBroadcast(intent); finish(); } } ``` ### 4.2 支付结果错误码说明 | errCode | 说明 | 处理方式 | |---------|------|----------| | 0 | 支付成功 | 跳转到成功页面,更新订单状态 | | -1 | 支付失败 | 提示用户支付失败,可重试 | | -2 | 用户取消支付 | 提示用户已取消,返回订单页面 | ### 4.3 微信AppID配置 **文件路径**: `app/src/main/java/com/ruilaizi/service/wxapi/WXEntryActivity.java` ```java public class WXEntryActivity extends WechatHandlerActivity { // 微信AppID public static final String WEIXIN_APP_ID = "wxaa49732bd3a29bec"; // 微信AppSecret(用于登录,支付不需要) private static final String APP_SECRET = "038324288450b5dcb610915fea7fb1af"; } ``` ## 五、支付调用流程 ### 5.1 支付流程概述 ``` 1. 用户点击支付 ↓ 2. 调用后端接口,获取支付参数(prepay_id等) ↓ 3. 构建PayReq对象,设置支付参数 ↓ 4. 调用IWXAPI.sendReq()发起支付 ↓ 5. 跳转到微信支付界面 ↓ 6. 用户在微信中完成支付 ↓ 7. 微信回调到WXPayEntryActivity ↓ 8. 处理支付结果,发送广播通知 ↓ 9. 更新订单状态 ``` ### 5.2 发起支付代码示例 **注意**: 以下代码为示例,实际项目中需要根据后端接口返回的支付参数进行构建。 ```java import com.tencent.mm.opensdk.modelpay.PayReq; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; public class PaymentHelper { private static final String WEIXIN_APP_ID = "wxaa49732bd3a29bec"; /** * 发起微信支付 * * @param context 上下文 * @param appId 应用ID * @param partnerId 商户号 * @param prepayId 预支付交易会话ID * @param nonceStr 随机字符串 * @param timeStamp 时间戳 * @param packageValue 扩展字段,固定值"Sign=WXPay" * @param sign 签名 */ public static void pay(Context context, String appId, String partnerId, String prepayId, String nonceStr, String timeStamp, String packageValue, String sign) { // 1. 创建IWXAPI实例 IWXAPI api = WXAPIFactory.createWXAPI(context, WEIXIN_APP_ID, true); // 2. 注册到微信 api.registerApp(WEIXIN_APP_ID); // 3. 检查是否安装微信 if (!api.isWXAppInstalled()) { Toast.makeText(context, "未安装微信", Toast.LENGTH_SHORT).show(); return; } // 4. 检查微信版本是否支持支付 if (!api.isWXAppSupportAPI()) { Toast.makeText(context, "微信版本过低,不支持支付", Toast.LENGTH_SHORT).show(); return; } // 5. 构建支付请求 PayReq req = new PayReq(); req.appId = appId; // 应用ID req.partnerId = partnerId; // 商户号 req.prepayId = prepayId; // 预支付交易会话ID req.nonceStr = nonceStr; // 随机字符串 req.timeStamp = timeStamp; // 时间戳 req.packageValue = packageValue; // 扩展字段,固定值"Sign=WXPay" req.sign = sign; // 签名 // 6. 发起支付 boolean result = api.sendReq(req); if (!result) { Toast.makeText(context, "调起支付失败", Toast.LENGTH_SHORT).show(); } } } ``` ### 5.3 支付参数说明 | 参数名 | 说明 | 来源 | |--------|------|------| | appId | 应用ID | 固定值:wxaa49732bd3a29bec | | partnerId | 商户号 | 从后端接口获取 | | prepayId | 预支付交易会话ID | 从后端接口获取 | | nonceStr | 随机字符串 | 从后端接口获取 | | timeStamp | 时间戳 | 从后端接口获取 | | packageValue | 扩展字段 | 固定值:"Sign=WXPay" | | sign | 签名 | 从后端接口获取(需要客户端重新签名) | ## 六、支付结果处理 ### 6.1 广播接收器 支付结果通过广播发送,Action为:`com.antiphon.BroadcastReceiver` **接收支付结果的示例代码**: ```java import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; public class PaymentResultReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if ("com.antiphon.BroadcastReceiver".equals(intent.getAction())) { int payCode = intent.getIntExtra("payCode", -999); switch (payCode) { case 0: // 支付成功 handlePaymentSuccess(); break; case -1: // 支付失败 handlePaymentFailure(); break; case -2: // 用户取消 handlePaymentCancel(); break; } } } private void handlePaymentSuccess() { // 更新订单状态 // 跳转到支付成功页面 } private void handlePaymentFailure() { // 提示支付失败 } private void handlePaymentCancel() { // 提示用户已取消支付 } } ``` ### 6.2 注册广播接收器 在需要接收支付结果的Activity中注册: ```java private PaymentResultReceiver paymentReceiver; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 注册广播接收器 paymentReceiver = new PaymentResultReceiver(); IntentFilter filter = new IntentFilter("com.antiphon.BroadcastReceiver"); registerReceiver(paymentReceiver, filter); } @Override protected void onDestroy() { super.onDestroy(); // 注销广播接收器 if (paymentReceiver != null) { unregisterReceiver(paymentReceiver); } } ``` ## 七、需要修复的问题 ### 7.1 当前存在的问题 #### 问题1: WXPayEntryActivity未在AndroidManifest中注册 **影响**: 微信无法回调到应用,支付结果无法接收 **解决方案**: 在AndroidManifest.xml中添加Activity配置(见3.1节) #### 问题2: WXPayEntryActivity中api未初始化 **代码位置**: `WXPayEntryActivity.java` 第64行 **当前代码**: ```java private void initData() { // api = WXAPIFactory.createWXAPI(this, PayUtils.APP_ID); api.handleIntent(getIntent(), this); } ``` **问题**: api为null,会导致NullPointerException **解决方案**: 取消注释并修复: ```java private void initData() { api = WXAPIFactory.createWXAPI(this, WXEntryActivity.WEIXIN_APP_ID, true); api.handleIntent(getIntent(), this); } ``` #### 问题3: 缺少支付发起代码 **说明**: 项目中未找到实际调用微信支付的代码 **建议**: 需要创建支付工具类或在相关Activity中添加支付调用逻辑 ### 7.2 修复步骤 1. **修复WXPayEntryActivity初始化问题** - 打开 `WXPayEntryActivity.java` - 修复 `initData()` 方法中的api初始化 2. **添加AndroidManifest配置** - 打开 `AndroidManifest.xml` - 在 `` 标签内添加WXPayEntryActivity配置 3. **创建支付工具类** - 创建 `PaymentHelper.java` 或 `WeChatPayUtils.java` - 实现支付发起逻辑 4. **在订单页面集成支付** - 在订单确认页面添加支付按钮 - 调用后端接口获取支付参数 - 调用支付工具类发起支付 ## 八、后端接口对接 ### 8.1 获取支付参数接口 **接口说明**: 调用后端接口获取微信支付所需的参数 **请求示例**: ```java // 假设后端接口为:POST /api/order/createPay @POST("order/createPay") @FormUrlEncoded Observable> createPay( @Field("order_id") String orderId, @Field("amount") String amount ); ``` **响应数据模型**: ```java public class PayParams { private String appId; // 应用ID private String partnerId; // 商户号 private String prepayId; // 预支付交易会话ID private String nonceStr; // 随机字符串 private String timeStamp; // 时间戳 private String packageValue; // 扩展字段 private String sign; // 签名(可能需要客户端重新计算) // getter和setter方法 } ``` ### 8.2 支付结果通知接口 **说明**: 支付成功后,需要调用后端接口通知服务器更新订单状态 **接口示例**: ```java @POST("order/payNotify") @FormUrlEncoded Observable> payNotify( @Field("order_id") String orderId, @Field("pay_result") int payResult // 0:成功, -1:失败, -2:取消 ); ``` ## 九、测试验证 ### 9.1 测试环境准备 1. **微信开发者账号** - 注册微信开放平台账号 - 创建移动应用,获取AppID - 配置应用签名和包名 2. **测试设备** - 安装微信客户端 - 使用测试账号登录微信 3. **测试账号** - 微信支付测试账号(沙箱环境) - 或使用真实商户号进行测试 ### 9.2 测试步骤 1. **检查微信安装** ```java IWXAPI api = WXAPIFactory.createWXAPI(context, WEIXIN_APP_ID, true); if (!api.isWXAppInstalled()) { // 提示用户安装微信 } ``` 2. **测试支付流程** - 创建测试订单 - 点击支付按钮 - 验证是否跳转到微信支付界面 - 完成支付(或取消) - 验证是否回调到WXPayEntryActivity - 验证广播是否发送 - 验证订单状态是否更新 3. **测试支付结果处理** - 测试支付成功场景 - 测试支付失败场景 - 测试用户取消场景 ### 9.3 常见问题排查 #### 问题1: 无法调起微信支付 - 检查微信是否安装 - 检查微信版本是否支持支付 - 检查AppID是否正确 - 检查支付参数是否完整 #### 问题2: 支付后无法回调 - 检查WXPayEntryActivity是否在AndroidManifest中注册 - 检查包名路径是否正确(必须是 包名.wxapi.WXPayEntryActivity) - 检查Activity的exported属性是否为true #### 问题3: 签名错误 - 检查支付参数是否正确 - 检查签名算法是否正确 - 确认是否需要客户端重新计算签名 ## 十、安全注意事项 ### 10.1 签名安全 1. **服务端签名**: 支付签名应在服务端计算,客户端不应包含签名密钥 2. **参数校验**: 客户端应对服务端返回的参数进行基本校验 3. **防重放**: 时间戳和随机字符串用于防止重放攻击 ### 10.2 数据安全 1. **敏感信息**: AppSecret等敏感信息不应硬编码在客户端 2. **网络传输**: 使用HTTPS进行网络通信 3. **日志安全**: 生产环境不应打印支付相关的敏感信息 ### 10.3 支付结果验证 1. **服务端验证**: 支付结果应由服务端通过微信回调接口验证 2. **客户端验证**: 客户端仅作为展示,不应仅依赖客户端结果 3. **订单状态**: 最终订单状态以服务端为准 ## 十一、代码示例汇总 ### 11.1 完整的支付工具类 ```java package com.ruilaizi.service.utils; import android.content.Context; import android.widget.Toast; import com.tencent.mm.opensdk.modelpay.PayReq; import com.tencent.mm.opensdk.openapi.IWXAPI; import com.tencent.mm.opensdk.openapi.WXAPIFactory; import com.ruilaizi.service.wxapi.WXEntryActivity; public class WeChatPayUtils { private static final String WEIXIN_APP_ID = WXEntryActivity.WEIXIN_APP_ID; /** * 发起微信支付 */ public static void pay(Context context, PayParams params) { IWXAPI api = WXAPIFactory.createWXAPI(context, WEIXIN_APP_ID, true); api.registerApp(WEIXIN_APP_ID); if (!api.isWXAppInstalled()) { Toast.makeText(context, "未安装微信", Toast.LENGTH_SHORT).show(); return; } if (!api.isWXAppSupportAPI()) { Toast.makeText(context, "微信版本过低,不支持支付", Toast.LENGTH_SHORT).show(); return; } PayReq req = new PayReq(); req.appId = params.getAppId(); req.partnerId = params.getPartnerId(); req.prepayId = params.getPrepayId(); req.nonceStr = params.getNonceStr(); req.timeStamp = params.getTimeStamp(); req.packageValue = params.getPackageValue(); req.sign = params.getSign(); boolean result = api.sendReq(req); if (!result) { Toast.makeText(context, "调起支付失败", Toast.LENGTH_SHORT).show(); } } /** * 支付参数Bean */ public static class PayParams { private String appId; private String partnerId; private String prepayId; private String nonceStr; private String timeStamp; private String packageValue; private String sign; // getter和setter方法 // ... } } ``` ### 11.2 在Activity中使用支付 ```java public class OrderActivity extends BaseActivity { private void payOrder(String orderId) { // 1. 调用后端接口获取支付参数 ApiUtils.getApi() .createPay(orderId, "100") // 假设金额为100 .subscribeOn(Schedulers.io()) .observeOn(AndroidSchedulers.mainThread()) .subscribe(new Consumer>() { @Override public void accept(ResponseBean response) throws Exception { if (response.isSuccess()) { // 2. 发起支付 WeChatPayUtils.pay(OrderActivity.this, response.getData()); } else { Toast.makeText(OrderActivity.this, response.getMessage(), Toast.LENGTH_SHORT).show(); } } }, new Consumer() { @Override public void accept(Throwable throwable) throws Exception { Toast.makeText(OrderActivity.this, "获取支付参数失败", Toast.LENGTH_SHORT).show(); } }); } } ``` ## 十二、参考资料 ### 12.1 官方文档 - 微信支付开发文档: https://pay.weixin.qq.com/wiki/doc/apiv3/index.shtml - 微信开放平台: https://open.weixin.qq.com/ - Android SDK下载: https://open.weixin.qq.com/cgi-bin/frame?t=home/android_tmpl&lang=zh_CN ### 12.2 项目相关文件 - 支付回调Activity: `app/src/main/java/com/ruilaizi/service/wxapi/WXPayEntryActivity.java` - 微信登录Activity: `app/src/main/java/com/ruilaizi/service/wxapi/WXEntryActivity.java` - 微信API工具: `app/src/main/java/com/ruilaizi/service/network/WeChatApi.java` - 网络工具: `app/src/main/java/com/ruilaizi/service/network/ApiUtils.java` ### 12.3 相关配置 - AndroidManifest: `app/src/main/AndroidManifest.xml` - Gradle配置: `app/build.gradle` - 微信AppID: `WXEntryActivity.WEIXIN_APP_ID` ## 十三、总结 ### 13.1 集成要点 1. ✅ 已添加微信SDK依赖 2. ✅ 已创建支付回调Activity 3. ⚠️ 需要修复WXPayEntryActivity初始化问题 4. ⚠️ 需要在AndroidManifest中注册WXPayEntryActivity 5. ⚠️ 需要创建支付工具类实现支付发起逻辑 6. ⚠️ 需要在订单页面集成支付功能 7. ⚠️ 需要实现支付结果广播接收器 ### 13.2 下一步工作 1. 修复WXPayEntryActivity中的bug 2. 添加AndroidManifest配置 3. 创建支付工具类 4. 对接后端支付接口 5. 在订单页面集成支付 6. 实现支付结果处理 7. 进行支付功能测试 --- **文档版本**: 1.0 **最后更新**: 2025年1月 **项目路径**: D:\androidPj\peizhen **适用版本**: Android SDK 26+, 微信SDK 1.0.2