From fb4c833fb8eefe55c756243f88ceb660ca1defb5 Mon Sep 17 00:00:00 2001 From: xiaoqiang Date: Tue, 14 Dec 2021 09:53:39 +0800 Subject: [PATCH] =?UTF-8?q?=E3=80=90=E5=BE=AE=E4=BF=A1=E6=94=AF=E4=BB=98?= =?UTF-8?q?=E3=80=91=E5=A2=9E=E5=8A=A0=E5=BE=AE=E4=BF=A1=E6=89=B9=E9=87=8F?= =?UTF-8?q?=E8=BD=AC=E8=B4=A6=E5=88=B0=E9=9B=B6=E9=92=B1=EF=BC=88=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=95=86=EF=BC=89=E3=80=81=E5=BE=AE=E5=B7=A5=E5=8D=A1?= =?UTF-8?q?=EF=BC=88=E6=9C=8D=E5=8A=A1=E5=95=86=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../marketing/payroll/AuthRecordRequest.java | 135 ++++++ .../marketing/payroll/AuthRecordResult.java | 213 ++++++++++ .../payroll/AuthenticationsResult.java | 182 ++++++++ .../payroll/MerchantIncomeRecordsRequest.java | 83 ++++ .../payroll/MerchantIncomeRecordsResult.java | 286 +++++++++++++ .../payroll/PartnerIncomeRecordsRequest.java | 97 +++++ .../payroll/PartnerIncomeRecordsResult.java | 286 +++++++++++++ .../marketing/payroll/PreOrderRequest.java | 125 ++++++ .../marketing/payroll/PreOrderResult.java | 111 +++++ .../payroll/PreOrderWithAuthRequest.java | 169 ++++++++ .../payroll/PreOrderWithAuthResult.java | 110 +++++ .../marketing/payroll/RelationsRequest.java | 83 ++++ .../marketing/payroll/RelationsResult.java | 114 +++++ .../payroll/SubFundFlowBillResult.java | 100 +++++ .../bean/marketing/payroll/TokensRequest.java | 128 ++++++ .../bean/marketing/payroll/TokensResult.java | 97 +++++ .../transfer/BatchDetailsRequest.java | 53 +++ .../transfer/BatchDetailsResult.java | 239 +++++++++++ .../transfer/BatchNumberRequest.java | 96 +++++ .../marketing/transfer/BatchNumberResult.java | 393 ++++++++++++++++++ .../marketing/transfer/BillReceiptResult.java | 143 +++++++ .../marketing/transfer/DownloadRequest.java | 65 +++ .../transfer/ElectronicReceiptsRequest.java | 70 ++++ .../transfer/ElectronicReceiptsResult.java | 137 ++++++ .../transfer/MerchantBatchRequest.java | 97 +++++ .../transfer/PartnerTransferRequest.java | 289 +++++++++++++ .../transfer/PartnerTransferResult.java | 67 +++ .../transfer/ReceiptBillRequest.java | 35 ++ .../wxpay/service/PartnerTransferService.java | 201 +++++++++ .../wxpay/service/PayrollService.java | 103 +++++ .../wxpay/service/WxPayService.java | 14 + .../service/impl/BaseWxPayServiceImpl.java | 9 +- .../impl/PartnerTransferServiceImpl.java | 311 ++++++++++++++ .../service/impl/PayrollServiceImpl.java | 192 +++++++++ .../impl/PartnerTransferServiceImplTest.java | 139 +++++++ .../service/impl/PayrollServiceImplTest.java | 128 ++++++ 36 files changed, 5099 insertions(+), 1 deletion(-) create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthenticationsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/SubFundFlowBillResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BillReceiptResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/DownloadRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/MerchantBatchRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferResult.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ReceiptBillRequest.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PartnerTransferService.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImpl.java create mode 100644 weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImplTest.java create mode 100644 weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordRequest.java new file mode 100644 index 0000000000..2de2168504 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordRequest.java @@ -0,0 +1,135 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 查询核身记录
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_5.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class AuthRecordRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:应用ID
+   * 变量名:appid
+   * 是否必填:二选一
+   * 类型:string[1, 32]
+   * 描述:
+   *   是服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID(与服务商主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。
+   *  当输入应用ID时,会校验其与服务商商户号的绑定关系。服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:子商户应用ID
+   * 变量名:sub_appid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  是特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID(与特约商户主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。当输入子商户应用ID时,会校验其与特约商户号的绑定关系。 服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   * 示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:核身日期
+   * 变量名:authenticate_date
+   * 是否必填:是
+   * 类型:string[8, 8]
+   * 描述:
+   *  query核身日期,一次只能查询一天,最久可查询90天内的记录,格式为“YYYY-MM-DD”
+   *     示例值:2020-12-25
+   * 
+ */ + @SerializedName(value = "authenticate_date") + private String authenticateDate; + /** + *
+   * 字段名:核身状态
+   * 变量名:authenticate_state
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   * query核身状态,列表查询仅提供成功状态的核身记录查询,故此字段固定默认值即可
+   *     示例值:AUTHENTICATE_SUCCESS
+   * 
+ */ + @SerializedName(value = "authenticate_state") + private String authenticateState; + /** + *
+   * 字段名:本次查询偏移量
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * query非负整数,表示该次请求资源的起始位置,从0开始计数。调用方选填,默认为0。offset为10,limit为10时,查询第10-19条数据
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + /** + *
+   * 字段名:本次请求最大查询条数
+   * 变量名:limit
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * query非0非负的整数,该次请求可返回的最大资源条数,默认值为10,最大支持10条。
+   *     示例值:10
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordResult.java new file mode 100644 index 0000000000..abf8397633 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthRecordResult.java @@ -0,0 +1,213 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 查询核身记录
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_5.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class AuthRecordResult implements Serializable { + private static final long serialVersionUID = 1L; + + @SerializedName(value = "data") + private List dataList; + + @Data + @NoArgsConstructor + public static class RecordData implements Serializable { + private static final long serialVersionUID = 1L; + /** + *
+     * 字段名:商户号
+     * 变量名:mchid
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  微信服务商商户的商户号,由微信支付生成并下发。
+     *  示例值:1111111
+     * 
+ */ + @SerializedName(value = "mchid") + private Integer mchid; + /** + *
+     * 字段名:子商户号
+     * 变量名:sub_mchid
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  微信服务商下特约商户的商户号,由微信支付生成并下发
+     *  示例值:111111
+     * 
+ */ + @SerializedName(value = "sub_mchid") + private Integer subMchid; + /** + *
+     * 字段名:用户标识
+     * 变量名:openid
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  用户在商户对应appid下的唯一标识
+     *  示例值:onqOjjmo8wmTOOtSKwXtGjg9Gb58
+     * 
+ */ + @SerializedName(value = "openid") + private Integer openid; + /** + *
+     * 字段名:核身渠道
+     * 变量名:authenticate_scene
+     * 是否必填:是
+     * 类型:string[1, 16]
+     * 描述:
+     *  核身渠道,发起核身时的来源渠道,如通过小程序,硬件设备等
+     *         FROM_MINI_APP:来自小程序方式核身
+     *         FROM_HARDWARE:来自硬件设备方式核身
+     *  示例值:FROM_HARDWARE
+     * 
+ */ + @SerializedName(value = "authenticate_scene") + private Integer authenticateScene; + /** + *
+     * 字段名:核身渠道标识
+     * 变量名:authenticate_source
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  核身渠道标识,用于定位渠道具体来源,如果是扫码打卡渠道标识就是具体的小程序appid,若是硬件设备,则是设备的序列号等
+     *  示例值:wdiooewl7587443649000
+     * 
+ */ + @SerializedName(value = "authenticate_source") + private Integer authenticateSource; + /** + *
+     * 字段名:项目名称
+     * 变量名:project_name
+     * 是否必填:是
+     * 类型:string[1, 12]
+     * 描述:
+     *  该项目的名称
+     *  示例值:某项目
+     * 
+ */ + @SerializedName(value = "project_name") + private Integer projectName; + /** + *
+     * 字段名:单位名称
+     * 变量名:employer_name
+     * 是否必填:是
+     * 类型:string[1, 12]
+     * 描述:
+     *    该用户所属的单位名称。
+     *     示例值:某单位名称
+     * 
+ */ + @SerializedName(value = "employer_name") + private String employerName; + /** + *
+     * 字段名:核身状态
+     * 变量名:authenticate_state
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *    核身状态
+     *     AUTHENTICATE_PROCESSING:核身中
+     *     AUTHENTICATE_SUCCESS:核身成功
+     *     AUTHENTICATE_FAILED:核身失败
+     *  示例值:AUTHENTICATE_PROCESSING
+     * 
+ */ + @SerializedName(value = "authenticate_state") + private String authenticateState; + + /** + *
+     * 字段名:核身时间
+     * 变量名:authenticate_time
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *   核身时间,遵循RFC3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。
+     *   示例值:2015-05-20T13:29:35+08:00
+     * 
+ */ + @SerializedName(value = "authenticate_time") + private String authenticateTime; + /** + *
+     * 字段名:商家核身单号
+     * 变量名:authenticate_number
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+     *  示例值:mcdhehfgisdhfjghed39384564i83
+     * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + } + + /** + *
+   * 字段名:总记录条数
+   * 变量名:total_count
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  经过条件筛选,查询到的记录总数
+   *  示例值:9
+   * 
+ */ + @SerializedName(value = "total_count") + private Integer totalCount; + + /** + *
+   * 字段名:记录起始位置
+   * 变量名:offset
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  该次请求资源的起始位置,请求中包含偏移量时应答消息返回相同偏移量,否则返回默认值0
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + + /** + *
+   * 字段名:本次返回条数
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  经过条件筛选,本次查询到的记录条数
+   *  示例值:10
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthenticationsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthenticationsResult.java new file mode 100644 index 0000000000..7557248691 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/AuthenticationsResult.java @@ -0,0 +1,182 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 获取核身结果
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_4.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/{authenticate_number}
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class AuthenticationsResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  query微信服务商下特约商户的商户号,由微信支付生成并下发
+   *     示例值:1111111
+   * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  query微信服务商下特约商户的商户号,由微信支付生成并下发
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + /** + *
+   * 字段名:用户标识
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   * 示例值:onqOjjmo8wmTOOtSKwXtGjg9Gb58
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:核身渠道
+   * 变量名:authenticate_scene
+   * 是否必填:是
+   * 类型:string[1, 16]
+   * 描述:
+   *   核身渠道,发起核身时的来源渠道,如通过小程序,硬件设备等
+   *     FROM_MINI_APP:来自小程序方式核身
+   *     FROM_HARDWARE:来自硬件设备方式核身
+   *  示例值:onqOjjmo8wmTOOtSKwXtGjg9Gb58
+   * 
+ */ + @SerializedName(value = "authenticate_scene") + private String authenticateScene; + + /** + *
+   * 字段名:核身渠道标识
+   * 变量名:authenticate_source
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *    核身渠道标识,用于定位渠道具体来源,如果是扫码打卡渠道标识就是具体的小程序appid,若是硬件设备,则是设备的序列号等
+   * 示例值:wdiooewl7587443649000
+   * 
+ */ + @SerializedName(value = "authenticate_source") + private String authenticateSource; + + /** + *
+   * 字段名:项目名称
+   * 变量名:project_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   *    该项目的名称
+   *  示例值:某项目
+   * 
+ */ + @SerializedName(value = "project_name") + private String projectName; + + /** + *
+   * 字段名:单位名称
+   * 变量名:employer_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   *    该用户所属的单位名称。
+   *  示例值:某单位名称
+   * 
+ */ + @SerializedName(value = "employer_name") + private String employerName; + + /** + *
+   * 字段名:核身状态
+   * 变量名:authenticate_state
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *    核身状态
+   *     AUTHENTICATE_PROCESSING:核身中
+   *     AUTHENTICATE_SUCCESS:核身成功
+   *     AUTHENTICATE_FAILED:核身失败
+   *  示例值:AUTHENTICATE_PROCESSING
+   * 
+ */ + @SerializedName(value = "authenticate_state") + private String authenticateState; + /** + *
+   * 字段名:核身时间
+   * 变量名:authenticate_time
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *   核身时间,遵循RFC3339标准格式,格式为YYYY-MM-DDTHH:mm:ss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss表示时分秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。
+   *   示例值:2015-05-20T13:29:35+08:00
+   * 
+ */ + @SerializedName(value = "authenticate_time") + private String authenticateTime; + /** + *
+   * 字段名:商家核身单号
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+   *  示例值:mcdhehfgisdhfjghed39384564i83
+   * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + + /** + *
+   * 字段名:核身失败原因
+   * 变量名:authenticate_failed_reason
+   * 是否必填:否
+   * 类型:string[1, 128]
+   * 描述:
+   *  结果为核身失败时的原因描述,仅在失败记录返回
+   *  示例值:人脸验证未通过
+   * 
+ */ + @SerializedName(value = "authenticate_failed_reason") + private String authenticateFailedReason; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsRequest.java new file mode 100644 index 0000000000..04fe709649 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsRequest.java @@ -0,0 +1,83 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 服务商银行来账查询
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_28.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/merchantfund/merchant/income-records
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/7 + */ +@Data +@NoArgsConstructor +public class MerchantIncomeRecordsRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:账户类型
+   * 变量名:account_type
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * query需查询银行来账记录商户的账户类型。
+   *     枚举值:
+   *     BASIC:基本账户
+   *     OPERATION:运营账户
+   *     FEES:手续费账户
+   * 示例值:BASIC
+   * 
+ */ + @SerializedName(value = "account_type") + private String accountType; + /** + *
+   * 字段名:日期
+   * 变量名:date
+   * 是否必填:是
+   * 类型:string[10, 10]
+   * 描述:
+   * query查询的日期,一次只能查询一天,最久可查询90天内的记录,格式为“YYYY-MM-DD”。
+   * 示例值:2019-06-11
+   * 
+ */ + @SerializedName(value = "date") + private String date; + /** + *
+   * 字段名:本次查询偏移量
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * query非负整数,表示该次请求资源的起始位置,从0开始计数。调用方选填,默认为0。offset为20,limit为100时,查询第20-119条数据。
+   * 示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private int offset; + /** + *
+   * 字段名:本次请求最大查询条数
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * query非0非负的整数,该次请求可返回的最大资源条数,最大支持100条。
+   * 示例值:100
+   * 
+ */ + @SerializedName(value = "limit") + private int limit; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsResult.java new file mode 100644 index 0000000000..a587d27f0c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/MerchantIncomeRecordsResult.java @@ -0,0 +1,286 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 服务商银行来账查询
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_28.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/merchantfund/merchant/income-records
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/7 + */ +@Data +@NoArgsConstructor +public class MerchantIncomeRecordsResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:查询数据总条数
+   * 变量名:total_count
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  经过条件筛选,查询到的银行来账记录总数 。
+   * 示例值:20
+   * 
+ */ + @SerializedName(value = "total_count") + private int totalCount; + + /** + *
+   * 字段名:本次查询偏移量
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * 该次请求资源的起始位置,请求中包含偏移量时应答消息返回相同偏移量,否则返回默认值0。
+   * 示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private int offset; + /** + *
+   * 字段名:本次请求最大查询条数
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * 经过条件筛选,本次查询到的银行来账记录条数。
+   * 示例值:100
+   * 
+ */ + @SerializedName(value = "limit") + private int limit; + /** + *
+   * 字段名:银行来账记录列表
+   * 变量名:data
+   * 是否必填:否
+   * 类型:array
+   * 描述:
+   *  单次查询返回的银行来账记录列表结果,如果查询结果为空时,则为空数组。
+   * 
+ */ + @SerializedName(value = "data") + private List incomeRecordDataList; + + + @Data + @NoArgsConstructor + public static class IncomeRecordData implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+     * 字段名:商户号
+     * 变量名:sub_mchid
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  需查询银行来账记录列表的商户号
+     * 示例值:2480253391
+     * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+     * 字段名:账户类型
+     * 变量名:account_type
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  需查询银行来账记录商户的账户类型。
+     *     枚举值:
+     *     BASIC:基本账户
+     *     OPERATION:运营账户
+     *     FEES:手续费账户
+     * 示例值:BASIC
+     * 
+ */ + @SerializedName(value = "account_type") + private String accountType; + /** + *
+     * 字段名:银行来账类型
+     * 变量名:income_record_type
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  银行来账类型,后续会有所扩展。
+     *     枚举值:
+     *     OFFLINERECHARGE:转账充值
+     *     ENTERPRISEDIRECTREVENUE:企业直收
+     * 示例值:OFFLINERECHARGE
+     * 
+ */ + @SerializedName(value = "income_record_type") + private String incomeRecordType; + /** + *
+     * 字段名:银行来账微信单号
+     * 变量名:income_record_id
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  银行来账的微信单号
+     * 示例值:4200000811202011056138519459
+     * 
+ */ + @SerializedName(value = "income_record_id") + private String incomeRecordId; + /** + *
+     * 字段名:银行来账金额
+     * 变量名:amount
+     * 是否必填:是
+     * 类型:int
+     * 描述:
+     *  银行来账金额,单位为分,只能为整数。
+     * 示例值:2734921
+     * 
+ */ + @SerializedName(value = "amount") + private String amount; + /** + *
+     * 字段名:银行来账完成时间
+     * 变量名:success_time
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  银行来账完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+     * 示例值:2017-12-08T00:08:00.00+08:00
+     * 
+ */ + @SerializedName(value = "success_time") + private String successTime; + /** + *
+     * 字段名:付款方银行名称
+     * 变量名:bank_name
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  银行来账的付款方银行名称,由于部分银行的数据获取限制,该字段有可能为空。
+     * 示例值:招商银行
+     * 
+ */ + @SerializedName(value = "bank_name") + private String bankName; + /** + *
+     * 字段名:付款方银行户名
+     * 变量名:bank_account_name
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  银行来账的付款方银行账户信息,户名为全称、明文,由于部分银行的数据获取限制,该字段有可能为空。
+     * 示例值:北京三快科技有限公司
+     * 
+ */ + @SerializedName(value = "bank_account_name") + private String bankAccountName; + /** + *
+     * 字段名:付款方银行卡号
+     * 变量名:bank_account_number
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  四位掩码+付款方银行卡尾号后四位。
+     * 示例值:****6473
+     * 
+ */ + @SerializedName(value = "bank_account_number") + private String bankAccountNumber; + /** + *
+     * 字段名:银行备注
+     * 变量名:recharge_remark
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  随银行转账时,商户填入的附言、摘要等信息,目前支持的银行及填写指引请查看各银行对账详情
+     * 示例值:单号:202106010001
+     * 
+ */ + @SerializedName(value = "recharge_remark") + private String rechargeRemark; + } + + /** + *
+   * 字段名:分页链接
+   * 变量名:links
+   * 是否必填:是
+   * 类型:object
+   * 描述:
+   *  返回前后页和当前页面的访问链接
+   * 
+ */ + @SerializedName(value = "links") + private List linksDataList; + + + @Data + @NoArgsConstructor + public static class LinksData implements Serializable { + private static final long serialVersionUID = 109053454401492L; + + /** + *
+     * 字段名:下一页链接
+     * 变量名:next
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  使用同样的limit进行下一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果已经到最后时,为空 。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=10&limit=5
+     * 
+ */ + @SerializedName(value = "next") + private String next; + /** + *
+     * 字段名:上一页链接
+     * 变量名:prev
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  使用同样的limit进行上一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果是第一页,为空。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=0&limit=5
+     * 
+ */ + @SerializedName(value = "prev") + private String prev; + /** + *
+     * 字段名:当前链接
+     * 变量名:self
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  当前的相对请求链接,使用方需要自行根据当前域名进行拼接。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=5&limit=5
+     * 
+ */ + @SerializedName(value = "self") + private String self; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsRequest.java new file mode 100644 index 0000000000..f266bdb17b --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsRequest.java @@ -0,0 +1,97 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 特约商户银行来账查询
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_27.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/merchantfund/partner/income-records
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/7 + */ +@Data +@NoArgsConstructor +public class PartnerIncomeRecordsRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:特约商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  query需查询银行来账记录列表的特约商户的商户号,该商户号须为服务商的特约商户号。
+   *  示例值:2480253391
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:账户类型
+   * 变量名:account_type
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * query需查询银行来账记录商户的账户类型。
+   *     枚举值:
+   *     BASIC:基本账户
+   *     OPERATION:运营账户
+   *     FEES:手续费账户
+   * 示例值:BASIC
+   * 
+ */ + @SerializedName(value = "account_type") + private String accountType; + /** + *
+   * 字段名:日期
+   * 变量名:date
+   * 是否必填:是
+   * 类型:string[10, 10]
+   * 描述:
+   * query查询的日期,一次只能查询一天,最久可查询90天内的记录,格式为“YYYY-MM-DD”。
+   * 示例值:2019-06-11
+   * 
+ */ + @SerializedName(value = "date") + private String date; + /** + *
+   * 字段名:本次查询偏移量
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * query非负整数,表示该次请求资源的起始位置,从0开始计数。调用方选填,默认为0。offset为20,limit为100时,查询第20-119条数据。
+   * 示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private int offset; + /** + *
+   * 字段名:本次请求最大查询条数
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * query非0非负的整数,该次请求可返回的最大资源条数,最大支持100条。
+   * 示例值:100
+   * 
+ */ + @SerializedName(value = "limit") + private int limit; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsResult.java new file mode 100644 index 0000000000..90d7d6cc15 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PartnerIncomeRecordsResult.java @@ -0,0 +1,286 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 特约商户银行来账查询
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_27.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/merchantfund/partner/income-records
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/7 + */ +@Data +@NoArgsConstructor +public class PartnerIncomeRecordsResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:查询数据总条数
+   * 变量名:total_count
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  经过条件筛选,查询到的银行来账记录总数 。
+   * 示例值:20
+   * 
+ */ + @SerializedName(value = "total_count") + private int totalCount; + + /** + *
+   * 字段名:本次查询偏移量
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   * 该次请求资源的起始位置,请求中包含偏移量时应答消息返回相同偏移量,否则返回默认值0。
+   * 示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private int offset; + /** + *
+   * 字段名:本次请求最大查询条数
+   * 变量名:limit
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * 经过条件筛选,本次查询到的银行来账记录条数。
+   * 示例值:100
+   * 
+ */ + @SerializedName(value = "limit") + private int limit; + /** + *
+   * 字段名:银行来账记录列表
+   * 变量名:data
+   * 是否必填:否
+   * 类型:array
+   * 描述:
+   *  单次查询返回的银行来账记录列表结果,如果查询结果为空时,则为空数组。
+   * 
+ */ + @SerializedName(value = "data") + private List incomeRecordDataList; + + + @Data + @NoArgsConstructor + public static class IncomeRecordData implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+     * 字段名:特约商户号
+     * 变量名:sub_mchid
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  需查询银行来账记录列表的特约商户的商户号,该商户号须为服务商的特约商户号。
+     * 示例值:2480253391
+     * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+     * 字段名:账户类型
+     * 变量名:account_type
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  需查询银行来账记录商户的账户类型。
+     *     枚举值:
+     *     BASIC:基本账户
+     *     OPERATION:运营账户
+     *     FEES:手续费账户
+     * 示例值:BASIC
+     * 
+ */ + @SerializedName(value = "account_type") + private String accountType; + /** + *
+     * 字段名:银行来账类型
+     * 变量名:income_record_type
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  银行来账类型,后续会有所扩展。
+     *     枚举值:
+     *     OFFLINERECHARGE:转账充值
+     *     ENTERPRISEDIRECTREVENUE:企业直收
+     * 示例值:OFFLINERECHARGE
+     * 
+ */ + @SerializedName(value = "income_record_type") + private String incomeRecordType; + /** + *
+     * 字段名:银行来账微信单号
+     * 变量名:income_record_id
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  银行来账的微信单号
+     * 示例值:4200000811202011056138519459
+     * 
+ */ + @SerializedName(value = "income_record_id") + private String incomeRecordId; + /** + *
+     * 字段名:银行来账金额
+     * 变量名:amount
+     * 是否必填:是
+     * 类型:int
+     * 描述:
+     *  银行来账金额,单位为分,只能为整数。
+     * 示例值:2734921
+     * 
+ */ + @SerializedName(value = "amount") + private String amount; + /** + *
+     * 字段名:银行来账完成时间
+     * 变量名:success_time
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  银行来账完成时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示,北京时间2015年5月20日 13点29分35秒。
+     * 示例值:2017-12-08T00:08:00.00+08:00
+     * 
+ */ + @SerializedName(value = "success_time") + private String successTime; + /** + *
+     * 字段名:付款方银行名称
+     * 变量名:bank_name
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  银行来账的付款方银行名称,由于部分银行的数据获取限制,该字段有可能为空。
+     * 示例值:招商银行
+     * 
+ */ + @SerializedName(value = "bank_name") + private String bankName; + /** + *
+     * 字段名:付款方银行户名
+     * 变量名:bank_account_name
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  银行来账的付款方银行账户信息,户名为全称、明文,由于部分银行的数据获取限制,该字段有可能为空。
+     * 示例值:北京三快科技有限公司
+     * 
+ */ + @SerializedName(value = "bank_account_name") + private String bankAccountName; + /** + *
+     * 字段名:付款方银行卡号
+     * 变量名:bank_account_number
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  四位掩码+付款方银行卡尾号后四位。
+     * 示例值:****6473
+     * 
+ */ + @SerializedName(value = "bank_account_number") + private String bankAccountNumber; + /** + *
+     * 字段名:银行备注
+     * 变量名:recharge_remark
+     * 是否必填:是
+     * 类型:string[1, 256]
+     * 描述:
+     *  随银行转账时,商户填入的附言、摘要等信息,目前支持的银行及填写指引请查看各银行对账详情
+     * 示例值:单号:202106010001
+     * 
+ */ + @SerializedName(value = "recharge_remark") + private String rechargeRemark; + } + + /** + *
+   * 字段名:分页链接
+   * 变量名:links
+   * 是否必填:是
+   * 类型:object
+   * 描述:
+   *  返回前后页和当前页面的访问链接
+   * 
+ */ + @SerializedName(value = "links") + private List linksDataList; + + + @Data + @NoArgsConstructor + public static class LinksData implements Serializable { + private static final long serialVersionUID = 109053454401492L; + + /** + *
+     * 字段名:下一页链接
+     * 变量名:next
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  使用同样的limit进行下一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果已经到最后时,为空 。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=10&limit=5
+     * 
+ */ + @SerializedName(value = "next") + private String next; + /** + *
+     * 字段名:上一页链接
+     * 变量名:prev
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  使用同样的limit进行上一页查询时的相对请求链接,使用方需要自行根据当前域名进行拼接。如果是第一页,为空。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=0&limit=5
+     * 
+ */ + @SerializedName(value = "prev") + private String prev; + /** + *
+     * 字段名:当前链接
+     * 变量名:self
+     * 是否必填:是
+     * 类型:string[1, 2048]
+     * 描述:
+     *  当前的相对请求链接,使用方需要自行根据当前域名进行拼接。
+     * 示例值:/v3/merchantfund/partner/income-records?offset=5&limit=5
+     * 
+ */ + @SerializedName(value = "self") + private String self; + } +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderRequest.java new file mode 100644 index 0000000000..80d0ed9f4d --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderRequest.java @@ -0,0 +1,125 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 微工卡核身预下单
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_3.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class PreOrderRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:应用ID
+   * 变量名:appid
+   * 是否必填:二选一
+   * 类型:string[1, 32]
+   * 描述:
+   *   是服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID(与服务商主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。
+   *  当输入应用ID时,会校验其与服务商商户号的绑定关系。服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   * 示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:子商户应用ID
+   * 变量名:sub_appid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  是特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID(与特约商户主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。当输入子商户应用ID时,会校验其与特约商户号的绑定关系。 服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+   * 字段名:商家核身单号
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  body商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+   *  示例值:mcdhehfgisdhfjghed39384564i83
+   * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + + /** + *
+   * 字段名:项目名称
+   * 变量名:project_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   * body该项目的名称
+   * 示例值:某项目
+   * 
+ */ + @SerializedName(value = "project_name") + private String projectName; + /** + *
+   * 字段名:单位名称
+   * 变量名:employer_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   * body该用户所属的单位名称
+   * 示例值:某单位名称
+   * 
+ */ + @SerializedName(value = "employer_name") + private String employerName; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderResult.java new file mode 100644 index 0000000000..dbe909ac69 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderResult.java @@ -0,0 +1,111 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 微工卡核身预下单
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_3.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class PreOrderResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:商家核身单号
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+   *  示例值:mcdhehfgisdhfjghed39384564i83
+   * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:服务商商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商商户的商户号,由微信支付生成并下发。
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:授权token
+   * 变量名:token
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  授权token
+   *  示例值:abcdefghijklmn
+   * 
+ */ + @SerializedName(value = "token") + private String token; + + /** + *
+   * 字段名:token有效时间
+   * 变量名:expires_in
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * token有效时间,单位秒
+   * 示例值:1800
+   * 
+ */ + @SerializedName(value = "expires_in") + private Integer expiresIn; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthRequest.java new file mode 100644 index 0000000000..5f4e8ae57b --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthRequest.java @@ -0,0 +1,169 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 微工卡核身预下单(流程中完成授权)
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_1.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order-with-auth
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class PreOrderWithAuthRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:应用ID
+   * 变量名:appid
+   * 是否必填:二选一
+   * 类型:string[1, 32]
+   * 描述:
+   *   是服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID(与服务商主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。
+   *  当输入应用ID时,会校验其与服务商商户号的绑定关系。服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   * 示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:子商户应用ID
+   * 变量名:sub_appid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  是特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID(与特约商户主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。当输入子商户应用ID时,会校验其与特约商户号的绑定关系。 服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+   * 字段名:商家核身单号
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+   *  示例值:mcdhehfgisdhfjghed39384564i83
+   * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + + /** + *
+   * 字段名:项目名称
+   * 变量名:project_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   *  该项目的名称
+   *  示例值:某项目
+   * 
+ */ + @SerializedName(value = "project_name") + private String projectName; + /** + *
+   * 字段名:用工单位名称
+   * 变量名:employer_name
+   * 是否必填:是
+   * 类型:string[1, 12]
+   * 描述:
+   *    该用户所属的单位名称。
+   *     示例值:某单位名称
+   * 
+ */ + @SerializedName(value = "employer_name") + private String employerName; + + /** + *
+   * 字段名:用户实名
+   * 变量名:user_name
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  用户证件号,该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+   * 示例值:7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5
+   * 
+ */ + @SerializedName(value = "user_name") + private String userName; + + /** + *
+   * 字段名:用户证件号
+   * 变量名:id_card_number
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  用户证件号,该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+   * 示例值:7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5
+   * 
+ */ + @SerializedName(value = "id_card_number") + private String idCardNumber; + + /** + *
+   * 字段名:用工类型
+   * 变量名:employment_type
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  微工卡服务仅支持用于与商户有用工关系的用户,需明确用工类型;参考值:
+   * LONG_TERM_EMPLOYMENT:长期用工,
+   * SHORT_TERM_EMPLOYMENT: 短期用工,
+   * COOPERATION_EMPLOYMENT:合作关系
+   * 示例值:LONG_TERM_EMPLOYMENT
+   * 
+ */ + @SerializedName(value = "employment_type") + private String employmentType; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthResult.java new file mode 100644 index 0000000000..235ac056d5 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/PreOrderWithAuthResult.java @@ -0,0 +1,110 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 微工卡核身预下单(流程中完成授权)
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_1.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order-with-auth
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class PreOrderWithAuthResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:商家核身单号
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  商户系统内部的商家核身单号,要求此参数只能由数字、大小写字母组成,在服务商内部唯一
+   *  示例值:mcdhehfgisdhfjghed39384564i83
+   * 
+ */ + @SerializedName(value = "authenticate_number") + private String authenticateNumber; + + /** + *
+   * 字段名:用户标识
+   * 变量名:authenticate_number
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   * 示例值:onqOjjmo8wmTOOtSKwXtGjg9Gb58
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商商户的商户号,由微信支付生成并下发
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "mchid") + private Integer mchid; + + /** + *
+   * 字段名:特约商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   *  示例值:1900000109
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:授权token
+   * 变量名:token
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  授权token
+   *  示例值:abcdefghijklmn
+   * 
+ */ + @SerializedName(value = "token") + private String token; + + /** + *
+   * 字段名:token有效时间
+   * 变量名:expires_in
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * token有效时间,单位秒
+   * 示例值:300
+   * 
+ */ + @SerializedName(value = "expires_in") + private Integer expiresIn; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsRequest.java new file mode 100644 index 0000000000..e2d77abb2f --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsRequest.java @@ -0,0 +1,83 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 查询微工卡授权关系
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_2.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/relations/{openid}
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class RelationsRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   * 示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:应用ID
+   * 变量名:appid
+   * 是否必填:二选一
+   * 类型:string[1, 32]
+   * 描述:
+   *   是服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID(与服务商主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。
+   *  当输入应用ID时,会校验其与服务商商户号的绑定关系。服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:子商户应用ID
+   * 变量名:sub_appid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  是特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID(与特约商户主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。当输入子商户应用ID时,会校验其与特约商户号的绑定关系。 服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsResult.java new file mode 100644 index 0000000000..70225850c7 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/RelationsResult.java @@ -0,0 +1,114 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 查询微工卡授权关系
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_2.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/relations/{openid}
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class RelationsResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:服务商商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商商户的商户号,由微信支付生成并下发。
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:授权状态
+   * 变量名:authorize_state
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  授权状态:
+   *      UNAUTHORIZED:未授权
+   *      AUTHORIZED:已授权
+   *      DEAUTHORIZED:已取消授权
+   * 示例值:UNAUTHORIZED
+   * 
+ */ + @SerializedName(value = "authorize_state") + private String authorizeState; + + /** + *
+   * 字段名:授权时间
+   * 变量名:authorize_time
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  授权时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒。
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "authorize_time") + private String authorizeTime; + + /** + *
+   * 字段名:取消授权时间
+   * 变量名:deauthorize_time
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  取消授权时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒。
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "deauthorize_time") + private String deauthorizeTime; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/SubFundFlowBillResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/SubFundFlowBillResult.java new file mode 100644 index 0000000000..f1c9d3abdc --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/SubFundFlowBillResult.java @@ -0,0 +1,100 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 申请单个子商户资金账单
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_25.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/bill/sub-merchant-fundflowbill
+ * 请求方式:GET
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/7 + */ +@Data +@NoArgsConstructor +public class SubFundFlowBillResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  query下载指定子商户的账单。
+   *  示例值:19000000001
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:账单日期
+   * 变量名:bill_date
+   * 是否必填:是
+   * 类型:string[10, 10]
+   * 描述:
+   *  query格式YYYY-MM-DD
+   *  示例值:2019-06-11
+   * 
+ */ + @SerializedName(value = "bill_date") + private String billDate; + + /** + *
+   * 字段名:资金账户类型
+   * 变量名:account_type
+   * 是否必填:是
+   * 类型:string[1, 16]
+   * 描述:
+   * query枚举值:
+   *     BASIC:基本账户
+   *     OPERATION:运营账户
+   *     FEES:手续费账户
+   * 示例值:BASIC
+   * 
+ */ + @SerializedName(value = "account_type") + private String accountType; + /** + *
+   * 字段名:加密算法
+   * 变量名:algorithm
+   * 是否必填:是
+   * 类型:string[1, 31]
+   * 描述:
+   * query枚举值:
+   *     AEAD_AES_256_GCM:AEAD_AES_256_GCM加密算法
+   * 示例值:AEAD_AES_256_GCM
+   * 
+ */ + @SerializedName(value = "algorithm") + private String algorithm; + /** + *
+   * 字段名:压缩格式
+   * 变量名:tar_type
+   * 是否必填:否
+   * 类型:string[1, 8]
+   * 描述:
+   * query不填则以不压缩的方式返回数据流
+   *     枚举值:
+   *     GZIP:返回格式为.gzip的压缩包账单
+   * 示例值:GZIP
+   * 
+ */ + @SerializedName(value = "tar_type") + private String tarType; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensRequest.java new file mode 100644 index 0000000000..f760a10f95 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensRequest.java @@ -0,0 +1,128 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 生成授权token
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_1.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/tokens
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class TokensRequest implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:应用ID
+   * 变量名:appid
+   * 是否必填:二选一
+   * 类型:string[1, 32]
+   * 描述:
+   *   是服务商在微信申请公众号/小程序或移动应用成功后分配的账号ID(与服务商主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。
+   *  当输入应用ID时,会校验其与服务商商户号的绑定关系。服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "appid") + private String appid; + + /** + *
+   * 字段名:子商户应用ID
+   * 变量名:sub_appid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  是特约商户在微信申请公众号/小程序或移动应用成功后分配的账号ID(与特约商户主体一致),登录平台为mp.weixin.qq.com或open.weixin.qq.com。当输入子商户应用ID时,会校验其与特约商户号的绑定关系。 服务商应用ID和与子商户应用ID至少输入一个,且必须要有拉起微工卡时使用的APPID。
+   *  示例值:wxa1111111
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   * 示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:用户实名
+   * 变量名:user_name
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  用户证件号,该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+   * 示例值:7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5
+   * 
+ */ + @SerializedName(value = "user_name") + private String userName; + + /** + *
+   * 字段名:用户证件号
+   * 变量名:id_card_number
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  用户证件号,该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+   * 示例值:7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5
+   * 
+ */ + @SerializedName(value = "id_card_number") + private String idCardNumber; + + /** + *
+   * 字段名:用工类型
+   * 变量名:employment_type
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  微工卡服务仅支持用于与商户有用工关系的用户,需明确用工类型;参考值:
+   * LONG_TERM_EMPLOYMENT:长期用工,
+   * SHORT_TERM_EMPLOYMENT: 短期用工,
+   * COOPERATION_EMPLOYMENT:合作关系
+   * 示例值:LONG_TERM_EMPLOYMENT
+   * 
+ */ + @SerializedName(value = "employment_type") + private String employmentType; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensResult.java new file mode 100644 index 0000000000..c49286436d --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/payroll/TokensResult.java @@ -0,0 +1,97 @@ +package com.github.binarywang.wxpay.bean.marketing.payroll; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + *
+ * 生成授权token
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3_partner/Offline/apis/chapter4_1_1.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/tokens
+ * 请求方式:POST
+ * 
+ * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Data +@NoArgsConstructor +public class TokensResult implements Serializable { + private static final long serialVersionUID = 1L; + + /** + *
+   * 字段名:用户标识
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   *  用户在商户对应appid下的唯一标识
+   *  示例值:9x111111
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+   * 字段名:服务商商户号
+   * 变量名:mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商商户的商户号,由微信支付生成并下发。
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "mchid") + private String mchid; + + /** + *
+   * 字段名:子商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信服务商下特约商户的商户号,由微信支付生成并下发
+   *  示例值:1111111
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:授权token
+   * 变量名:token
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   *  授权token
+   *  示例值:abcdefghijklmn
+   * 
+ */ + @SerializedName(value = "token") + private String token; + + /** + *
+   * 字段名:token有效时间
+   * 变量名:expires_in
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * token有效时间,单位秒
+   * 示例值:1800
+   * 
+ */ + @SerializedName(value = "expires_in") + private Integer expiresIn; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsRequest.java new file mode 100644 index 0000000000..aeb778f690 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsRequest.java @@ -0,0 +1,53 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +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/wxpay/pay/transfer_partner/chapter3_3.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id}
+ * 请求方式:GET
+ * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class BatchDetailsRequest implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:微信支付批次单号
+   * 变量名:need_query_detail
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   *  path微信支付批次单号,微信商家转账系统返回的唯一标识
+   *  示例值:1030000071100999991182020050700019480001
+   * 
+ */ + @SerializedName(value = "batch_id") + private String batchId; + /** + *
+   * 字段名:微信明细单号
+   * 变量名:need_query_detail
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   *  path微信支付系统内部区分转账批次单下不同转账明细单的唯一标识
+   *  示例值:1040000071100999991182020050700019500100
+   * 
+ */ + @SerializedName(value = "detail_id") + private String detailId; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsResult.java new file mode 100644 index 0000000000..0ca10dcb40 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchDetailsResult.java @@ -0,0 +1,239 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; +import java.util.Date; + +/** + *
+ * 微信支付明细单号查询明细单API
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_3.shtml
+ *
+ * 适用对象:服务商
+ * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id}
+ * 请求方式:GET
+ * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class BatchDetailsResult implements Serializable { + public static final float serialVersionUID = 1L; + + @Override + public String toString() { + return WxGsonBuilder.create().toJson(this); + } + + /** + *
+   * 字段名:服务商商户号
+   * 变量名:sp_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信支付分配的商户号,此处为服务商商户号
+   *  示例值:1900001109
+   * 
+ */ + @SerializedName(value = "sp_mchid") + private String spMchid; + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  商户系统内部的商家批次单号,在商户系统内部唯一
+   *     示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + /** + *
+   * 字段名:微信支付批次单号
+   * 变量名:batch_id
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  微信支付批次单号,微信商家转账系统返回的唯一标识
+   *     示例值:1030000071100999991182020050700019480001
+   * 
+ */ + @SerializedName(value = "batch_id") + private String batchId; + /** + *
+   * 字段名:商户的appid
+   * 变量名:
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   * 微信分配的特约商户公众账号ID。特约商户授权类型为 INFORMATION_AUTHORIZATION_TYPE和
+   *     INFORMATION_AND_FUND_AUTHORIZATION_TYPE时对应的是特约商户的appid,
+   *     特约商户授权类型为FUND_AUTHORIZATION_TYPE时为服务商的appid
+   * 例值:wxf636efh567hg4356
+   * 
+ */ + @Expose + @SerializedName(value = "appid") + private String appId; + /** + *
+   * 字段名:商家明细单号
+   * 变量名:out_detail_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   * 商户系统内部区分转账批次单下不同转账明细单的唯一标识
+   *     示例值:x23zy545Bd5436
+   * 
+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; + /** + *
+   * 字段名:微信支付明细单号
+   * 变量名:detail_id
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   * 微信支付系统内部区分转账批次单下不同转账明细单的唯一标识
+   *     示例值:1040000071100999991182020050700019500100
+   * 
+ */ + @SerializedName(value = "detail_id") + private String detailId; + /** + *
+   * 字段名:明细状态
+   * 变量名:detail_status
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * 枚举值:
+   *     PROCESSING:转账中。正在处理中,转账结果尚未明确
+   *     SUCCESS:转账成功
+   *     FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单)
+   * 示例值:SUCCESS
+   * 
+ */ + @SerializedName(value = "detail_status") + private String detailStatus; + /** + *
+   * 字段名:转账金额
+   * 变量名:transfer_amount
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   * 转账金额单位为“分”
+   *     示例值:200000
+   * 
+ */ + @SerializedName(value = "transfer_amount") + private Integer transferAmount; + /** + *
+   * 字段名:转账备注
+   * 变量名:transfer_remark
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * 单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符
+   *     示例值:2020年4月报销
+   * 
+ */ + @SerializedName(value = "transfer_remark") + private String transferRemark; + /** + *
+   * 字段名:明细失败原因
+   * 变量名:fail_reason
+   * 是否必填:否
+   * 类型:string[1, 64]
+   * 描述:
+   * 如果转账失败则有失败原因:
+   *     ACCOUNT_FROZEN:账户冻结
+   *     REAL_NAME_CHECK_FAIL:用户未实名
+   *     NAME_NOT_CORRECT:用户姓名校验失败
+   *     OPENID_INVALID:Openid校验失败
+   *     TRANSFER_QUOTA_EXCEED:超过用户单笔收款额度
+   *     DAY_RECEIVED_QUOTA_EXCEED:超过用户单日收款额度
+   *     MONTH_RECEIVED_QUOTA_EXCEED:超过用户单月收款额度
+   *     DAY_RECEIVED_COUNT_EXCEED:超过用户单日收款次数
+   *     PRODUCT_AUTH_CHECK_FAIL:产品权限校验失败
+   *     OVERDUE_CLOSE:转账关闭
+   *     ID_CARD_NOT_CORRECT:用户身份证校验失败
+   *     ACCOUNT_NOT_EXIST:用户账户不存在
+   *     TRANSFER_RISK:转账存在风险
+   * 示例值:ACCOUNT_FROZEN
+   * 
+ */ + @SerializedName(value = "fail_reason") + private String failReason; + /** + *
+   * 字段名:收款用户openid
+   * 变量名:openid
+   * 是否必填:是
+   * 类型:string[1, 64]
+   * 描述:
+   * 收款用户openid。如果转账特约商户授权类型是INFORMATION_AUTHORIZATION_TYPE,对应的是特约商户公众号下的openid;
+   *     如果转账特约商户授权类型是FUND_AUTHORIZATION_TYPE,对应的是服务商商户公众号下的openid。
+   * 示例值:o-MYE42l80oelYMDE34nYD456Xoy
+   * 
+ */ + @SerializedName(value = "openid") + private String openid; + /** + *
+   * 字段名:收款用户姓名
+   * 变量名:username
+   * 是否必填:是
+   * 类型:string[1, 1024]
+   * 描述:
+   * 1、收款方姓名。采用标准RSA算法,公钥由微信侧提供
+   * 2、该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+   *     示例值:757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45
+   * 
+ */ + @SerializedName(value = "username") + private String userName; + /** + *
+   * 字段名:转账发起时间
+   * 变量名:initiate_time
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * 转账发起的时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *     示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "initiate_time") + private String initiateTime; + /** + *
+   * 字段名:明细更新时间
+   * 变量名:initiate_time
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   * 明细最后一次状态变更的时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *     示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "update_time") + private Date updateTime; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberRequest.java new file mode 100644 index 0000000000..904fc2d03a --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberRequest.java @@ -0,0 +1,96 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +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/wxpay/pay/transfer_partner/chapter3_2.shtml
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class BatchNumberRequest implements Serializable { + public static final float serialVersionUID = 1L; + + /** + *
+   * 字段名:微信支付批次单号
+   * 变量名:batch_id
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   *  path微信支付批次单号,微信商家转账系统返回的唯一标识
+   *  示例值:1030000071100999991182020050700019480001
+   * 
+ */ + @SerializedName(value = "batch_id") + private String batchId; + + /** + *
+   * 字段名:是否查询转账明细单
+   * 变量名:need_query_detail
+   * 是否必填:是
+   * 类型:boolean 默认否
+   * 描述:
+   *  商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单
+   *  示例值:true
+   * 
+ */ + @SerializedName(value = "need_query_detail") + private Boolean needQueryDetail; + + /** + *
+   * 字段名:请求资源起始位置
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  query该次请求资源的起始位置。返回的明细是按照设置的明细条数进行分页展示的,一次查询可能无法返回所有明细,我们使用该参数标识查询开始位置,默认值为0
+   *  示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + + /** + *
+   * 字段名:最大资源条数
+   * 变量名:limit
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  query该次请求可返回的最大明细条数,最小20条,最大100条,不传则默认20条。不足20条按实际条数返回
+   * 示例值:20
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; + + /** + *
+   * 字段名:明细状态
+   * 变量名:detail_status
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  query查询指定状态的转账明细单,不传没有明细状态信息返回。当need_query_detail为true时,该字段必填
+   *  枚举值:
+   *     ALL:全部。需要同时查询转账成功和转账失败的明细单
+   *     SUCCESS:转账成功。只查询转账成功的明细单
+   *     FAIL:转账失败。只查询转账失败的明细单
+   *  示例值:FAIL
+   * 
+ */ + @SerializedName(value = "detail_status") + private String detailStatus; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberResult.java new file mode 100644 index 0000000000..9f1036d229 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BatchNumberResult.java @@ -0,0 +1,393 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; +import java.util.List; + +/** + *
+ * 微信支付批次单号查询批次单API
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_2.shtml
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class BatchNumberResult implements Serializable { + public static final float serialVersionUID = 1L; + + @Override + public String toString() { + return WxGsonBuilder.create().toJson(this); + } + + /** + *
+   * 字段名:服务商商户号
+   * 变量名:sp_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信支付分配的服务商商户号
+   *  示例值:1900001109
+   * 
+ */ + @SerializedName(value = "sp_mchid") + private String spMchid; + + /** + *
+   * 字段名:特约商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信支付分配的特约商户号
+   *  示例值:1900000109
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  商户系统内部的商家批次单号,在商户系统内部唯一
+   *  示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:微信支付批次单号
+   * 变量名:batch_id
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   *  微信支付批次单号,微信商家转账系统返回的唯一标识
+   *  示例值:1030000071100999991182020050700019480001
+   * 
+ */ + @SerializedName(value = "batch_id") + private String batchId; + /** + *
+   * 字段名:特约商户appid
+   * 变量名:sub_appid
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  微信分配的特约商户公众账号ID。特约商户appid
+   *   示例值:wxf636efh567hg4356
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + /** + *
+   * 字段名:批次状态
+   * 变量名:batch_status
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  枚举值:
+   *     WAIT_PAY:待付款,商户员工确认付款阶段。
+   *     ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等。商户可查询账户资金流水,若该笔转账批次单的扣款已经发生,则表示批次已经进入转账中,请再次查单确认
+   *     PROCESSING:转账中。已开始处理批次内的转账明细单
+   *     FINISHED:已完成。批次内的所有转账明细单都已处理完成
+   *     CLOSED:已关闭。可查询具体的批次关闭原因确认
+   *  示例值:ACCEPTED
+   * 
+ */ + @SerializedName(value = "batch_status") + private String batchStatus; + + /** + *
+   * 字段名:批次类型
+   * 变量名:batch_type
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  枚举值:
+   *     API:API方式发起
+   *     WEB:页面方式发起
+   * 示例值:API
+   * 
+ */ + @SerializedName(value = "batch_type") + private String batchType; + + /** + *
+   * 字段名:特约商户授权类型
+   * 变量名:authorization_type
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  特约商户授权类型:
+   *     INFORMATION_AUTHORIZATION_TYPE:信息授权类型
+   *     FUND_AUTHORIZATION_TYPE:资金授权类型
+   *     INFORMATION_AND_FUND_AUTHORIZATION_TYPE:信息和资金授权类型
+   * 示例值:INFORMATION_AUTHORIZATION_TYPE
+   * 
+ */ + @SerializedName(value = "authorization_type") + private String authorizationType; + + /** + *
+   * 字段名:批次名称
+   * 变量名: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, 64]
+   * 描述:
+   *    如果批次单状态为“CLOSED”(已关闭),则有关闭原因:
+   *     MERCHANT_REVOCATION:商户主动撤销
+   *     OVERDUE_CLOSE:系统超时关闭
+   * 示例值:OVERDUE_CLOSE
+   * 
+ */ + @SerializedName(value = "close_reason") + private String closeReason; + + /** + *
+   * 字段名:转账总金额
+   * 变量名:total_amount
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *   转账金额单位为“分”
+   * 示例值:4000000
+   * 
+ */ + @SerializedName(value = "total_amount") + private Integer 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,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   * 示例值: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,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "update_time") + private String updateTime; + /** + *
+   * 字段名:转账成功金额
+   * 变量名:success_amount
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  转账成功的金额,单位为“分”。当批次状态为“PROCESSING”(转账中)时,转账成功金额随时可能变化
+   *  示例值:3900000
+   * 
+ */ + @SerializedName(value = "success_amount") + private Integer successAmount; + /** + *
+   * 字段名:转账成功笔数
+   * 变量名:success_num
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  转账成功的笔数。当批次状态为“PROCESSING”(转账中)时,转账成功笔数随时可能变化
+   * 示例值:199
+   * 
+ */ + @SerializedName(value = "success_num") + private Integer successNum; + /** + *
+   * 字段名:转账失败金额
+   * 变量名:fail_amount
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  转账失败的金额,单位为“分”
+   *     示例值:100000
+   * 
+ */ + @SerializedName(value = "fail_amount") + private Integer failAmount; + /** + *
+   * 字段名:转账失败笔数
+   * 变量名:fail_amount
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  转账失败的笔数
+   *     示例值:1
+   * 
+ */ + @SerializedName(value = "fail_num") + private Integer failNum; + /** + *
+   * 字段名:转账明细单列表
+   * 变量名:transfer_detail_list
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  当批次状态为“FINISHED”(已完成),且成功查询到转账明细单时返回。包括微信明细单号、明细状态信息
+   * 
+ */ + @SerializedName(value = "transfer_detail_list") + private List transferDetailList; + + @Data + @NoArgsConstructor + public static class TransferDetail implements Serializable { + private static final long serialVersionUID = 10941148801492L; + /** + *
+     * 字段名:微信支付明细单号
+     * 变量名:detail_id
+     * 是否必填:是
+     * 类型:string[32, 64]
+     * 描述:
+     *  微信支付系统内部区分转账批次单下不同转账明细单的唯一标识
+     *  示例值:1040000071100999991182020050700019500100
+     * 
+ */ + @SerializedName(value = "detail_id") + private String detailId; + + /** + *
+     * 字段名:商家明细单号
+     * 变量名:out_detail_no
+     * 是否必填:是
+     * 类型:string[5, 32]
+     * 描述:
+     *  商户系统内部区分转账批次单下不同转账明细单的唯一标识
+     *  示例值:x23zy545Bd5436
+     * 
+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; + + /** + *
+     * 字段名:明细状态
+     * 变量名:detail_status
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *     枚举值:
+     *         PROCESSING:转账中。正在处理中,转账结果尚未明确
+     *         SUCCESS:转账成功
+     *         FAIL:转账失败。需要确认失败原因后,再决定是否重新发起对该笔明细单的转账(并非整个转账批次单)
+     * 示例值:SUCCESS
+     * 
+ */ + @SerializedName(value = "detail_status") + private String detailStatus; + } + + /** + *
+   * 字段名:服务商的appid
+   * 变量名:sp_appid
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *    微信分配的服务商商户公众账号ID,特约商户授权类型为FUND_AUTHORIZATION_TYPE时才有该字段
+   *     示例值:wxf636efh567hg4388
+   * 
+ */ + @SerializedName(value = "sp_appid") + private String spAppid; + /** + *
+   * 字段名:批量转账用途
+   * 变量名:transfer_purpose
+   * 是否必填:否
+   * 类型:string[1,16]
+   * 描述:
+   *   批量转账用途:
+   *     GOODSPAYMENT:货款
+   *     COMMISSION:佣金
+   *     REFUND:退款
+   *     REIMBURSEMENT:报销
+   *     FREIGHT:运费
+   *     OTHERS:其他
+   * 示例值:COMMISSION
+   * 
+ */ + @SerializedName(value = "transfer_purpose") + private String transferPurpose; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BillReceiptResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BillReceiptResult.java new file mode 100644 index 0000000000..a6f98e6aa1 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/BillReceiptResult.java @@ -0,0 +1,143 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; +import me.chanjar.weixin.common.util.json.WxGsonBuilder; + +import java.io.Serializable; + +/** + * 转账电子回单申请受理API + * 接口说明 + * 适用对象:直连商户 服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer/bill-receipt + * 请求方式:POST + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class BillReceiptResult implements Serializable { + public static final float serialVersionUID = 1L; + + @Override + public String toString() { + return WxGsonBuilder.create().toJson(this); + } + + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5,32]
+   * 描述:
+   *  商户系统内部的商家批次单号,在商户系统内部唯一。需要电子回单的批次单号
+   *  示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:电子回单申请单号
+   * 变量名:signature_no
+   * 是否必填:是
+   * 类型:string[3.45]
+   * 描述:
+   *  电子回单申请单号,申请单据的唯一标识
+   *     示例值:1050000010509999485212020110200058820001
+   * 
+ */ + @SerializedName(value = "signature_no") + private String signatureNo; + + /** + *
+   * 字段名:电子回单状态
+   * 变量名:signature_status
+   * 是否必填:否
+   * 类型:string[1,10]
+   * 描述:
+   *  枚举值:
+   *     ACCEPTED:已受理,电子签章已受理成功
+   *     FINISHED:已完成。电子签章已处理完成
+   *     示例值:ACCEPTED
+   * 
+ */ + @SerializedName(value = "signature_status") + private String signatureStatus; + + /** + *
+   * 字段名:电子回单文件的hash方法
+   * 变量名:hash_type
+   * 是否必填:否
+   * 类型:string[1,20]
+   * 描述:
+   *  电子回单文件的hash方法,回单状态为:FINISHED时返回。
+   *     示例值:SHA256
+   * 
+ */ + @SerializedName(value = "hash_type") + private String hashType; + + /** + *
+   * 字段名:电子回单文件的hash值
+   * 变量名:hash_value
+   * 是否必填:否
+   * 类型:string[3,1000]
+   * 描述:
+   *  电子回单文件的hash值,用于下载之后验证文件的完整、正确性,回单状态为:FINISHED时返回。
+   *     示例值:DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529
+   * 
+ */ + @SerializedName(value = "hash_value") + private String hashValue; + + + /** + *
+   * 字段名:电子回单文件的下载地址
+   * 变量名:hash_value
+   * 是否必填:否
+   * 类型:string[10,3000]
+   * 描述:
+   *  电子回单文件的下载地址,回单状态为:FINISHED时返回。URL有效时长为10分钟,10分钟后需要重新去获取下载地址
+   *     示例值:https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx
+   * 
+ */ + @SerializedName(value = "download_url") + private String downloadUrl; + + /** + *
+   * 字段名:创建时间
+   * 变量名:create_time
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   * 	电子签章单创建时间,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *     示例值:2020-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,YYYY-MM-DD表示年月日,T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *     示例值:2020-05-21T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "update_time") + private String updateTime; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/DownloadRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/DownloadRequest.java new file mode 100644 index 0000000000..639b2cd572 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/DownloadRequest.java @@ -0,0 +1,65 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 下载电子回单API + * 接口说明 + * 适用对象:直连商户 服务商 + * 请求URL:通过申请账单接口获取到“download_url”,URL有效期10min + * 请求方式:GET + * 前置条件:调用申请账单接口并获取到“download_url” + * 接口规则:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class DownloadRequest implements Serializable { + public static final float serialVersionUID = 1L; + + /** + *
+   * 字段名:电子回单文件的hash方法
+   * 变量名:hash_type
+   * 是否必填:否
+   * 类型:string[1, 20]
+   * 描述:
+   *  电子回单文件的hash方法,回单状态为:FINISHED时返回
+   *  例值:SHA256
+   * 
+ */ + @SerializedName(value = "hash_type") + private String hashType; + /** + *
+   * 字段名:电子回单文件的hash值
+   * 变量名:hash_value
+   * 是否必填:否
+   * 类型:string[3, 1000]
+   * 描述:
+   *  电子回单文件的hash值,用于下载之后验证文件的完整、正确性,回单状态为:FINISHED时返回
+   *  示例值:DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529
+   * 
+ */ + @SerializedName(value = "hash_value") + private String hashValue; + /** + *
+   * 字段名:电子回单文件的下载地址
+   * 变量名:download_url
+   * 是否必填:否
+   * 类型:string[10, 3000]
+   * 描述:
+   *  电子回单文件的下载地址,回单状态为:FINISHED时返回。URL有效时长为10分钟,10分钟后需要重新去获取下载地址(但不需要走受理)
+   * 示例值:https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx
+   * 
+ */ + @SerializedName(value = "download_url") + private String downloadUrl; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsRequest.java new file mode 100644 index 0000000000..6c54cbc9c9 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsRequest.java @@ -0,0 +1,70 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 转账明细电子回单受理API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:POST + * 前置条件:只支持受理最近90天内的转账明细单 + * 接口规则:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class ElectronicReceiptsRequest implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:受理类型
+   * 变量名:accept_type
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  body电子回单受理类型:
+   *     BATCH_TRANSFER:批量转账明细电子回单
+   *     TRANSFER_TO_POCKET:企业付款至零钱电子回单
+   *     TRANSFER_TO_BANK:企业付款至银行卡电子回单
+   * 示例值:BATCH_TRANSFER
+   * 
+ */ + @SerializedName(value = "accept_type") + private String acceptType; + + /** + *
+   * 字段名:商家转账批次单号
+   * 变量名:out_batch_no
+   * 是否必填:否
+   * 类型:string[5, 32]
+   * 描述:
+   *  body需要电子回单的批量转账明细单所在的转账批次单号,该单号为商户申请转账时生成的商户单号。受理类型为BATCH_TRANSFER时该单号必填,否则该单号留空。
+   *  示例值:GD2021011610162610BBdkkIwcu3
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:商家转账明细单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  body该单号为商户申请转账时生成的商家转账明细单号。
+   *             1.受理类型为BATCH_TRANSFER时填写商家批量转账明细单号。
+   *             2. 受理类型为TRANSFER_TO_POCKET或TRANSFER_TO_BANK时填写商家转账单号。
+   *  示例值:mx0911231610162610v4CNkO4HAf
+   * 
+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsResult.java new file mode 100644 index 0000000000..75d1243e4c --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ElectronicReceiptsResult.java @@ -0,0 +1,137 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 转账明细电子回单受理API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:POST + * 前置条件:只支持受理最近90天内的转账明细单 + * 接口规则:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class ElectronicReceiptsResult implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:受理类型
+   * 变量名:accept_type
+   * 是否必填:是
+   * 类型:string[1,32]
+   * 描述:
+   *  电子回单受理类型:
+   *     BATCH_TRANSFER:批量转账明细电子回单
+   *     TRANSFER_TO_POCKET:企业付款至零钱电子回单
+   *     TRANSFER_TO_BANK:企业付款至银行卡电子回单
+   *  示例值:BATCH_TRANSFER
+   * 
+ */ + @SerializedName(value = "accept_type") + private String acceptType; + + /** + *
+   * 字段名:商家转账批次单号
+   * 变量名:out_batch_no
+   * 是否必填:否
+   * 类型:string[5, 32]
+   * 描述:
+   *  需要电子回单的批量转账明细单所在的转账批次单号,该单号为商户申请转账时生成的商户单号。受理类型为BATCH_TRANSFER时该单号必填,否则该单号留空。
+   *  示例值:GD2021011610162610BBdkkIwcu3
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:商家转账明细单号
+   * 变量名:out_detail_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  该单号为商户申请转账时生成的商家转账明细单号。
+   *     1.受理类型为BATCH_TRANSFER时填写商家批量转账明细单号。
+   *     2. 受理类型为TRANSFER_TO_POCKET或TRANSFER_TO_BANK时填写商家转账单号。
+   *  示例值:mx0911231610162610v4CNkO4HAf
+   * 
+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; + /** + *
+   * 字段名:电子回单受理单号
+   * 变量名:signature_no
+   * 是否必填:是
+   * 类型:string[3, 256]
+   * 描述:
+   *  电子回单受理单号,受理单据的唯一标识
+   *  示例值:1050000010509999485212020110200058820001
+   * 
+ */ + @SerializedName(value = "signature_no") + private String signatureNo; + /** + *
+   * 字段名:电子回单状态
+   * 变量名:signature_status
+   * 是否必填:否
+   * 类型:string[1, 10]
+   * 描述:
+   *  枚举值:
+   *     ACCEPTED:已受理,电子签章已受理成功
+   *     FINISHED:已完成。电子签章已处理完成
+   *  示例值:ACCEPTED
+   * 
+ */ + @SerializedName(value = "signature_status") + private String signatureStatus; + /** + *
+   * 字段名:电子回单文件的hash方法
+   * 变量名:hash_type
+   * 是否必填:否
+   * 类型:string[1, 20]
+   * 描述:
+   *  电子回单文件的hash方法,回单状态为:FINISHED时返回
+   *  例值:SHA256
+   * 
+ */ + @SerializedName(value = "hash_type") + private String hashType; + /** + *
+   * 字段名:电子回单文件的hash值
+   * 变量名:hash_value
+   * 是否必填:否
+   * 类型:string[3, 1000]
+   * 描述:
+   *  电子回单文件的hash值,用于下载之后验证文件的完整、正确性,回单状态为:FINISHED时返回
+   *  示例值:DE731F35146A0BEFADE5DB9D1E468D96C01CA8898119C674FEE9F11F4DBE5529
+   * 
+ */ + @SerializedName(value = "hash_value") + private String hashValue; + /** + *
+   * 字段名:电子回单文件的下载地址
+   * 变量名:download_url
+   * 是否必填:否
+   * 类型:string[10, 3000]
+   * 描述:
+   *  电子回单文件的下载地址,回单状态为:FINISHED时返回。URL有效时长为10分钟,10分钟后需要重新去获取下载地址(但不需要走受理)
+   * 示例值:https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx
+   * 
+ */ + @SerializedName(value = "download_url") + private String downloadUrl; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/MerchantBatchRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/MerchantBatchRequest.java new file mode 100644 index 0000000000..3a1e3ed80d --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/MerchantBatchRequest.java @@ -0,0 +1,97 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; + +/** + * 商家批次单号查询批次单API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/out-batch-no/{out_batch_no} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * 接口规则:https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay-1.shtml + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class MerchantBatchRequest implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  path商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
+   *     示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:是否查询转账明细单
+   * 变量名:need_query_detail
+   * 是否必填:是
+   * 类型:boolean 默认否
+   * 描述:
+   *  商户可选择是否查询指定状态的转账明细单,当转账批次单状态为“FINISHED”(已完成)时,才会返回满足条件的转账明细单
+   *  示例值:true
+   * 
+ */ + @SerializedName(value = "need_query_detail") + private Boolean needQueryDetail; + + /** + *
+   * 字段名:请求资源起始位置
+   * 变量名:offset
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  query该次请求资源的起始位置。返回的明细是按照设置的明细条数进行分页展示的,一次查询可能无法返回所有明细,我们使用该参数标识查询开始位置,默认值为0
+   *  示例值:0
+   * 
+ */ + @SerializedName(value = "offset") + private Integer offset; + + /** + *
+   * 字段名:最大资源条数
+   * 变量名:limit
+   * 是否必填:否
+   * 类型:int
+   * 描述:
+   *  query该次请求可返回的最大明细条数,最小20条,最大100条,不传则默认20条。不足20条按实际条数返回
+   * 示例值:20
+   * 
+ */ + @SerializedName(value = "limit") + private Integer limit; + + /** + *
+   * 字段名:明细状态
+   * 变量名:detail_status
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  query查询指定状态的转账明细单,不传没有明细状态信息返回。当need_query_detail为true时,该字段必填
+   *  枚举值:
+   *     ALL:全部。需要同时查询转账成功和转账失败的明细单
+   *     SUCCESS:转账成功。只查询转账成功的明细单
+   *     FAIL:转账失败。只查询转账失败的明细单
+   *  示例值:FAIL
+   * 
+ */ + @SerializedName(value = "detail_status") + private String detailStatus; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferRequest.java new file mode 100644 index 0000000000..ce4738ae1f --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferRequest.java @@ -0,0 +1,289 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +import com.google.gson.annotations.SerializedName; +import lombok.Data; +import lombok.NoArgsConstructor; + +import java.io.Serializable; +import java.util.List; + +/** + * 发起批量转账API + *
+ * 文档地址:https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer_partner/chapter3_1.shtml
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class PartnerTransferRequest implements Serializable { + public static final float serialVersionUID = 1L; + + /** + *
+   * 字段名:特约商户号
+   * 变量名:sub_mchid
+   * 是否必填:是
+   * 类型:string(32)
+   * 描述:
+   *  特约商户号
+   *  示例值:1900000109
+   * 
+ */ + @SerializedName(value = "sub_mchid") + private String subMchid; + + /** + *
+   * 字段名:特约商户appid
+   * 变量名:sub_appid
+   * 是否必填:否
+   * 类型:string(32)
+   * 描述:
+   *  示例值:wxf636efh567hg4356
+   * 
+ */ + @SerializedName(value = "sub_appid") + private String subAppid; + + /** + *
+   * 字段名:特约商户授权类型
+   * 变量名:authorization_type
+   * 是否必填:是
+   * 类型:string(32)
+   * 描述:
+   *  特约商户授权类型:
+   *    INFORMATION_AUTHORIZATION_TYPE:特约商户信息授权类型
+   *    FUND_AUTHORIZATION_TYPE:特约商户资金授权类型
+   *    INFORMATION_AND_FUND_AUTHORIZATION_TYPE:特约商户信息和资金授权类型
+   * 示例值:INFORMATION_AUTHORIZATION_TYPE
+   * 
+ */ + @SerializedName(value = "authorization_type") + private String authorizationType; + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string(5-32)
+   * 描述:
+   *    商户系统内部的商家批次单号,要求此参数只能由数字、大小写字母组成,在商户系统内部唯一
+   *    示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:批次名称
+   * 变量名:batch_name
+   * 是否必填:是
+   * 类型:string(32)
+   * 描述:
+   *  body该笔批量转账的名称
+   *  示例值:2019年1月深圳分部报销单
+   * 
+ */ + @SerializedName(value = "batch_name") + private String batchName; + + /** + *
+   * 字段名:批次备注
+   * 变量名:out_trade_no
+   * 是否必填:是
+   * 类型:string(32)
+   * 描述:
+   *  body转账说明,UTF8编码,最多允许32个字符
+   *   示例值:2019年1月深圳分部报销单
+   * 
+ */ + @SerializedName(value = "batch_remark") + private String batchRemark; + + /** + *
+   * 字段名:转账总金额
+   * 变量名:time_expire
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  body转账金额单位为“分”。转账总金额必须与批次内所有明细转账金额之和保持一致,否则无法发起转账操作
+   *  示例值:4000000
+   * 
+ */ + @SerializedName(value = "total_amount") + private Integer totalAmount; + + /** + *
+   * 字段名:转账总笔数
+   * 变量名:total_num
+   * 是否必填:是
+   * 类型:int
+   * 描述:
+   *  body一个转账批次单最多发起三千笔转账。转账总笔数必须与批次内所有明细之和保持一致,否则无法发起转账操作
+   *  示例值:200
+   * 
+ */ + @SerializedName(value = "total_num") + private Integer totalNum; + + /** + *
+   * 字段名:转账明细列表
+   * 变量名:transfer_detail_list
+   * 是否必填:是
+   * 类型:array
+   * 描述:
+   *  body发起批量转账的明细列表,最多三千笔
+   * 
+ */ + @SerializedName(value = "transfer_detail_list") + private List transferDetailList; + + @Data + @NoArgsConstructor + public static class TransferDetail implements Serializable { + private static final long serialVersionUID = 109053454401492L; + + /** + *
+     * 字段名:商家明细单号
+     * 变量名:out_detail_no
+     * 是否必填:是
+     * 类型:string[5, 32]
+     * 描述:
+     *  商户系统内部区分转账批次单下不同转账明细单的唯一标识,要求此参数只能由数字、大小写字母组成
+     *  示例值:x23zy545Bd5436
+     * 
+ */ + @SerializedName(value = "out_detail_no") + private String outDetailNo; + + + /** + *
+     * 字段名:转账金额
+     * 变量名:transfer_amount
+     * 是否必填:是
+     * 类型:int
+     * 描述:
+     *  转账金额单位为“分”
+     *  示例值:200000
+     * 
+ */ + @SerializedName(value = "transfer_amount") + private Integer transferAmount; + + /** + *
+     * 字段名:转账备注
+     * 变量名:transfer_amount
+     * 是否必填:是
+     * 类型:string[1, 32]
+     * 描述:
+     *  单条转账备注(微信用户会收到该备注),UTF8编码,最多允许32个字符
+     *  示例值:2020年4月报销
+     * 
+ */ + @SerializedName(value = "transfer_remark") + private String transferRemark; + + /** + *
+     * 字段名:收款用户openid
+     * 变量名:openid
+     * 是否必填:是
+     * 类型:string[1, 64]
+     * 描述:
+     *  收款用户openid。如果转账特约商户授权类型是INFORMATION_AUTHORIZATION_TYPE,对应的是特约商户公众号下的openid。
+     *  示例值:o-MYE42l80oelYMDE34nYD456Xoy
+     * 
+ */ + @SerializedName(value = "openid") + private String openid; + + /** + *
+     * 字段名:收款用户姓名
+     * 变量名:user_name
+     * 是否必填:是
+     * 类型:string[1, 1024]
+     * 描述:
+     *  1、收款用户姓名。采用标准RSA算法,公钥由微信侧提供
+     *  2、该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+     *  示例值:757b340b45ebef5467rter35gf464344v3542sdf4t6re4tb4f54ty45t4yyry45
+     * 
+ */ + @SerializedName(value = "user_name") + private String userName; + /** + *
+     * 字段名:收款用户身份证
+     * 变量名:user_id_card
+     * 是否必填:否
+     * 类型:string[1, 1024]
+     * 描述:
+     *  1、收款方身份证号,可不用填(采用标准RSA算法,公钥由微信侧提供)
+     *  2、该字段需进行加密处理,加密方法详见敏感信息加密说明。(提醒:必须在HTTP头中上送Wechatpay-Serial)
+     *  示例值:8609cb22e1774a50a930e414cc71eca06121bcd266335cda230d24a7886a8d9f
+     * 
+ */ + @SerializedName(value = "user_id_card") + private String userIdCard; + } + + /** + *
+   * 字段名:服务商的appid
+   * 变量名:sp_appid
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  特约商户授权类型为FUND_AUTHORIZATION_TYPE时需要填写
+   *  示例值:wxf636efh567hg4388
+   * 
+ */ + @SerializedName(value = "sp_appid") + private String spAppid; + + + /** + *
+   * 字段名:批量转账用途
+   * 变量名:transfer_purpose
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  body批量转账用途,枚举值:
+   *        GOODSPAYMENT:货款、COMMISSION:佣金、REFUND:退款、REIMBURSEMENT:报销
+   *        FREIGHT:运费、OTHERS:其他
+   *  示例值:COMMISSION
+   * 
+ */ + @SerializedName(value = "transfer_purpose") + private String transferPurpose; + + /** + *
+   * 字段名:转账场景【微工卡】
+   * 变量名:transfer_scene
+   * 是否必填:否
+   * 类型:string[1, 32]
+   * 描述:
+   *  body商户的转账场景
+   *     ORDINARY_TRANSFER:普通转账,可转入用户的零钱账户
+   *     PAYROLL_CARD_TRANSFER:微工卡转账,可转入用户在微工卡选择的收款账户(零钱/银行卡)
+   *  示例值:ORDINARY_TRANSFER
+   * 
+ */ + @SerializedName(value = "transfer_scene") + private String transferScene; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferResult.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferResult.java new file mode 100644 index 0000000000..9ecc6a7a57 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/PartnerTransferResult.java @@ -0,0 +1,67 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +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/wxpay/pay/transfer_partner/chapter3_1.shtml
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class PartnerTransferResult implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  商户系统内部的商家批次单号,在商户系统内部唯一
+   *  示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; + + /** + *
+   * 字段名:微信支付批次单号
+   * 变量名:batch_id
+   * 是否必填:是
+   * 类型:string[32, 64]
+   * 描述:
+   *  微信支付批次单号,微信商家转账系统返回的唯一标识
+   *  示例值:1030000071100999991182020050700019480001
+   * 
+ */ + @SerializedName(value = "batch_id") + private String batchId; + + /** + *
+   * 字段名:批次创建时间
+   * 变量名:create_time
+   * 是否必填:是
+   * 类型:string[1, 32]
+   * 描述:
+   *  批次受理成功时返回,遵循rfc3339标准格式,格式为YYYY-MM-DDTHH:mm:ss.sss+TIMEZONE,YYYY-MM-DD表示年月日,
+   *  T出现在字符串中,表示time元素的开头,HH:mm:ss.sss表示时分秒毫秒,TIMEZONE表示时区(+08:00表示东八区时间,
+   *  领先UTC 8小时,即北京时间)。例如:2015-05-20T13:29:35.120+08:00表示北京时间2015年05月20日13点29分35秒
+   *
+   *  示例值:2015-05-20T13:29:35.120+08:00
+   * 
+ */ + @SerializedName(value = "create_time") + private String createTime; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ReceiptBillRequest.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ReceiptBillRequest.java new file mode 100644 index 0000000000..967ba4f155 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/marketing/transfer/ReceiptBillRequest.java @@ -0,0 +1,35 @@ +package com.github.binarywang.wxpay.bean.marketing.transfer; + +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/wxpay/pay/transfer/chapter4_1.shtml
+ * 
+ * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Data +@NoArgsConstructor +public class ReceiptBillRequest implements Serializable { + public static final float serialVersionUID = 1L; + /** + *
+   * 字段名:商家批次单号
+   * 变量名:out_batch_no
+   * 是否必填:是
+   * 类型:string[5, 32]
+   * 描述:
+   *  body商户系统内部的商家批次单号,在商户系统内部唯一。需要电子回单的批次单号
+   *  示例值:plfk2020042013
+   * 
+ */ + @SerializedName(value = "out_batch_no") + private String outBatchNo; +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PartnerTransferService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PartnerTransferService.java new file mode 100644 index 0000000000..0bfc96cf3f --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PartnerTransferService.java @@ -0,0 +1,201 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.ecommerce.FundBalanceResult; +import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum; +import com.github.binarywang.wxpay.bean.marketing.transfer.*; +import com.github.binarywang.wxpay.exception.WxPayException; + +import javax.crypto.BadPaddingException; +import java.io.InputStream; + +/** + * 微信批量转账到零钱【V3接口】服务商API + * + * @author xiaoqiang + * @date 2021-12-06 + */ +public interface PartnerTransferService { + + /** + * 发起批量转账API + * 适用对象:服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_1.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches + * 请求方式:POST + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + PartnerTransferResult batchTransfer(PartnerTransferRequest request) throws WxPayException; + + /** + * 微信支付批次单号查询批次单API + * 接口说明 + * 适用对象:服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_2.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + BatchNumberResult queryBatchByBatchId(BatchNumberRequest request) throws WxPayException; + + /** + * 微信支付明细单号查询明细单API + * 接口说明 + * 适用对象:服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_3.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param batchId 微信批次单号 + * @param detailId 微信明细单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + * @throws BadPaddingException the wx decrypt exception + */ + BatchDetailsResult queryBatchDetailByWeChat(String batchId, String detailId) throws WxPayException, BadPaddingException; + + /** + * 商家批次单号查询批次单API + * 接口说明 + * 适用对象:服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_4.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/out-batch-no/{out_batch_no} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + BatchNumberResult queryBatchByOutBatchNo(MerchantBatchRequest request) throws WxPayException; + + /** + * 商家明细单号查询明细单API + * 接口说明 + * 适用对象:服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter3_5.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param outBatchNo 商家明细单号 + * @param outDetailNo 商家批次单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + * @throws BadPaddingException the wx decrypt exception + */ + BatchDetailsResult queryBatchDetailByMch(String outBatchNo, String outDetailNo) throws WxPayException, BadPaddingException; + + + /** + * 转账电子回单申请受理API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_1.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer/bill-receipt + * 请求方式:POST + * + * @param request 商家批次单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + BillReceiptResult receiptBill(ReceiptBillRequest request) throws WxPayException; + + + /** + * 查询转账电子回单API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_2.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer/bill-receipt/{out_batch_no} + * 请求方式:GET + * + * @param outBatchNo 商家批次单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + BillReceiptResult queryBillReceipt(String outBatchNo) throws WxPayException; + + /** + * 转账明细电子回单受理API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_4.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:POST + * 前置条件:只支持受理最近90天内的转账明细单 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + ElectronicReceiptsResult transferElectronic(ElectronicReceiptsRequest request) throws WxPayException; + + /** + * 查询转账明细电子回单受理结果API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_5.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:GET + * 前置条件:只支持查询最近90天内的转账明细单 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + ElectronicReceiptsResult queryTransferElectronicResult(ElectronicReceiptsRequest request) throws WxPayException; + + /** + * 下载电子回单API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_3.shtml + * 请求URL:通过申请账单接口获取到“download_url”,URL有效期10min + * 请求方式:GET + * 前置条件:调用申请账单接口并获取到“download_url” + * + * @param url 微信返回的电子回单地址。 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + InputStream transferDownload(String url) throws WxPayException; + + /** + *
+   * 查询账户实时余额API
+   * 接口说明
+   * 适用对象:直连商户 服务商
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_1.shtml
+   * 请求URL:https://api.mch.weixin.qq.com/v3/merchant/fund/balance/{account_type}
+   * 请求方式:GET
+   * 
+ * + * @param accountType 服务商账户类型 {@link SpAccountTypeEnum} + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + FundBalanceResult fundBalance(SpAccountTypeEnum accountType) throws WxPayException; + + /** + *
+   * 服务商账户日终余额
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_2.shtml
+   * 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/amount.shtml
+   * 
+ * + * @param accountType 服务商账户类型 + * @param date 查询日期 2020-09-11 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + FundBalanceResult spDayEndBalance(SpAccountTypeEnum accountType, String date); +} 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 new file mode 100644 index 0000000000..be9c64f2e1 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/PayrollService.java @@ -0,0 +1,103 @@ +package com.github.binarywang.wxpay.service; + +import com.github.binarywang.wxpay.bean.marketing.payroll.*; +import com.github.binarywang.wxpay.exception.WxPayException; + +/** + * 微工卡-对接微信api + * + * @author xiaoqiang + * @date 2021/12/7 14:26 + */ +public interface PayrollService { + /** + * 生成授权token + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/tokens + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + TokensResult payrollCardTokens(TokensRequest request) throws WxPayException; + + /** + * 查询微工卡授权关系API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/relations/{openid} + * 请求方式:GET + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + RelationsResult payrollCardRelations(RelationsRequest request) throws WxPayException; + + /** + * 微工卡核身预下单API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + PreOrderResult payrollCardPreOrder(PreOrderRequest request) throws WxPayException; + + /** + * 获取核身结果API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/{authenticate_number} + * 请求方式:GET + * + * @param subMchid 子商户号 + * @param authenticateNumber 商家核身单号 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + AuthenticationsResult payrollCardAuthenticationsNumber(String subMchid, String authenticateNumber) throws WxPayException; + + /** + * 查询核身记录API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications + * 请求方式:GET + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + AuthRecordResult payrollCardAuthentications(AuthRecordRequest request) throws WxPayException; + + /** + * 微工卡核身预下单(流程中完成授权) + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order-with-auth + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + PreOrderWithAuthResult payrollCardPreOrderWithAuth(PreOrderWithAuthRequest request) throws WxPayException; + + /** + * 按日下载提现异常文件API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/merchant/fund/withdraw/bill-type/{bill_type} + * 请求方式:GET + * + * @param billType 账单类型 + * NO_SUCC:提现异常账单,包括提现失败和提现退票账单。 + * 示例值:NO_SUCC + * @param billDate 账单日期 表示所在日期的提现账单,格式为YYYY-MM-DD。 + * 例如:2008-01-01日发起的提现,2008-01-03日银行返回提现失败,则该提现数据将出现在bill_date为2008-01-03日的账单中。 + * 示例值:2019-08-17 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + PreOrderWithAuthResult merchantFundWithdrawBillType(String billType, String billDate) throws WxPayException; + +} diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java index 73dad0c9d2..2a567fa1df 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java @@ -179,6 +179,20 @@ public interface WxPayService { */ WxEntrustPapService getWxEntrustPapService(); + /** + * 获取批量转账到零钱服务类. + * + * @return the Batch transfer to change service + */ + PartnerTransferService getPartnerTransferService(); + + /** + * 微工卡 + * + * @return the micro card + */ + PayrollService getPayrollService(); + /** * 获取企业付款服务类. * diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java index e5ef0be8be..437b618678 100644 --- a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java @@ -75,7 +75,8 @@ public abstract class BaseWxPayServiceImpl implements WxPayService { private final MarketingFavorService marketingFavorService = new MarketingFavorServiceImpl(this); private final MarketingBusiFavorService marketingBusiFavorService = new MarketingBusiFavorServiceImpl(this); private final WxEntrustPapService wxEntrustPapService = new WxEntrustPapServiceImpl(this); - + private final PartnerTransferService partnerTransferService = new PartnerTransferServiceImpl(this); + private final PayrollService payrollService = new PayrollServiceImpl(this); protected Map configMap; @@ -144,6 +145,12 @@ public WxEntrustPapService getWxEntrustPapService() { return wxEntrustPapService; } + @Override + public PartnerTransferService getPartnerTransferService(){return partnerTransferService;} + + @Override + public PayrollService getPayrollService(){return payrollService;} + @Override public WxPayConfig getConfig() { if (this.configMap.size() == 1) { diff --git a/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImpl.java b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImpl.java new file mode 100644 index 0000000000..1a8a28f84b --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImpl.java @@ -0,0 +1,311 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.ecommerce.FundBalanceResult; +import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum; +import com.github.binarywang.wxpay.bean.marketing.transfer.*; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.PartnerTransferService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import jodd.util.StringUtil; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; + +import javax.crypto.BadPaddingException; +import javax.crypto.IllegalBlockSizeException; +import java.io.InputStream; + +/** + * 批量转账到零钱(服务商) + * + * @author xiaoqiang + * @date 2021-12-06 + */ +@Slf4j +@RequiredArgsConstructor +public class PartnerTransferServiceImpl implements PartnerTransferService { + + private static final Gson GSON = new GsonBuilder().create(); + private final WxPayService payService; + + /** + * 发起批量转账API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches + * 请求方式:POST + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 {@link PartnerTransferResult} + * @throws WxPayException the wx pay exception + */ + @Override + public PartnerTransferResult batchTransfer(PartnerTransferRequest request) throws WxPayException { + request.getTransferDetailList().stream().forEach(p -> { + try { + String userName = RsaCryptoUtil.encryptOAEP(p.getUserName(), this.payService.getConfig().getVerifier().getValidCertificate()); + p.setUserName(userName); + } catch (IllegalBlockSizeException e) { + throw new RuntimeException("姓名转换异常!", e); + } + }); + String url = String.format("%s/v3/partner-transfer/batches", this.payService.getPayBaseUrl()); + String response = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request)); + return GSON.fromJson(response, PartnerTransferResult.class); + } + + /** + * 微信支付批次单号查询批次单API + * 接口说明 + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id} + * https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/1030000071100999991182020050700019480001?need_query_detail=true&offset=1 + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 {@link BatchNumberResult} + * @throws WxPayException the wx pay exception + */ + @Override + public BatchNumberResult queryBatchByBatchId(BatchNumberRequest request) throws WxPayException { + String url = String.format("%s/v3/partner-transfer/batches/batch-id/%s", this.payService.getPayBaseUrl(), request.getBatchId()); + if (request.getOffset() == null) { + request.setOffset(0); + } + if (request.getLimit() == null || request.getLimit() <= 0) { + request.setLimit(20); + } + String query = String.format("?need_query_detail=true&detail_status=ALL&offset=%s&limit=%s", request.getNeedQueryDetail(), request.getOffset(), request.getLimit()); + if (StringUtil.isNotBlank(request.getDetailStatus())){ + query += "&detail_status="+request.getDetailStatus(); + } + String response = this.payService.getV3(url + query); + return GSON.fromJson(response, BatchNumberResult.class); + } + + /** + * 商家批次单号查询批次单API + * 接口说明 + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/out-batch-no/{out_batch_no} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param request 请求对象 + * @return 返回数据 {@link BatchNumberResult} + * @throws WxPayException the wx pay exception + */ + @Override + public BatchNumberResult queryBatchByOutBatchNo(MerchantBatchRequest request) throws WxPayException { + String url = String.format("%s/v3/partner-transfer/batches/out-batch-no/%s", this.payService.getPayBaseUrl(), request.getOutBatchNo()); + if (request.getOffset() == null) { + request.setOffset(0); + } + if (request.getLimit() == null || request.getLimit() <= 0) { + request.setLimit(20); + } + String query = String.format("?need_query_detail=true&offset=%s&limit=%s", request.getNeedQueryDetail(), request.getOffset(), request.getLimit()); + if (StringUtil.isNotBlank(request.getDetailStatus())){ + query += "&detail_status="+request.getDetailStatus(); + } + String response = this.payService.getV3(url + query); + return GSON.fromJson(response, BatchNumberResult.class); + } + + /** + * 微信支付明细单号查询明细单API + * 接口说明 + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/batch-id/{batch_id}/details/detail-id/{detail_id} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param batchId 微信批次单号 + * @param detailId 微信明细单号 + * @return 返回数据 {@link BatchDetailsResult} + * @throws WxPayException the wx pay exception + * @throws BadPaddingException the wx decrypt exception + */ + @Override + public BatchDetailsResult queryBatchDetailByWeChat(String batchId, String detailId) throws WxPayException, BadPaddingException { + String url = String.format("%s/v3/partner-transfer/batches/batch-id/%s/details/detail-id/%s", this.payService.getPayBaseUrl(), batchId, detailId); + String response = this.payService.getV3(url); + BatchDetailsResult batchDetailsResult = GSON.fromJson(response, BatchDetailsResult.class); + String userName = RsaCryptoUtil.decryptOAEP(batchDetailsResult.getUserName(), this.payService.getConfig().getPrivateKey()); + batchDetailsResult.setUserName(userName); + return batchDetailsResult; + } + + /** + * 商家明细单号查询明细单API + * 接口说明 + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/partner-transfer/batches/out-batch-no/{out_batch_no}/details/out-detail-no/{out_detail_no} + * 请求方式:GET + * 接口限频:单个服务商 50QPS,如果超过频率限制,会报错FREQUENCY_LIMITED,请降低频率请求。 + * + * @param outBatchNo 商家明细单号 + * @param outDetailNo 商家批次单号 + * @return 返回数据 {@link BatchDetailsResult} + * @throws WxPayException the wx pay exception + * @throws BadPaddingException the wx decrypt exception + */ + @Override + public BatchDetailsResult queryBatchDetailByMch(String outBatchNo, String outDetailNo) throws WxPayException, BadPaddingException { + String url = String.format("%s/v3/partner-transfer/batches/out-batch-no/%s/details/out-detail-no/%s", this.payService.getPayBaseUrl(), outBatchNo, outDetailNo); + String response = this.payService.getV3(url); + BatchDetailsResult batchDetailsResult = GSON.fromJson(response, BatchDetailsResult.class); + String userName = RsaCryptoUtil.decryptOAEP(batchDetailsResult.getUserName(), this.payService.getConfig().getPrivateKey()); + batchDetailsResult.setUserName(userName); + return batchDetailsResult; + } + + + /** + * 转账电子回单申请受理API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_1.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer/bill-receipt + * 请求方式:POST + * + * @param request 商家批次单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public BillReceiptResult receiptBill(ReceiptBillRequest request) throws WxPayException { + String url = String.format("%s/v3/transfer/bill-receipt", this.payService.getPayBaseUrl()); + String response = this.payService.postV3(url, GSON.toJson(request)); + return GSON.fromJson(response, BillReceiptResult.class); + } + + + /** + * 查询转账电子回单API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_2.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer/bill-receipt/{out_batch_no} + * 请求方式:GET + * + * @param outBatchNo 商家批次单号 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public BillReceiptResult queryBillReceipt(String outBatchNo) throws WxPayException { + String url = String.format("%s/v3/transfer/bill-receipt/%s", this.payService.getPayBaseUrl(), outBatchNo); + String response = this.payService.getV3(url); + return GSON.fromJson(response, BillReceiptResult.class); + } + + /** + * 转账明细电子回单受理API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_4.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:POST + * 前置条件:只支持受理最近90天内的转账明细单 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public ElectronicReceiptsResult transferElectronic(ElectronicReceiptsRequest request) throws WxPayException { + String url = String.format("%s/v3/transfer-detail/electronic-receipts", this.payService.getPayBaseUrl()); + String response = this.payService.postV3(url, GSON.toJson(request)); + return GSON.fromJson(response, ElectronicReceiptsResult.class); + } + + + /** + * 查询转账明细电子回单受理结果API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_5.shtml + * 请求URL:https://api.mch.weixin.qq.com/v3/transfer-detail/electronic-receipts + * 请求方式:GET + * 前置条件:只支持查询最近90天内的转账明细单 + * + * @param request 请求对象 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public ElectronicReceiptsResult queryTransferElectronicResult(ElectronicReceiptsRequest request) throws WxPayException { + String url = String.format("%s/v3/transfer-detail/electronic-receipts", this.payService.getPayBaseUrl()); + String query = String.format("?accept_type=%s&out_batch_no=%s&out_detail_no=%s", request.getAcceptType(), request.getOutBatchNo(), request.getOutDetailNo()); + String response = this.payService.getV3(url + query); + return GSON.fromJson(response, ElectronicReceiptsResult.class); + } + + /** + * 下载电子回单API + * 接口说明 + * 适用对象:直连商户 服务商 + * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter4_3.shtml + * 请求URL:通过申请账单接口获取到“download_url”,URL有效期10min + * 请求方式:GET + * 前置条件:调用申请账单接口并获取到“download_url” + * + * @param url 微信返回的电子回单地址。 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public InputStream transferDownload(String url) throws WxPayException { + InputStream response = this.payService.downloadV3(url); + return response; + } + + /** + *
+   * 查询账户实时余额API
+   * 接口说明
+   * 适用对象:直连商户 服务商
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_1.shtml
+   * 请求URL:https://api.mch.weixin.qq.com/v3/merchant/fund/balance/{account_type}
+   * 请求方式:GET
+   * 
+ * + * @param accountType 服务商账户类型 {@link SpAccountTypeEnum} + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public FundBalanceResult fundBalance(SpAccountTypeEnum accountType) throws WxPayException { + String url = String.format("%s/v3/merchant/fund/balance/%s", this.payService.getPayBaseUrl(), accountType); + String response = this.payService.getV3(url); + return GSON.fromJson(response, FundBalanceResult.class); + } + + /** + *
+   * 服务商账户日终余额
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pay/transfer/chapter5_2.shtml
+   * 文档地址: https://pay.weixin.qq.com/wiki/doc/apiv3/wxpay/pages/amount.shtml
+   * 
+ * + * @param accountType 服务商账户类型 + * @param date 查询日期 2020-09-11 + * @return 返回数据 fund balance result + * @throws WxPayException the wx pay exception + */ + @Override + public FundBalanceResult spDayEndBalance(SpAccountTypeEnum accountType, String date) { + try { + return this.payService.getEcommerceService().spDayEndBalance(accountType, date); + } catch (Exception e) { + e.printStackTrace(); + } + return null; + } + + +} 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 new file mode 100644 index 0000000000..51947a2747 --- /dev/null +++ b/weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImpl.java @@ -0,0 +1,192 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.marketing.payroll.*; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.PayrollService; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.StringUtils; + +import javax.crypto.IllegalBlockSizeException; + +/** + * 微信支付-微工卡 + * + * @author xiaoqiang + * @date 2021/12/2 + */ +@Slf4j +@RequiredArgsConstructor +public class PayrollServiceImpl implements PayrollService { + + private static final Gson GSON = new GsonBuilder().create(); + + private final WxPayService payService; + + /** + * 生成授权token + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/tokens + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public TokensResult payrollCardTokens(TokensRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/tokens", payService.getPayBaseUrl()); + try { + String userName = RsaCryptoUtil.encryptOAEP(request.getUserName(), payService.getConfig().getVerifier().getValidCertificate()); + request.setUserName(userName); + String idCardNumber = RsaCryptoUtil.encryptOAEP(request.getIdCardNumber(), payService.getConfig().getVerifier().getValidCertificate()); + request.setIdCardNumber(idCardNumber); + } catch (IllegalBlockSizeException e) { + throw new RuntimeException("加密异常!", e); + } + String response = payService.postV3(url, GSON.toJson(request)); + return GSON.fromJson(response, TokensResult.class); + } + + /** + * 查询微工卡授权关系API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/relations/{openid} + * 请求方式:GET + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public RelationsResult payrollCardRelations(RelationsRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/relations/%s", + payService.getPayBaseUrl(), request.getOpenid()); + String query = String.format("?sub_mchid=%s", request.getSubMchid()); + if (StringUtils.isNotEmpty(request.getAppid())) { + query += "&appid=" + request.getAppid(); + } + if (StringUtils.isNotEmpty(request.getSubAppid())) { + query += "&sub_appid=" + request.getSubAppid(); + } + String response = payService.getV3(url + query); + return GSON.fromJson(response, RelationsResult.class); + } + + /** + * 微工卡核身预下单API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public PreOrderResult payrollCardPreOrder(PreOrderRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/authentications/pre-order", payService.getPayBaseUrl()); + String response = payService.postV3(url, GSON.toJson(request)); + return GSON.fromJson(response, PreOrderResult.class); + } + + /** + * 获取核身结果API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/{authenticate_number} + * 请求方式:GET + * + * @param subMchid 子商户号 + * @param authenticateNumber 商家核身单号 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public AuthenticationsResult payrollCardAuthenticationsNumber(String subMchid, String authenticateNumber) throws WxPayException { + String url = String.format("%s/v3/payroll-card/authentications/%s", payService.getPayBaseUrl(), authenticateNumber); + String query = String.format("?sub_mchid=%s", subMchid); + String response = payService.getV3(url + query); + return GSON.fromJson(response, AuthenticationsResult.class); + } + + /** + * 查询核身记录API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications + * 请求方式:GET + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public AuthRecordResult payrollCardAuthentications(AuthRecordRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/authentications", payService.getPayBaseUrl()); + String query = String.format("?openid=%s&sub_mchid=%s&authenticate_date=%s", + request.getOpenid(), request.getAppid(), request.getSubMchid(), request.getAuthenticateDate()); + if (StringUtils.isNotEmpty(request.getAppid())) { + query += "&appid=" + request.getAppid(); + } + if (StringUtils.isNotEmpty(request.getAppid())) { + query += "&sub_appid=" + request.getSubAppid(); + } + if (StringUtils.isNotEmpty(request.getAuthenticateState())) { + query += "&authenticate_state=" + request.getAuthenticateState(); + } + String response = payService.getV3(url + query); + return GSON.fromJson(response, AuthRecordResult.class); + } + + /** + * 微工卡核身预下单(流程中完成授权) + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/payroll-card/authentications/pre-order-with-auth + * 请求方式:POST + * + * @param request 请求参数 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public PreOrderWithAuthResult payrollCardPreOrderWithAuth(PreOrderWithAuthRequest request) throws WxPayException { + String url = String.format("%s/v3/payroll-card/authentications/pre-order-with-auth", payService.getPayBaseUrl()); + try { + String userName = RsaCryptoUtil.encryptOAEP(request.getUserName(), payService.getConfig().getVerifier().getValidCertificate()); + request.setUserName(userName); + String idCardNumber = RsaCryptoUtil.encryptOAEP(request.getIdCardNumber(), payService.getConfig().getVerifier().getValidCertificate()); + request.setIdCardNumber(idCardNumber); + } catch (IllegalBlockSizeException e) { + throw new RuntimeException("敏感信息加密异常!", e); + } + String response = payService.postV3(url, GSON.toJson(request)); + return GSON.fromJson(response, PreOrderWithAuthResult.class); + } + + /** + * 按日下载提现异常文件API + * 适用对象:服务商 + * 请求URL:https://api.mch.weixin.qq.com/v3/merchant/fund/withdraw/bill-type/{bill_type} + * 请求方式:GET + * + * @param billType 账单类型 + * NO_SUCC:提现异常账单,包括提现失败和提现退票账单。 + * 示例值:NO_SUCC + * @param billDate 账单日期 表示所在日期的提现账单,格式为YYYY-MM-DD。 + * 例如:2008-01-01日发起的提现,2008-01-03日银行返回提现失败,则该提现数据将出现在bill_date为2008-01-03日的账单中。 + * 示例值:2019-08-17 + * @return 返回数据 + * @throws WxPayException the wx pay exception + */ + @Override + public PreOrderWithAuthResult merchantFundWithdrawBillType(String billType, String billDate) throws WxPayException { + String url = String.format("%s/v3/merchant/fund/withdraw/bill-type/%s", payService.getPayBaseUrl(), billType); + String query = String.format("?bill_date=%s", billDate); + String response = payService.getV3(url + query); + return GSON.fromJson(response, PreOrderWithAuthResult.class); + } + +} diff --git a/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImplTest.java b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImplTest.java new file mode 100644 index 0000000000..9c7b1cb541 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PartnerTransferServiceImplTest.java @@ -0,0 +1,139 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.ecommerce.FundBalanceResult; +import com.github.binarywang.wxpay.bean.ecommerce.enums.SpAccountTypeEnum; +import com.github.binarywang.wxpay.bean.marketing.transfer.*; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +import javax.crypto.BadPaddingException; +import java.io.InputStream; + +/** + * 批量转账到零钱(服务商) + * + * @author xiaoqiang + * @date 2021/12/9 + */ +@Slf4j +@Test +@Guice(modules = ApiTestModule.class) +public class PartnerTransferServiceImplTest { + + @Inject + private WxPayService wxPayService; + + private static final Gson GSON = new GsonBuilder().create(); + + @Test + public void batchTransfer() throws WxPayException { + String requestParamStr = "{\"sub_mchid\":\"1608*****1\",\"authorization_type\":\"FUND_AUTHORIZATION_TYPE\",\"out_batch_no\":\"202108241345*****4618387\",\"batch_name\":\"用户提现批次单2021-12-13_13_45_50\",\"batch_remark\":\"用户>提现\",\"total_amount\":30,\"total_num\":1,\"transfer_detail_list\":[{\"out_detail_no\":\"DN202112131345506240631640467671\",\"transfer_amount\":30,\"transfer_remark\":\"钱包提现\",\"openid\":\"oUaIE6PdSuBpsHAOtvf_jsgtqu5I\",\"user_name\":\"Q2FoOMuf1Ulsab+j0nObLjkIZAUZan8Z7RaEU5qOjv1RUq5ImuqqAqoQZ4f/zD5CMxuLD7lM1TIdGIvrvO8pe2YOwoUdRxiRzDX+Z0Rsy5Y9QqEiuHHK1JTR7vC18eKp0a4PlY7K4jUl49jG0QE+6gOG83Cqj3Z9dupPor94fPRUM/ZIzF293ONgSJW1iuHkd6g7EHTpizHZ/r5XcT+qh*************************kqjtVkT3GiuDXmMA8d/hO85uY50ItNNa5Ov8kmJbLCgFreoS49LUEwj/yuDap6F4g\\u003d\\u003d\"}],\"sp_appid\":\"wx6aa************ef\",\"transfer_purpose\":\"OTHERS\"}"; + + PartnerTransferRequest request = GSON.fromJson(requestParamStr, PartnerTransferRequest.class); + + PartnerTransferResult partnerTransferResult = wxPayService.getPartnerTransferService().batchTransfer(request); + log.info(partnerTransferResult.toString()); + } + + + @Test + public void queryBatchByBatchId() throws WxPayException { + BatchNumberRequest request = new BatchNumberRequest(); + request.setBatchId("1030000071100999991182020050700019480001"); + request.setNeedQueryDetail(true); + request.setDetailStatus("ALL"); + BatchNumberResult batchResult = wxPayService.getPartnerTransferService().queryBatchByBatchId(request); + log.info(batchResult.toString()); + } + + + @Test + public void queryBatchDetailByWeChat() throws WxPayException, BadPaddingException { + String batchId = "1030000071100999991182020050700019480001"; + String detailId = "1040000071100999991182020050700019500100"; + BatchDetailsResult batchResult = wxPayService.getPartnerTransferService().queryBatchDetailByWeChat(batchId, detailId); + log.info(batchResult.toString()); + } + + @Test + public void queryBatchByOutBatchNo() throws WxPayException { + MerchantBatchRequest request = new MerchantBatchRequest(); + request.setOutBatchNo("10300000************0019480001"); + request.setDetailStatus("ALL"); + request.setNeedQueryDetail(true); + BatchNumberResult batchResult = wxPayService.getPartnerTransferService().queryBatchByOutBatchNo(request); + log.info(batchResult.toString()); + } + + @Test + public void queryBatchDetailByMch() throws WxPayException, BadPaddingException { + String outBatchNo = "10300000************0019480001"; + String outDetailNo = "10***********0019480001"; + BatchDetailsResult batchResult = wxPayService.getPartnerTransferService().queryBatchDetailByMch(outBatchNo, outDetailNo); + log.info(batchResult.toString()); + } + + @Test + public void receiptBill() throws WxPayException { + ReceiptBillRequest request = new ReceiptBillRequest(); + request.setOutBatchNo("10300000************0019480001"); + BillReceiptResult batchResult = wxPayService.getPartnerTransferService().receiptBill(request); + log.info(batchResult.toString()); + } + + @Test + public void queryBillReceipt() throws WxPayException { + String outBatchNo = "10300000************0019480001"; + BillReceiptResult batchResult = wxPayService.getPartnerTransferService().queryBillReceipt(outBatchNo); + log.info(batchResult.toString()); + } + + @Test + public void transferElectronic() throws WxPayException { + ElectronicReceiptsRequest request = new ElectronicReceiptsRequest(); + request.setAcceptType("BATCH_TRANSFER"); + request.setOutBatchNo("GD2021011610162610BBdkkIwcu3"); + request.setOutDetailNo("mx0911231610162610v4CNkO4HAf"); + ElectronicReceiptsResult batchResult = wxPayService.getPartnerTransferService().transferElectronic(request); + log.info(batchResult.toString()); + } + + @Test + public void queryTransferElectronicResult() throws WxPayException { + ElectronicReceiptsRequest request = new ElectronicReceiptsRequest(); + request.setAcceptType("BATCH_TRANSFER"); + request.setOutBatchNo("GD2021011610162610BBdkkIwcu3"); + request.setOutDetailNo("mx0911231610162610v4CNkO4HAf"); + ElectronicReceiptsResult batchResult = wxPayService.getPartnerTransferService().queryTransferElectronicResult(request); + log.info(batchResult.toString()); + } + + + @Test + public void transferDownload() throws WxPayException { + String url = "https://api.mch.weixin.qq.com/v3/billdownload/file?token=xxx"; + InputStream batchResult = wxPayService.getPartnerTransferService().transferDownload(url); + log.info(batchResult.toString()); + } + + @Test + public void fundBalance() throws WxPayException { + FundBalanceResult batchResult = wxPayService.getPartnerTransferService().fundBalance(SpAccountTypeEnum.BASIC); + log.info(batchResult.toString()); + } + + @Test + public void spDayEndBalance() { + String date = "2020-09-11"; + FundBalanceResult batchResult = wxPayService.getPartnerTransferService().spDayEndBalance(SpAccountTypeEnum.BASIC, date); + log.info(batchResult.toString()); + } + +} 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 new file mode 100644 index 0000000000..406d1fdf12 --- /dev/null +++ b/weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/PayrollServiceImplTest.java @@ -0,0 +1,128 @@ +package com.github.binarywang.wxpay.service.impl; + +import com.github.binarywang.wxpay.bean.marketing.payroll.*; +import com.github.binarywang.wxpay.bean.marketing.transfer.PartnerTransferRequest; +import com.github.binarywang.wxpay.bean.marketing.transfer.PartnerTransferResult; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; +import com.github.binarywang.wxpay.testbase.ApiTestModule; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.inject.Inject; +import lombok.extern.slf4j.Slf4j; +import org.testng.annotations.Guice; +import org.testng.annotations.Test; + +/** + * 微工卡(服务商) + * + * @author xiaoqiang + * @date 2021/12/9 + */ +@Slf4j +@Test +@Guice(modules = ApiTestModule.class) +public class PayrollServiceImplTest { + + + @Inject + private WxPayService wxPayService; + + private static final Gson GSON = new GsonBuilder().create(); + + @Test + public void payrollCardTokens() throws WxPayException { + TokensRequest request = new TokensRequest(); + request.setOpenid("onqOjjmo8wmTOOtSKwXtGjg9Gb58"); + request.setAppid("wxa1111111"); + request.setSubMchid("1111111"); + request.setSubAppid("wxa1111111"); + request.setUserName("LP7bT4hQXUsOZCEvK2YrSiqFsnP0oRMfeoLN0vBg"); + request.setIdCardNumber("7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5"); + request.setEmploymentType("LONG_TERM_EMPLOYMENT"); + TokensResult tokensResult = wxPayService.getPayrollService().payrollCardTokens(request); + log.info(tokensResult.toString()); + + } + + @Test + public void payrollCardRelations() throws WxPayException { + RelationsRequest request = new RelationsRequest(); + request.setOpenid("onqOjjmo8wmTOOtSKwXtGjg9Gb58"); + request.setSubMchid("1111111"); + request.setAppid("wxa1111111"); + request.setSubAppid("wxa1111111"); + RelationsResult relationsResult = wxPayService.getPayrollService().payrollCardRelations(request); + log.info(relationsResult.toString()); + + } + + + @Test + public void payrollCardPreOrder() throws WxPayException { + PreOrderRequest request = new PreOrderRequest(); + request.setOpenid("onqOjjmo8wmTOOtSKwXtGjg9Gb58"); + request.setSubMchid("1111111"); + request.setAppid("wxa1111111"); + request.setSubAppid("wxa1111111"); + request.setAuthenticateNumber("mcdhehfgisdhfjghed39384564i83"); + request.setProjectName("某项目"); + request.setEmployerName("某单位名称"); + PreOrderResult preOrderResult = wxPayService.getPayrollService().payrollCardPreOrder(request); + log.info(preOrderResult.toString()); + + } + + @Test + public void payrollCardAuthenticationsNumber() throws WxPayException { + String subMchid = "1111111"; + String authenticateNumber = "mcdhehfgisdhfjghed39384564i83"; + AuthenticationsResult authenticationsResult = wxPayService.getPayrollService().payrollCardAuthenticationsNumber(subMchid, authenticateNumber); + log.info(authenticationsResult.toString()); + + } + + @Test + public void payrollCardAuthentications() throws WxPayException { + AuthRecordRequest request = new AuthRecordRequest(); + request.setOpenid("onqOjjmo8wmTOOtSKwXtGjg9Gb58"); + request.setSubMchid("1111111"); + request.setAppid("wxa1111111"); + request.setSubAppid("wxa1111111"); + request.setAuthenticateDate("2020-12-25"); + request.setAuthenticateState("AUTHENTICATE_SUCCESS"); + request.setOffset(0); + request.setLimit(10); + AuthRecordResult authRecordResult = wxPayService.getPayrollService().payrollCardAuthentications(request); + log.info(authRecordResult.toString()); + + } + + @Test + public void payrollCardPreOrderWithAuth() throws WxPayException { + PreOrderWithAuthRequest request = new PreOrderWithAuthRequest(); + request.setOpenid("onqOjjmo8wmTOOtSKwXtGjg9Gb58"); + request.setSubMchid("1111111"); + request.setAppid("wxa1111111"); + request.setSubAppid("wxa1111111"); + request.setAuthenticateNumber("mcdhehfgisdhfjghed39384564i83"); + request.setEmployerName("某用工企业"); + request.setEmploymentType("LONG_TERM_EMPLOYMENT"); + request.setIdCardNumber("7FzH5XksJG3a8HLLsaaUV6K54y1OnPMY5"); + request.setProjectName("某项目"); + request.setUserName("LP7bT4hQXUsOZCEvK2YrSiqFsnP0oRMfeoLN0vBg"); + PreOrderWithAuthResult preOrderWithAuthResult = wxPayService.getPayrollService().payrollCardPreOrderWithAuth(request); + log.info(preOrderWithAuthResult.toString()); + + } + + @Test + public void merchantFundWithdrawBillType() throws WxPayException { + String billType = "NO_SUCC"; + String billDate = "2019-08-17"; + PreOrderWithAuthResult preOrderWithAuthResult = wxPayService.getPayrollService().merchantFundWithdrawBillType(billType, billDate); + log.info(preOrderWithAuthResult.toString()); + + } + +}