Files
peizhen/微信支付集成.txt

671 lines
20 KiB
Plaintext
Raw Permalink Normal View History

2025-12-19 23:45:38 +08:00
# 微信支付集成文档
## 一、概述
### 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` 的 `<application>` 标签内添加:
```xml
<!-- 微信支付回调Activity -->
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@android:style/Theme.Translucent.NoTitleBar" />
```
### 3.2 权限配置
微信支付需要以下权限已在AndroidManifest.xml中配置
```xml
<!-- 网络权限 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 其他必要权限 -->
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
```
## 四、核心代码实现
### 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`
- 在 `<application>` 标签内添加WXPayEntryActivity配置
3. **创建支付工具类**
- 创建 `PaymentHelper.java` 或 `WeChatPayUtils.java`
- 实现支付发起逻辑
4. **在订单页面集成支付**
- 在订单确认页面添加支付按钮
- 调用后端接口获取支付参数
- 调用支付工具类发起支付
## 八、后端接口对接
### 8.1 获取支付参数接口
**接口说明**: 调用后端接口获取微信支付所需的参数
**请求示例**:
```java
// 假设后端接口为POST /api/order/createPay
@POST("order/createPay")
@FormUrlEncoded
Observable<ResponseBean<PayParams>> 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<ResponseBean<OrderInfo>> 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<ResponseBean<PayParams>>() {
@Override
public void accept(ResponseBean<PayParams> 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<Throwable>() {
@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