Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions NEW_TRANSFER_API_SUPPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
| **转账方式** | 批量转账 | 单笔转账 |
| **场景支持** | 基础场景 | 丰富场景(如佣金报酬等) |
| **撤销功能** | ❌ 不支持 | ✅ 支持 |
| **授权模式** | 仅需确认模式 | ✅ 支持免确认授权模式 |
| **适用范围** | 所有商户 | **新开通商户必须使用** |

### 2. 新版API功能列表
Expand All @@ -27,6 +28,30 @@
✅ **回调通知** - `parseTransferBillsNotifyResult()`
✅ **RSA加密** - 自动处理用户姓名加密
✅ **场景支持** - 支持多种转账场景ID
✅ **授权模式** - 支持免确认收款授权模式

### 3. 收款授权模式支持

**新增功能:免确认收款授权模式**

- **需确认收款授权模式**(默认):用户需要手动确认才能收款
- **免确认收款授权模式**:用户授权后,收款无需确认,转账直接到账

#### 使用方法

```java
// 免确认授权模式 - 提升用户体验
TransferBillsRequest request = TransferBillsRequest.newBuilder()
.receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION)
// 其他参数...
.build();

// 需确认授权模式(默认)
TransferBillsRequest request2 = TransferBillsRequest.newBuilder()
.receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.CONFIRM_RECEIPT_AUTHORIZATION)
// 其他参数...
.build();
```

## 快速开始

Expand Down
94 changes: 94 additions & 0 deletions NEW_TRANSFER_API_USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,100 @@
- **API前缀**: `/v3/fund-app/mch-transfer/transfer-bills`
- **特点**: 单笔转账,支持更丰富的转账场景

## 收款授权模式功能

### 授权模式说明

微信支付转账支持两种收款授权模式:

#### 1. 需确认收款授权模式(默认)
- **常量**: `WxPayConstants.ReceiptAuthorizationMode.CONFIRM_RECEIPT_AUTHORIZATION`
- **特点**: 用户收到转账后需要手动点击确认才能到账
- **适用场景**: 一般的转账场景
- **用户体验**: 安全性高,但需要额外操作

#### 2. 免确认收款授权模式
- **常量**: `WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION`
- **特点**: 用户事先授权后,转账直接到账,无需确认
- **适用场景**: 高频转账场景,如佣金发放、返现等
- **用户体验**: 体验流畅,无需额外操作
- **前提条件**: 需要用户事先进行授权

### 使用示例

#### 免确认授权模式转账

```java
TransferBillsRequest request = TransferBillsRequest.newBuilder()
.appid("your_appid")
.outBillNo("NO_CONFIRM_" + System.currentTimeMillis())
.transferSceneId("1005") // 佣金报酬场景
.openid("user_openid")
.transferAmount(200) // 2元
.transferRemark("免确认收款转账")
.receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION)
.userRecvPerception("Y")
.build();

try {
TransferBillsResult result = transferService.transferBills(request);
System.out.println("转账成功,直接到账:" + result.getTransferBillNo());
} catch (WxPayException e) {
if ("USER_NOT_AUTHORIZED".equals(e.getErrCode())) {
System.err.println("用户未授权免确认收款,请先引导用户进行授权");
}
}
```

#### 需确认授权模式转账(默认)

```java
TransferBillsRequest request = TransferBillsRequest.newBuilder()
.appid("your_appid")
.outBillNo("CONFIRM_" + System.currentTimeMillis())
.transferSceneId("1005")
.openid("user_openid")
.transferAmount(150) // 1.5元
.transferRemark("需确认收款转账")
// .receiptAuthorizationMode(...) // 不设置时使用默认的确认模式
.userRecvPerception("Y")
.build();

TransferBillsResult result = transferService.transferBills(request);
System.out.println("转账发起成功,等待用户确认:" + result.getPackageInfo());
```

### 错误处理

使用免确认授权模式时,需要处理以下可能的错误:

