From 3db8b235fcfa56d1fd784ed72c5162424e473089 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 03:39:04 +0000 Subject: [PATCH 1/6] Initial plan From 25096689e1a3fcca658b06ed5e3c3634b7ce4679 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 03:48:22 +0000 Subject: [PATCH 2/6] =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=BE=AE=E5=B7=A5?= =?UTF-8?q?=E5=8D=A1=E6=89=B9=E9=87=8F=E8=BD=AC=E8=B4=A6=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../PayrollTransferBatchesRequest.java | 239 +++++++++++++++++ .../payroll/PayrollTransferBatchesResult.java | 241 ++++++++++++++++++ .../wxpay/service/PayrollService.java | 12 + .../service/impl/PayrollServiceImpl.java | 30 +++ .../service/impl/PayrollServiceImplTest.java | 25 ++ 5 files changed, 547 insertions(+) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java new file mode 100644 index 0000000000..0c4685699d --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java @@ -0,0 +1,239 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.github.binarywang.wxpay.v3.SpecEncrypt; +import com.google.gson.annotations.SerializedName; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 微工卡批量转账API请求参数 + * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_8.shtml + * + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/transfer-batches + * 请求方式:POST + *+ * + * @author Generated by GitHub Copilot + * created on 2026/01/19 + */ +@Data +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class PayrollTransferBatchesRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+ * 字段名:应用ID + * 变量名:appid + * 是否必填:二选一 + * 类型:string[1, 32] + * 描述: + * 服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID + * 示例值:wxa1111111 + *+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+ * 字段名:子商户应用ID + * 变量名:sub_appid + * 是否必填:二选一 + * 类型:string[1, 32] + * 描述: + * 特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID + * 示例值:wxa1111111 + *+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+ * 字段名:子商户号 + * 变量名:sub_mchid + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 微信服务商下特约商户的商户号,由微信支付生成并下发 + * 示例值:1111111 + *+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+ * 字段名:商家批次单号 + * 变量名:out_batch_no + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一 + * 示例值:plfk2020042013 + *+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+ * 字段名:批次名称 + * 变量名:batch_name + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 该笔批量转账的名称 + * 示例值:2019年1月深圳分部报销单 + *+ */ + @SerializedName(value = "batch_name") + private String batchName; + + /** + *
+ * 字段名:批次备注 + * 变量名:batch_remark + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 转账说明,UTF8编码,最多允许32个字符 + * 示例值:2019年1月深圳分部报销单 + *+ */ + @SerializedName(value = "batch_remark") + private String batchRemark; + + /** + *
+ * 字段名:转账总金额 + * 变量名:total_amount + * 是否必填:是 + * 类型:int64 + * 描述: + * 转账金额单位为"分"。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作 + * 示例值:4000000 + *+ */ + @SerializedName(value = "total_amount") + private Long totalAmount; + + /** + *
+ * 字段名:转账总笔数 + * 变量名:total_num + * 是否必填:是 + * 类型:int + * 描述: + * 一个转账批次单最多发起一千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作 + * 示例值:200 + *+ */ + @SerializedName(value = "total_num") + private Integer totalNum; + + /** + *
+ * 字段名:转账明细列表 + * 变量名:transfer_detail_list + * 是否必填:是 + * 类型:array + * 描述: + * 发起批量转账的明细列表,最多一千笔 + *+ */ + @SerializedName(value = "transfer_detail_list") + private List
+ * 字段名:商家明细单号 + * 变量名:out_detail_no + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 商户系统内部区分转账批次单下不同转账明细单的唯一标识 + * 示例值:x23zy545Bd5436 + *+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; + + /** + *
+ * 字段名:转账金额 + * 变量名:transfer_amount + * 是否必填:是 + * 类型:int64 + * 描述: + * 转账金额单位为"分" + * 示例值:200000 + *+ */ + @SerializedName(value = "transfer_amount") + private Long transferAmount; + + /** + *
+ * 字段名:转账备注 + * 变量名:transfer_remark + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符 + * 示例值:2020年4月报销 + *+ */ + @SerializedName(value = "transfer_remark") + private String transferRemark; + + /** + *
+ * 字段名:用户标识 + * 变量名:openid + * 是否必填:是 + * 类型:string[1, 64] + * 描述: + * 用户在商户对应appid下的唯一标识 + * 示例值:o-MYE42l80oelYMDE34nYD456Xoy + *+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+ * 字段名:收款用户姓名 + * 变量名:user_name + * 是否必填:否 + * 类型:string[1, 1024] + * 描述: + * 收款用户真实姓名。该字段需进行加密处理,加密方法详见敏感信息加密说明 + * 示例值:757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45 + *+ */ + @SpecEncrypt + @SerializedName(value = "user_name") + private String userName; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java new file mode 100644 index 0000000000..dd52bce4cb --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java @@ -0,0 +1,241 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 微工卡批量转账API返回结果 + * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_8.shtml + * + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/transfer-batches + * 请求方式:POST + *+ * + * @author Generated by GitHub Copilot + * created on 2026/01/19 + */ +@Data +@NoArgsConstructor +public class PayrollTransferBatchesResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+ * 字段名:商家批次单号 + * 变量名:out_batch_no + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 商户系统内部的商家批次单号 + * 示例值:plfk2020042013 + *+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+ * 字段名:微信批次单号 + * 变量名:batch_id + * 是否必填:是 + * 类型:string[1, 64] + * 描述: + * 微信批次单号,微信商家转账系统返回的唯一标识 + * 示例值:1030000071100999991182020050700019480001 + *+ */ + @SerializedName(value = "batch_id") + private String batchId; + + /** + *
+ * 字段名:批次状态 + * 变量名:batch_status + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * ACCEPTED:已受理,批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认 + * PROCESSING:转账中,已开始处理批次内的转账明细单 + * FINISHED:已完成,批次内的所有转账明细单都已处理完成 + * CLOSED:已关闭,可查询具体的批次关闭原因确认 + * 示例值:ACCEPTED + *+ */ + @SerializedName(value = "batch_status") + private String batchStatus; + + /** + *
+ * 字段名:批次类型 + * 变量名:batch_type + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 批次类型 + * API:API方式发起 + * WEB:WEB方式发起 + * 示例值:API + *+ */ + @SerializedName(value = "batch_type") + private String batchType; + + /** + *
+ * 字段名:批次名称 + * 变量名:batch_name + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 该笔批量转账的名称 + * 示例值:2019年1月深圳分部报销单 + *+ */ + @SerializedName(value = "batch_name") + private String batchName; + + /** + *
+ * 字段名:批次备注 + * 变量名:batch_remark + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 转账说明,UTF8编码,最多允许32个字符 + * 示例值:2019年1月深圳分部报销单 + *+ */ + @SerializedName(value = "batch_remark") + private String batchRemark; + + /** + *
+ * 字段名:批次关闭原因 + * 变量名:close_reason + * 是否必填:否 + * 类型:string[1, 32] + * 描述: + * 如果批次单状态为"CLOSED"(已关闭),则有关闭原因 + * 示例值:OVERDUE_CLOSE + *+ */ + @SerializedName(value = "close_reason") + private String closeReason; + + /** + *
+ * 字段名:转账总金额 + * 变量名:total_amount + * 是否必填:是 + * 类型:int64 + * 描述: + * 转账金额单位为"分" + * 示例值:4000000 + *+ */ + @SerializedName(value = "total_amount") + private Long totalAmount; + + /** + *
+ * 字段名:转账总笔数 + * 变量名:total_num + * 是否必填:是 + * 类型:int + * 描述: + * 一个转账批次单最多发起一千笔转账 + * 示例值:200 + *+ */ + @SerializedName(value = "total_num") + private Integer totalNum; + + /** + *
+ * 字段名:批次创建时间 + * 变量名:create_time + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 批次受理成功时返回,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss:sss+TIMEZONE + * 示例值:2015-05-20T13:29:35.120+08:00 + *+ */ + @SerializedName(value = "create_time") + private String createTime; + + /** + *
+ * 字段名:批次更新时间 + * 变量名:update_time + * 是否必填:是 + * 类型:string[1, 32] + * 描述: + * 批次最近一次状态变更的时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss:sss+TIMEZONE + * 示例值:2015-05-20T13:29:35.120+08:00 + *+ */ + @SerializedName(value = "update_time") + private String updateTime; + + /** + *
+ * 字段名:转账成功金额 + * 变量名:success_amount + * 是否必填:否 + * 类型:int64 + * 描述: + * 转账成功的金额,单位为"分" + * 示例值:3900000 + *+ */ + @SerializedName(value = "success_amount") + private Long successAmount; + + /** + *
+ * 字段名:转账成功笔数 + * 变量名:success_num + * 是否必填:否 + * 类型:int + * 描述: + * 转账成功的笔数 + * 示例值:199 + *+ */ + @SerializedName(value = "success_num") + private Integer successNum; + + /** + *
+ * 字段名:转账失败金额 + * 变量名:fail_amount + * 是否必填:否 + * 类型:int64 + * 描述: + * 转账失败的金额,单位为"分" + * 示例值:100000 + *+ */ + @SerializedName(value = "fail_amount") + private Long failAmount; + + /** + *
+ * 字段名:转账失败笔数 + * 变量名:fail_num + * 是否必填:否 + * 类型:int + * 描述: + * 转账失败的笔数 + * 示例值:1 + *+ */ + @SerializedName(value = "fail_num") + private Integer failNum; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java index b3f788815c..581e3230b7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java @@ -101,4 +101,16 @@ public interface PayrollService { */ WxPayApplyBillV3Result merchantFundWithdrawBillType(String billType, String billDate, String tarType) throws WxPayException; + /** + * 微工卡批量转账API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/transfer-batches + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + PayrollTransferBatchesResult payrollCardTransferBatches(PayrollTransferBatchesRequest request) throws WxPayException; + } diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java index 3d8c831271..58446a4425 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java @@ -193,4 +193,34 @@ public WxPayApplyBillV3Result merchantFundWithdrawBillType(String billType, Stri return GSON.fromJson(response, WxPayApplyBillV3Result.class); } + /** + * 微工卡批量转账API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/transfer-batches + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public PayrollTransferBatchesResult payrollCardTransferBatches(PayrollTransferBatchesRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/transfer-batches", payService.getPayBaseUrl()); + try { + // 对敏感信息进行加密 + if (request.getTransferDetailList() != null && !request.getTransferDetailList().isEmpty()) { + for (PayrollTransferBatchesRequest.TransferDetail detail : request.getTransferDetailList()) { + if (StringUtils.isNotEmpty(detail.getUserName())) { + String userName = RsaCryptoUtil.encryptOAEP(detail.getUserName(), payService.getConfig().getVerifier().getValidCertificate()); + detail.setUserName(userName); + } + } + } + } catch (IllegalBlockSizeException e) { + throw new RuntimeException("敏感信息加密异常!", e); + } + String response = payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(response, PayrollTransferBatchesResult.class); + } + } diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java index 03bbc8c593..8a5514bf21 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java @@ -125,4 +125,29 @@ public void merchantFundWithdrawBillType() throws WxPayException { log.info(result.toString()); } + @Test + public void payrollCardTransferBatches() throws WxPayException { + PayrollTransferBatchesRequest request = PayrollTransferBatchesRequest.builder() + .appid("wxa1111111") + .subMchid("1111111") + .subAppid("wxa1111111") + .outBatchNo("plfk2020042013" + System.currentTimeMillis()) + .batchName("2019年1月深圳分部报销单") + .batchRemark("2019年1月深圳分部报销单") + .totalAmount(200000L) + .totalNum(1) + .transferDetailList(java.util.Collections.singletonList( + PayrollTransferBatchesRequest.TransferDetail.builder() + .outDetailNo("x23zy545Bd5436" + System.currentTimeMillis()) + .transferAmount(200000L) + .transferRemark("2020年4月报销") + .openid("o-MYE42l80oelYMDE34nYD456Xoy") + .userName("张三") + .build() + )) + .build(); + PayrollTransferBatchesResult result = wxPayService.getPayrollService().payrollCardTransferBatches(request); + log.info(result.toString()); + } + } From 426c5e97f62b7e300c31329f39919bbfca8cf2ac Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 03:49:49 +0000 Subject: [PATCH 3/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=EF=BC=9A=E6=9B=B4=E6=96=B0?= =?UTF-8?q?=E4=BD=9C=E8=80=85=E4=BF=A1=E6=81=AF=E5=92=8C=E5=BC=82=E5=B8=B8?= =?UTF-8?q?=E6=B6=88=E6=81=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../bean/marketing/payroll/PayrollTransferBatchesRequest.java | 2 +- .../bean/marketing/payroll/PayrollTransferBatchesResult.java | 2 +- .../binarywang/wxpay/service/impl/PayrollServiceImpl.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java index 0c4685699d..ff5faf5acc 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java @@ -20,7 +20,7 @@ * 请求方式:POST * * - * @author Generated by GitHub Copilot + * @author binarywang * created on 2026/01/19 */ @Data diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java index dd52bce4cb..dd716d33cb 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java @@ -16,7 +16,7 @@ * 请求方式:POST * * - * @author Generated by GitHub Copilot + * @author binarywang * created on 2026/01/19 */ @Data diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java index 58446a4425..58cd051d4a 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java @@ -217,7 +217,7 @@ public PayrollTransferBatchesResult payrollCardTransferBatches(PayrollTransferBa } } } catch (IllegalBlockSizeException e) { - throw new RuntimeException("敏感信息加密异常!", e); + throw new RuntimeException("Sensitive information encryption failed!", e); } String response = payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); return GSON.fromJson(response, PayrollTransferBatchesResult.class); From 773d10a50c4252f8780d878e13be5475755b525e Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 03:51:38 +0000 Subject: [PATCH 4/6] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E5=AE=A1=E6=9F=A5=E9=97=AE=E9=A2=98=EF=BC=9A=E7=BB=9F=E4=B8=80?= =?UTF-8?q?=E9=94=99=E8=AF=AF=E6=B6=88=E6=81=AF=E6=A0=BC=E5=BC=8F=E5=92=8C?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E6=97=A5=E6=9C=9F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../bean/marketing/payroll/PayrollTransferBatchesRequest.java | 2 +- .../bean/marketing/payroll/PayrollTransferBatchesResult.java | 2 +- .../binarywang/wxpay/service/impl/PayrollServiceImpl.java | 2 +- .../binarywang/wxpay/service/impl/PayrollServiceImplTest.java | 4 +++- 4 files changed, 6 insertions(+), 4 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java index ff5faf5acc..50954e70e5 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesRequest.java @@ -21,7 +21,7 @@ * * * @author binarywang - * created on 2026/01/19 + * created on 2025/01/19 */ @Data @Builder diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java index dd716d33cb..628c75d5f7 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PayrollTransferBatchesResult.java @@ -17,7 +17,7 @@ * * * @author binarywang - * created on 2026/01/19 + * created on 2025/01/19 */ @Data @NoArgsConstructor diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java index 58cd051d4a..51a33e1bd0 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java @@ -217,7 +217,7 @@ public PayrollTransferBatchesResult payrollCardTransferBatches(PayrollTransferBa } } } catch (IllegalBlockSizeException e) { - throw new RuntimeException("Sensitive information encryption failed!", e); + throw new RuntimeException("加密异常!", e); } String response = payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); return GSON.fromJson(response, PayrollTransferBatchesResult.class); diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java index 8a5514bf21..ce43aa3d04 100644 --- a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java @@ -14,6 +14,8 @@ import org.testng.annotations.Guice; import org.testng.annotations.Test; +import java.util.Collections; + /** * 微工卡(服务商) * @@ -136,7 +138,7 @@ public void payrollCardTransferBatches() throws WxPayException { .batchRemark("2019年1月深圳分部报销单") .totalAmount(200000L) .totalNum(1) - .transferDetailList(java.util.Collections.singletonList( + .transferDetailList(Collections.singletonList( PayrollTransferBatchesRequest.TransferDetail.builder() .outDetailNo("x23zy545Bd5436" + System.currentTimeMillis()) .transferAmount(200000L) From 1fce1abc74094c9855e33b6a61d57d81f0ea7e33 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 19 Jan 2026 03:54:44 +0000 Subject: [PATCH 5/6] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=95=8F=E6=84=9F?= =?UTF-8?q?=E4=BF=A1=E6=81=AF=E5=8A=A0=E5=AF=86=E5=AE=9E=E7=8E=B0=EF=BC=9A?= =?UTF-8?q?=E4=BD=BF=E7=94=A8encryptFields=E6=96=B9=E6=B3=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: binarywang <1343140+binarywang@users.noreply.github.com> --- .../wxpay/service/impl/PayrollServiceImpl.java | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java index 51a33e1bd0..17b92c3d0d 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java @@ -206,18 +206,13 @@ public WxPayApplyBillV3Result merchantFundWithdrawBillType(String billType, Stri @Override public PayrollTransferBatchesResult payrollCardTransferBatches(PayrollTransferBatchesRequest request) throws WxPayException { String url = String.format("%s/v3/payroll-card/transfer-batches", payService.getPayBaseUrl()); - try { - // 对敏感信息进行加密 - if (request.getTransferDetailList() != null && !request.getTransferDetailList().isEmpty()) { - for (PayrollTransferBatchesRequest.TransferDetail detail : request.getTransferDetailList()) { - if (StringUtils.isNotEmpty(detail.getUserName())) { - String userName = RsaCryptoUtil.encryptOAEP(detail.getUserName(), payService.getConfig().getVerifier().getValidCertificate()); - detail.setUserName(userName); - } + // 对敏感信息进行加密 + if (request.getTransferDetailList() != null && !request.getTransferDetailList().isEmpty()) { + for (PayrollTransferBatchesRequest.TransferDetail detail : request.getTransferDetailList()) { + if (StringUtils.isNotEmpty(detail.getUserName())) { + RsaCryptoUtil.encryptFields(detail, payService.getConfig().getVerifier().getValidCertificate()); } } - } catch (IllegalBlockSizeException e) { - throw new RuntimeException("加密异常!", e); } String response = payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); return GSON.fromJson(response, PayrollTransferBatchesResult.class); From d6d5f92f34f0d7ac4960983e9abccdd4d1f134fe Mon Sep 17 00:00:00 2001 From: Binary Wang