```java
try {
TransferBillsResult result = transferService.transferBills(request);
} catch (WxPayException e) {
switch (e.getErrCode()) {
case "USER_NOT_AUTHORIZED":
// 用户未授权免确认收款
System.err.println("请先引导用户进行免确认收款授权");
// 可以引导用户到授权页面
break;
case "AUTHORIZATION_EXPIRED":
// 授权已过期
System.err.println("用户授权已过期,请重新授权");
break;
default:
System.err.println("转账失败:" + e.getMessage());
}
}
```

### 使用建议

1. **高频转账场景**推荐使用免确认模式,提升用户体验
2. **首次使用**需引导用户进行授权
3. **处理异常**妥善处理授权相关异常,提供友好的错误提示
4. **场景选择**根据业务场景选择合适的授权模式

## 使用新版转账API

### 1. 获取服务实例
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,26 @@ public class TransferBillsRequest implements Serializable {
@SerializedName("transfer_scene_report_infos")
private List<TransferSceneReportInfo> transferSceneReportInfos;

/**
* 收款授权模式
* <pre>
* 字段名:收款授权模式
* 变量名:receipt_authorization_mode
* 是否必填:否
* 类型:string
* 描述:
* 控制收款方式的授权模式,可选值:
* - CONFIRM_RECEIPT_AUTHORIZATION:需确认收款授权模式(默认值)
* - NO_CONFIRM_RECEIPT_AUTHORIZATION:免确认收款授权模式(需要用户事先授权)
* 为空时,默认为需确认收款授权模式
* 示例值:NO_CONFIRM_RECEIPT_AUTHORIZATION
* </pre>
*
* @see com.github.binarywang.wxpay.constant.WxPayConstants.ReceiptAuthorizationMode
*/
@SerializedName("receipt_authorization_mode")
private String receiptAuthorizationMode;


@Data
@Builder(builderMethodName = "newBuilder")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -436,4 +436,25 @@ public static class CASH_MARKETING {
}

}

/**
* 收款授权模式
*
* @see <a href="https://pay.weixin.qq.com/doc/v3/merchant/4014399293">官方文档</a>
*/
@UtilityClass
public static class ReceiptAuthorizationMode {
/**
* 需确认收款授权模式(默认值)
* 用户需要手动确认才能收款
*/
public static final String CONFIRM_RECEIPT_AUTHORIZATION = "CONFIRM_RECEIPT_AUTHORIZATION";

/**
* 免确认收款授权模式
* 用户授权后,收款不需要确认,转账直接到账
*/
public static final String NO_CONFIRM_RECEIPT_AUTHORIZATION = "NO_CONFIRM_RECEIPT_AUTHORIZATION";
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
import com.github.binarywang.wxpay.bean.transfer.*;
import com.github.binarywang.wxpay.config.WxPayConfig;
import com.github.binarywang.wxpay.constant.WxPayConstants;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.TransferService;
import com.github.binarywang.wxpay.service.WxPayService;
Expand Down Expand Up @@ -215,6 +216,100 @@ public void batchTransferExample() {
}
}

/**
* 使用免确认收款授权模式进行转账示例
* 注意:使用此模式前,用户需要先进行授权
*/
public void transferWithNoConfirmAuthModeExample() {
try {
// 构建转账请求,使用免确认收款授权模式
TransferBillsRequest request = TransferBillsRequest.newBuilder()
.appid("wx1234567890123456")
.outBillNo("NO_CONFIRM_" + System.currentTimeMillis()) // 商户转账单号
.transferSceneId("1005") // 转账场景ID(佣金报酬)
.openid("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o") // 收款用户的openid
.transferAmount(200) // 转账金额,单位:分(此处为2元)
.transferRemark("免确认收款转账") // 转账备注
.receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.NO_CONFIRM_RECEIPT_AUTHORIZATION)
.userRecvPerception("Y") // 用户收款感知
.build();

// 发起转账
TransferBillsResult result = transferService.transferBills(request);

System.out.println("=== 免确认授权模式转账成功 ===");
System.out.println("商户单号: " + result.getOutBillNo());
System.out.println("微信转账单号: " + result.getTransferBillNo());
System.out.println("状态: " + result.getState());
System.out.println("说明: 使用免确认授权模式,转账直接到账,无需用户确认");

} catch (WxPayException e) {
System.err.println("免确认授权转账失败: " + e.getMessage());
System.err.println("错误代码: " + e.getErrCode());

// 可能的错误原因
if ("USER_NOT_AUTHORIZED".equals(e.getErrCode())) {
System.err.println("用户未授权免确认收款,请先引导用户进行授权");
}
}
}

/**
* 使用需确认收款授权模式进行转账示例(默认模式)
*/
public void transferWithConfirmAuthModeExample() {
try {
// 构建转账请求,显式设置为需确认收款授权模式
TransferBillsRequest request = TransferBillsRequest.newBuilder()
.appid("wx1234567890123456")
.outBillNo("CONFIRM_" + System.currentTimeMillis()) // 商户转账单号
.transferSceneId("1005") // 转账场景ID
.openid("oUpF8uMuAJO_M2pxb1Q9zNjWeS6o") // 收款用户的openid
.transferAmount(150) // 转账金额,单位:分(此处为1.5元)
.transferRemark("需确认收款转账") // 转账备注
.receiptAuthorizationMode(WxPayConstants.ReceiptAuthorizationMode.CONFIRM_RECEIPT_AUTHORIZATION)
.userRecvPerception("Y") // 用户收款感知
.build();

// 发起转账
TransferBillsResult result = transferService.transferBills(request);

System.out.println("=== 需确认授权模式转账成功 ===");
System.out.println("商户单号: " + result.getOutBillNo());
System.out.println("微信转账单号: " + result.getTransferBillNo());
System.out.println("状态: " + result.getState());
System.out.println("packageInfo: " + result.getPackageInfo());
System.out.println("说明: 使用需确认授权模式,用户需要手动确认才能收款");

} catch (WxPayException e) {
System.err.println("需确认授权转账失败: " + e.getMessage());
}
}

/**
* 权限模式对比示例
* 展示两种权限模式的区别和使用场景
*/
public void authModeComparisonExample() {
System.out.println("\n=== 收款授权模式对比 ===");
System.out.println("1. 需确认收款授权模式 (CONFIRM_RECEIPT_AUTHORIZATION):");
System.out.println(" - 这是默认模式");
System.out.println(" - 用户收到转账后需要手动点击确认才能到账");
System.out.println(" - 适用于一般的转账场景");
System.out.println(" - 转账状态可能包含 WAIT_USER_CONFIRM 等待确认状态");

System.out.println("\n2. 免确认收款授权模式 (NO_CONFIRM_RECEIPT_AUTHORIZATION):");
System.out.println(" - 用户事先授权后,转账直接到账,无需确认");
System.out.println(" - 提升用户体验,减少操作步骤");
System.out.println(" - 适用于高频转账场景,如佣金发放等");
System.out.println(" - 需要用户先进行授权,否则会返回授权错误");

System.out.println("\n使用建议:");
System.out.println("- 高频业务场景推荐使用免确认模式,提升用户体验");
System.out.println("- 首次使用需引导用户进行授权");
System.out.println("- 处理授权相关异常,提供友好的错误提示");
}

/**
* 使用配置示例
*/
Expand All @@ -230,20 +325,29 @@ public static void main(String[] args) {
// 创建示例实例
NewTransferApiExample example = new NewTransferApiExample(config);

// 权限模式对比说明
example.authModeComparisonExample();

// 运行示例
System.out.println("新版商户转账API使用示例");
System.out.println("===============================");

// 1. 发起单笔转账
// 1. 发起转账(使用免确认授权模式)
// example.transferWithNoConfirmAuthModeExample();

// 2. 发起转账(使用需确认授权模式)
// example.transferWithConfirmAuthModeExample();

// 3. 发起单笔转账(默认模式)
example.transferExample();

// 2. 查询转账结果
// 4. 查询转账结果
// example.queryByOutBillNoExample();

// 3. 撤销转账
// 5. 撤销转账
// example.cancelTransferExample();

// 4. 批量转账(传统API)
// 6. 批量转账(传统API)
// example.batchTransferExample();
}
}