Quellcode durchsuchen

:art: 【微信支付】重构分账相关接口,重命名接口方法和请求实体,合并分账v2、v3实现类,方便同时使用

四叶草 vor 1 Jahr
Ursprung
Commit
bcc4839ff0
42 geänderte Dateien mit 904 neuen und 897 gelöschten Zeilen
  1. 80 0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/Receiver.java
  2. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingNotifyData.java
  3. 15 5
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingPartnerNotifyResult.java
  4. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingBillRequest.java
  5. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingMerchantRatioQueryRequest.java
  6. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingOrderAmountQueryRequest.java
  7. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java
  8. 2 7
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingQueryRequest.java
  9. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java
  10. 13 50
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReceiver.java
  11. 5 5
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java
  12. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java
  13. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java
  14. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReturnRequest.java
  15. 3 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java
  16. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnfreezeRequest.java
  17. 186 0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/request/ProfitSharingV3Request.java
  18. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingBillResult.java
  19. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingMerchantRatioQueryResult.java
  20. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingMerchantMaxRatioQueryResult.java
  21. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingOrderAmountQueryResult.java
  22. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnsplitResult.java
  23. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java
  24. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java
  25. 102 0
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/result/ProfitSharingReceiverV3Result.java
  26. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java
  27. 1 1
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java
  28. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReturnResult.java
  29. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnfreezeResult.java
  30. 2 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingResult.java
  31. 0 128
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingNotifyResult.java
  32. 0 99
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingRequest.java
  33. 271 4
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/ProfitSharingService.java
  34. 0 295
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/ProfitSharingV3Service.java
  35. 1 8
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java
  36. 0 3
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java
  37. 174 2
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java
  38. 0 220
      weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingV3ServiceImpl.java
  39. 1 0
      weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResultTest.java
  40. 2 1
      weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResultTest.java
  41. 17 1
      weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java
  42. 0 35
      weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingV3ServiceImplTest.java

+ 80 - 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/Receiver.java

@@ -1,8 +1,10 @@
 package com.github.binarywang.wxpay.bean.profitsharing;
 
+import com.github.binarywang.wxpay.v3.SpecEncrypt;
 import com.google.gson.FieldNamingPolicy;
 import com.google.gson.Gson;
 import com.google.gson.GsonBuilder;
+import com.google.gson.annotations.SerializedName;
 
 import java.io.Serializable;
 
@@ -11,12 +13,90 @@ import java.io.Serializable;
  * @version 1.0
  */
 public class Receiver implements Serializable {
+  /**
+   * <pre>
+   * 字段名:分账接收方类型
+   * 是否必填:是
+   * 描述:
+   * 1、MERCHANT_ID:商户号
+   * 2、PERSONAL_OPENID:个人openid(由父商户APPID转换得到)
+   * </pre>
+   */
+  @SerializedName("type")
   private String type;
+  /**
+   * <pre>
+   * 字段名:分账接收方帐号
+   * 是否必填:是
+   * 描述:
+   * 1、分账接收方类型为MERCHANT_ID时,分账接收方账号为商户号
+   * 2、分账接收方类型为PERSONAL_OPENID时,分账接收方账号为个人openid
+   * </pre>
+   */
+  @SerializedName("account")
   private String account;
+  /**
+   * <pre>
+   * 字段名:分账金额
+   * 是否必填:是
+   * 描述: 分账金额,单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
+   * </pre>
+   */
+  @SerializedName("amount")
   private Integer amount;
+  /**
+   * <pre>
+   * 字段名:分账描述
+   * 是否必填:是
+   * 描述: 分账的原因描述,分账账单中需要体现
+   * </pre>
+   */
+  @SerializedName("description")
   private String description;
+  /**
+   * <pre>
+   * 字段名:分账个人接收方姓名
+   * 是否必填:否
+   * 描述:
+   * 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求
+   * 1、分账接收方类型是PERSONAL_OPENID,是个人姓名的密文(选传,传则校验) 此字段的加密方法详见:敏感信息加密说明
+   * 2、使用微信支付平台证书中的公钥
+   * 3、使用RSAES-OAEP算法进行加密
+   * 4、将请求中HTTP头部的Wechatpay-Serial设置为证书序列号
+   * </pre>
+   */
+  @SerializedName("name")
+  @SpecEncrypt
   private String name;
+  /**
+   * <pre>
+   * 字段名:与分账方的关系类型
+   * 是否必填:是
+   * 描述:子商户与接收方的关系。 本字段值为枚举:
+   * STORE:门店
+   * STAFF:员工
+   * STORE_OWNER:店主
+   * PARTNER:合作伙伴
+   * HEADQUARTER:总部
+   * BRAND:品牌方
+   * DISTRIBUTOR:分销商
+   * USER:用户
+   * SUPPLIER: 供应商
+   * CUSTOM:自定义
+   * </pre>
+   */
+  @SerializedName("relation_type")
   private String relationType;
+  /**
+   * <pre>
+   * 字段名:自定义的分账关系
+   * 是否必填:是
+   * 描述:子商户与接收方具体的关系,本字段最多10个字。
+   * 当字段relationType的值为CUSTOM时,本字段必填;
+   * 当字段relationType的值不为CUSTOM时,本字段无需填写。
+   * </pre>
+   */
+  @SerializedName("custom_relation")
   private String customRelation;
 
   /**

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingNotifyData.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.notify;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
@@ -16,7 +16,7 @@ import java.io.Serializable;
  */
 @Data
 @NoArgsConstructor
-public class ProfitSharingNotifyData implements Serializable{
+public class ProfitSharingNotifyV3Response implements Serializable{
   private static final long serialVersionUID = 4242383310854692441L;
 
   /**

+ 15 - 5
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingPartnerNotifyResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.notify;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
@@ -8,19 +8,29 @@ import java.io.Serializable;
 
 /**
  *
- * 微信V3接口-服务商
+ * 微信V3接口
  * 分账动账通知解密后数据实体
  *
- * @author linyaqiang
- * @since 2023-08-01
+ * @author yuanbo
+ * @since 2022-04-26-21:08 PM
  */
 @Data
 @NoArgsConstructor
-public class ProfitSharingPartnerNotifyResult implements Serializable {
+public class ProfitSharingNotifyV3Result implements Serializable {
   private static final long serialVersionUID = -2875006651351414624L;
 
   /**
    * <pre>
+   * 字段名:直连商户号
+   * 是否必填:是
+   * 描述:直连模式分账发起和出资商户
+   * </pre>
+   */
+  @SerializedName("mchid")
+  private String mchId;
+
+  /**
+   * <pre>
    * 字段名:服务商商户号
    * 是否必填:是
    * 描述:服务商模式分账发起商户。

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingBillRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import java.io.Serializable;
 
@@ -19,7 +19,7 @@ import lombok.NoArgsConstructor;
 @Builder(builderMethodName = "newBuilder")
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProfitSharingBillRequest implements Serializable {
+public class ProfitSharingBillV3Request implements Serializable {
   private static final long serialVersionUID = 5200819754873844593L;
 
   /**

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingMerchantRatioQueryRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingOrderAmountQueryRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 2 - 7
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingQueryRequest.java

@@ -1,16 +1,11 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
-import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
-import com.github.binarywang.wxpay.constant.WxPayConstants;
-import com.github.binarywang.wxpay.exception.WxPayException;
 import com.google.gson.annotations.SerializedName;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
-import lombok.experimental.Accessors;
 import me.chanjar.weixin.common.annotation.Required;
 
 import java.io.Serializable;
-import java.util.Map;
 
 /**
  * @author lyt 2023/08/21 15:44
@@ -20,7 +15,7 @@ import java.util.Map;
 @Builder(builderMethodName = "newBuilder")
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProfitSharingQueryRequest implements Serializable {
+public class ProfitSharingQueryV3Request implements Serializable {
   private static final long serialVersionUID = 1L;
   /**
    * <pre>

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 13 - 50
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReceiver.java

@@ -1,29 +1,29 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
+import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
+import com.github.binarywang.wxpay.constant.WxPayConstants;
+import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.v3.SpecEncrypt;
 import com.google.gson.annotations.SerializedName;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.*;
+import me.chanjar.weixin.common.annotation.Required;
 
 import java.io.Serializable;
+import java.util.Map;
 
 /**
+ * 添加/删除分账接受方请求对象
  *
- * 微信V3接口 分账接收方实体
- * @author pg
- * created on  2021-6-25
- *
+ * @author lyt 2023-08-23 10:09:21
+ * @version 1.0
  */
 @Data
 @Builder(builderMethodName = "newBuilder")
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProfitSharingReceiver implements Serializable {
-  private static final long serialVersionUID = -4391888575149767840L;
-
-
+public class ProfitSharingReceiverV3Request implements Serializable {
+  private static final long serialVersionUID = 1L;
   /**
    * <pre>
    * 字段名:子商户号
@@ -125,41 +125,4 @@ public class ProfitSharingReceiver implements Serializable {
    */
   @SerializedName("custom_relation")
   private String customRelation;
-
-  /**
-   * <pre>
-   * 字段名:分账描述
-   * 是否必填:是
-   * 描述: 分账的原因描述,分账账单中需要体现
-   * </pre>
-   */
-  private String description;
-  /**
-   * <pre>
-   * 字段名:分账金额
-   * 是否必填:是
-   * 描述: 分账金额,单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
-   * </pre>
-   */
-  private Long amount;
-
-  /**
-   * 此构造函数用于分账接口
-   *
-   * @param type        MERCHANT_ID:商户ID
-   *                    PERSONAL_WECHATID:个人微信号PERSONAL_OPENID:个人openid(由父商户APPID转换得到)PERSONAL_SUB_OPENID: 个人sub_openid(由子商户APPID转换得到)
-   * @param account     类型是MERCHANT_ID时,是商户ID
-   *                    类型是PERSONAL_WECHATID时,是个人微信号
-   *                    类型是PERSONAL_OPENID时,是个人openid
-   *                    类型是PERSONAL_SUB_OPENID时,是个人sub_openid
-   * @param amount      分账金额,单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
-   * @param description 分账的原因描述,分账账单中需要体现
-   */
-  public ProfitSharingReceiver(String type, String account, Long amount, String description) {
-    this.type = type;
-    this.account = account;
-    this.amount = amount;
-    this.description = description;
-  }
-
 }

+ 5 - 5
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingRequest.java

@@ -1,12 +1,16 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;
 import com.github.binarywang.wxpay.exception.WxPayException;
+import com.github.binarywang.wxpay.v3.SpecEncrypt;
+import com.google.gson.Gson;
+import com.google.gson.annotations.SerializedName;
 import com.thoughtworks.xstream.annotations.XStreamAlias;
 import lombok.*;
 import me.chanjar.weixin.common.annotation.Required;
 
+import java.io.Serializable;
 import java.util.Map;
 
 /**
@@ -21,7 +25,6 @@ import java.util.Map;
 @XStreamAlias("xml")
 public class ProfitSharingRequest extends BaseWxPayRequest {
   private static final long serialVersionUID = 212049937430575842L;
-
   /**
    * <pre>
    * 字段名:微信订单号.
@@ -35,7 +38,6 @@ public class ProfitSharingRequest extends BaseWxPayRequest {
   @XStreamAlias("transaction_id")
   @Required
   private String transactionId;
-
   /**
    * <pre>
    * 字段名:商户分账单号.
@@ -49,7 +51,6 @@ public class ProfitSharingRequest extends BaseWxPayRequest {
   @XStreamAlias("out_order_no")
   @Required
   private String outOrderNo;
-
   /**
    * <pre>
    * 字段名:分账接收方列表.
@@ -77,7 +78,6 @@ public class ProfitSharingRequest extends BaseWxPayRequest {
   @Required
   private String receivers;
 
-
   @Override
   protected void checkConstraints() throws WxPayException {
     // 目前仅支持HMAC-SHA256.

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnQueryRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReturnRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.AllArgsConstructor;
@@ -19,7 +19,7 @@ import java.io.Serializable;
 @Builder(builderMethodName = "newBuilder")
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProfitSharingReturnRequest implements Serializable {
+public class ProfitSharingReturnV3Request implements Serializable {
   private static final long serialVersionUID = -2175582517588397426L;
 
   /**

+ 3 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingFinishRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
 import com.github.binarywang.wxpay.constant.WxPayConstants;
@@ -9,6 +9,7 @@ import me.chanjar.weixin.common.annotation.Required;
 import java.util.Map;
 
 /**
+ * 解冻剩余资金API请求实体
  * @author Wang GuangXin 2019/10/23 14:02
  * @version 1.0
  */
@@ -18,7 +19,7 @@ import java.util.Map;
 @NoArgsConstructor
 @AllArgsConstructor
 @XStreamAlias("xml")
-public class ProfitSharingFinishRequest extends BaseWxPayRequest {
+public class ProfitSharingUnfreezeRequest extends BaseWxPayRequest {
 
   private static final long serialVersionUID = -4265779954583596627L;
 

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnfreezeRequest.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.request;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.AllArgsConstructor;
@@ -19,7 +19,7 @@ import java.io.Serializable;
 @Builder(builderMethodName = "newBuilder")
 @NoArgsConstructor
 @AllArgsConstructor
-public class ProfitSharingUnfreezeRequest implements Serializable {
+public class ProfitSharingUnfreezeV3Request implements Serializable {
   private static final long serialVersionUID = 6835471990040104843L;
 
   /**

+ 186 - 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/request/ProfitSharingV3Request.java

@@ -0,0 +1,186 @@
+package com.github.binarywang.wxpay.bean.profitsharing.request;
+
+import com.github.binarywang.wxpay.v3.SpecEncrypt;
+import com.google.gson.annotations.SerializedName;
+import lombok.AllArgsConstructor;
+import lombok.Builder;
+import lombok.Data;
+import lombok.NoArgsConstructor;
+
+import java.io.Serializable;
+import java.util.List;
+
+/**
+ * 微信V3接口
+ * 请求分账API请求实体
+ *
+ * @author pg
+ * created on  2021-6-24
+ */
+@Data
+@Builder(builderMethodName = "newBuilder")
+@NoArgsConstructor
+@AllArgsConstructor
+public class ProfitSharingV3Request implements Serializable {
+  private static final long serialVersionUID = 3644929701624280800L;
+
+  /**
+   * <pre>
+   * 字段名:子商户号
+   * 是否必填:是
+   * 描述:微信支付分配的子商户号,即分账的出资商户号。
+   * </pre>
+   */
+  @SerializedName("sub_mchid")
+  private String subMchId;
+
+  /**
+   * <pre>
+   * 字段名:应用ID
+   * 是否必填:是
+   * 描述:微信分配的商户appid
+   * </pre>
+   */
+  @SerializedName("appid")
+  private String appid;
+
+  /**
+   * <pre>
+   * 字段名:子商户应用ID
+   * 是否必填:否
+   * 描述:子商户的公众账号ID,分账接收方类型包含PERSONAL_SUB_OPENID时必填
+   * </pre>
+   */
+  @SerializedName("sub_appid")
+  private String subAppid;
+
+  /**
+   * <pre>
+   * 字段名:微信订单号
+   * 是否必填:是
+   * 描述:微信支付订单号
+   * </pre>
+   */
+  @SerializedName("transaction_id")
+  private String transactionId;
+
+  /**
+   * <pre>
+   * 字段名:商户分账单号
+   * 是否必填:是
+   * 描述:商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@
+   * </pre>
+   */
+  @SerializedName("out_order_no")
+  private String outOrderNo;
+
+  /**
+   * <pre>
+   * 字段名:分账接收方列表
+   * 是否必填:是
+   * 描述:分账接收方列表,可以设置出资商户作为分账接受方,最多可有50个分账接收方
+   * </pre>
+   */
+  @SpecEncrypt
+  @SerializedName("receivers")
+  private List<Receiver> receivers;
+
+  /**
+   * <pre>
+   * 字段名:是否解冻剩余未分资金
+   * 是否必填:是
+   * 描述:
+   * 1、如果为true,该笔订单剩余未分账的金额会解冻回分账方商户;
+   * 2、如果为false,该笔订单剩余未分账的金额不会解冻回分账方商户,可以对该笔订单再次进行分账。
+   * </pre>
+   */
+  @SerializedName("unfreeze_unsplit")
+  private boolean unfreezeUnsplit;
+  /**
+   * 分账接收方实体
+   */
+  @Data
+  @NoArgsConstructor
+  public static class Receiver implements Serializable {
+    private static final long serialVersionUID = 1L;
+    /**
+     * <pre>
+     * 字段名:分账接收方类型
+     * 是否必填:是
+     * 描述:
+     * 1、MERCHANT_ID:商户号
+     * 2、PERSONAL_OPENID:个人openid(由父商户APPID转换得到)
+     * </pre>
+     */
+    @SerializedName("type")
+    private String type;
+
+    /**
+     * <pre>
+     * 字段名:分账接收方帐号
+     * 是否必填:是
+     * 描述:
+     * 1、分账接收方类型为MERCHANT_ID时,分账接收方账号为商户号
+     * 2、分账接收方类型为PERSONAL_OPENID时,分账接收方账号为个人openid
+     * </pre>
+     */
+    @SerializedName("account")
+    private String account;
+
+    /**
+     * <pre>
+     * 字段名:分账个人接收方姓名
+     * 是否必填:否
+     * 描述:
+     * 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求
+     * 1、分账接收方类型是PERSONAL_OPENID,是个人姓名的密文(选传,传则校验) 此字段的加密方法详见:敏感信息加密说明
+     * 2、使用微信支付平台证书中的公钥
+     * 3、使用RSAES-OAEP算法进行加密
+     * 4、将请求中HTTP头部的Wechatpay-Serial设置为证书序列号
+     * </pre>
+     */
+    @SerializedName("name")
+    @SpecEncrypt
+    private String name;
+
+    /**
+     * <pre>
+     * 字段名:与分账方的关系类型
+     * 是否必填:是
+     * 描述:子商户与接收方的关系。 本字段值为枚举:
+     * STORE:门店
+     * STAFF:员工
+     * STORE_OWNER:店主
+     * PARTNER:合作伙伴
+     * HEADQUARTER:总部
+     * BRAND:品牌方
+     * DISTRIBUTOR:分销商
+     * USER:用户
+     * SUPPLIER: 供应商
+     * CUSTOM:自定义
+     * </pre>
+     */
+    @SerializedName("relation_type")
+    private String relationType;
+
+    /**
+     * <pre>
+     * 字段名:自定义的分账关系
+     * 是否必填:是
+     * 描述:子商户与接收方具体的关系,本字段最多10个字。
+     * 当字段relationType的值为CUSTOM时,本字段必填;
+     * 当字段relationType的值不为CUSTOM时,本字段无需填写。
+     * </pre>
+     */
+    @SerializedName("custom_relation")
+    private String customRelation;
+    /**
+     * <pre>
+     * 字段名:分账描述
+     * 是否必填:是
+     * 描述: 分账的原因描述,分账账单中需要体现
+     * </pre>
+     */
+    private String description;
+  }
+}

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingBillResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import java.io.Serializable;
 
@@ -15,7 +15,7 @@ import lombok.NoArgsConstructor;
  */
 @Data
 @NoArgsConstructor
-public class ProfitSharingBillResult implements Serializable {
+public class ProfitSharingBillV3Result implements Serializable {
   private static final long serialVersionUID = -704896948531566657L;
 
   /**

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingMerchantRatioQueryResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingMerchantMaxRatioQueryResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import java.io.Serializable;
 
@@ -13,7 +13,7 @@ import lombok.Data;
  * @date 2022-12-09
  */
 @Data
-public class ProfitSharingMerchantMaxRatioQueryResult implements Serializable {
+public class ProfitSharingMerchantRatioQueryV3Result implements Serializable {
   private static final long serialVersionUID = -6259241881199571683L;
 
   /** 子商户号 */

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingOrderAmountQueryResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnsplitResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
@@ -13,7 +13,7 @@ import java.io.Serializable;
  * created on  2021-6-25
  */
 @Data
-public class ProfitSharingUnsplitResult implements Serializable {
+public class ProfitSharingOrderAmountQueryV3Result implements Serializable {
 
   private static final long serialVersionUID = -7025255772409082288L;
   /**

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.google.gson.FieldNamingPolicy;

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReceiverResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;

+ 102 - 0
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/result/ProfitSharingReceiverV3Result.java

@@ -0,0 +1,102 @@
+package com.github.binarywang.wxpay.bean.profitsharing.result;
+
+import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
+import com.github.binarywang.wxpay.v3.SpecEncrypt;
+import com.google.gson.annotations.SerializedName;
+import com.thoughtworks.xstream.annotations.XStreamAlias;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import lombok.NoArgsConstructor;
+import org.w3c.dom.Document;
+
+import java.io.Serializable;
+
+/**
+ * @author 添加/删除分账接收方结果
+ * @version 1.0
+ */
+@Data
+public class ProfitSharingReceiverV3Result implements Serializable {
+  private static final long serialVersionUID = 876204163877798066L;
+  /**
+   * <pre>
+   * 字段名:子商户号
+   * 是否必填:是
+   * 描述:微信支付分配的子商户号,即分账的出资商户号。
+   * </pre>
+   */
+  @SerializedName("sub_mchid")
+  private String subMchId;
+
+  /**
+   * <pre>
+   * 字段名:分账接收方类型
+   * 是否必填:是
+   * 描述:
+   * 1、MERCHANT_ID:商户号
+   * 2、PERSONAL_OPENID:个人openid(由父商户APPID转换得到)
+   * </pre>
+   */
+  @SerializedName("type")
+  private String type;
+
+  /**
+   * <pre>
+   * 字段名:分账接收方帐号
+   * 是否必填:是
+   * 描述:
+   * 1、分账接收方类型为MERCHANT_ID时,分账接收方账号为商户号
+   * 2、分账接收方类型为PERSONAL_OPENID时,分账接收方账号为个人openid
+   * </pre>
+   */
+  @SerializedName("account")
+  private String account;
+
+  /**
+   * <pre>
+   * 字段名:分账个人接收方姓名
+   * 是否必填:否
+   * 描述:
+   * 可选项,在接收方类型为个人的时可选填,若有值,会检查与 name 是否实名匹配,不匹配会拒绝分账请求
+   * 1、分账接收方类型是PERSONAL_OPENID,是个人姓名的密文(选传,传则校验) 此字段的加密方法详见:敏感信息加密说明
+   * 2、使用微信支付平台证书中的公钥
+   * 3、使用RSAES-OAEP算法进行加密
+   * 4、将请求中HTTP头部的Wechatpay-Serial设置为证书序列号
+   * </pre>
+   */
+  @SerializedName("name")
+  @SpecEncrypt
+  private String name;
+
+  /**
+   * <pre>
+   * 字段名:与分账方的关系类型
+   * 是否必填:是
+   * 描述:子商户与接收方的关系。 本字段值为枚举:
+   * STORE:门店
+   * STAFF:员工
+   * STORE_OWNER:店主
+   * PARTNER:合作伙伴
+   * HEADQUARTER:总部
+   * BRAND:品牌方
+   * DISTRIBUTOR:分销商
+   * USER:用户
+   * SUPPLIER: 供应商
+   * CUSTOM:自定义
+   * </pre>
+   */
+  @SerializedName("relation_type")
+  private String relationType;
+
+  /**
+   * <pre>
+   * 字段名:自定义的分账关系
+   * 是否必填:是
+   * 描述:子商户与接收方具体的关系,本字段最多10个字。
+   * 当字段relationType的值为CUSTOM时,本字段必填;
+   * 当字段relationType的值不为CUSTOM时,本字段无需填写。
+   * </pre>
+   */
+  @SerializedName("custom_relation")
+  private String customRelation;
+}

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.google.gson.Gson;

+ 1 - 1
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingReturnResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.thoughtworks.xstream.annotations.XStreamAlias;

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingReturnResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
@@ -13,7 +13,7 @@ import java.io.Serializable;
  * created on  2021-6-25
  */
 @Data
-public class ProfitSharingReturnResult implements Serializable {
+public class ProfitSharingReturnV3Result implements Serializable {
   private static final long serialVersionUID = -2175582517588397426L;
 
   /**

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingUnfreezeResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 import com.google.gson.annotations.SerializedName;
 import lombok.Data;
@@ -14,7 +14,7 @@ import java.util.List;
  * created on  2021-6-25
  */
 @Data
-public class ProfitSharingUnfreezeResult implements Serializable {
+public class ProfitSharingUnfreezeV3Result implements Serializable {
   private static final long serialVersionUID = 5053171678880645337L;
 
   /**

+ 2 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingResult.java

@@ -1,4 +1,4 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
+package com.github.binarywang.wxpay.bean.profitsharing.result;
 
 
 import com.google.gson.annotations.SerializedName;
@@ -15,7 +15,7 @@ import java.util.List;
  * created on  2021-6-24
  */
 @Data
-public class ProfitSharingResult implements Serializable {
+public class ProfitSharingV3Result implements Serializable {
   private static final long serialVersionUID = -6201692412535987502L;
 
   /**

+ 0 - 128
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingNotifyResult.java

@@ -1,128 +0,0 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
-
-import com.google.gson.annotations.SerializedName;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-
-/**
- *
- * 微信V3接口
- * 分账动账通知解密后数据实体
- *
- * @author yuanbo
- * @since 2022-04-26-21:08 PM
- */
-@Data
-@NoArgsConstructor
-public class ProfitSharingNotifyResult implements Serializable {
-  private static final long serialVersionUID = -2875006651351414624L;
-
-  /**
-   * <pre>
-   * 字段名:直连商户号
-   * 是否必填:是
-   * 描述:直连模式分账发起和出资商户
-   * </pre>
-   */
-  @SerializedName("mchid")
-  private String mchId;
-
-  /**
-   * <pre>
-   * 字段名:微信订单号
-   * 是否必填:是
-   * 描述:微信支付订单号
-   * </pre>
-   */
-  @SerializedName("transaction_id")
-  private String transactionId;
-
-  /**
-   * <pre>
-   * 字段名:微信分账/回退单号
-   * 是否必填:是
-   * 描述:微信分账/回退单号
-   * </pre>
-   */
-  @SerializedName("order_id")
-  private String orderId;
-
-  /**
-   * <pre>
-   * 字段名:商户分账/回退单号
-   * 是否必填:是
-   * 描述:分账方系统内部的分账/回退单号
-   * </pre>
-   */
-  @SerializedName("out_order_no")
-  private String outOrderNo;
-
-  /**
-   * <pre>
-   * 字段名:分账接收方
-   * 是否必填:是
-   * 描述:分账接收方对象
-   * </pre>
-   */
-  @SerializedName("receiver")
-  private Receiver receiver;
-
-  /**
-   * <pre>
-   * 字段名:成功时间
-   * 是否必填:是
-   * 描述:成功时间,Rfc3339标准
-   * </pre>
-   */
-  @SerializedName("success_time")
-  private String successTime;
-
-  @Data
-  @NoArgsConstructor
-  public static class Receiver implements Serializable {
-
-    private static final long serialVersionUID = -931070141604645363L;
-
-    /**
-     * <pre>
-     * 字段名:分账接收方类型
-     * 是否必填:是
-     * 描述:MERCHANT_ID:商户号(mch_id或者sub_mch_id)
-     * </pre>
-     */
-    @SerializedName("type")
-    private String type;
-
-    /**
-     * <pre>
-     * 字段名:分账接收方账号
-     * 是否必填:是
-     * 描述:申请本功能商户号
-     * </pre>
-     */
-    @SerializedName("account")
-    private String account;
-
-    /**
-     * <pre>
-     * 字段名:分账动账金额
-     * 是否必填:是
-     * 描述:分账动账金额,单位为分,只能为整数
-     * </pre>
-     */
-    @SerializedName("amount")
-    private Integer amount;
-
-    /**
-     * <pre>
-     * 字段名:分账/回退描述
-     * 是否必填:是
-     * 描述:分账/回退描述
-     * </pre>
-     */
-    @SerializedName("description")
-    private String description;
-  }
-}

+ 0 - 99
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/bean/profitsharing/v3/ProfitSharingRequest.java

@@ -1,99 +0,0 @@
-package com.github.binarywang.wxpay.bean.profitsharing.v3;
-
-import com.github.binarywang.wxpay.v3.SpecEncrypt;
-import com.google.gson.annotations.SerializedName;
-import lombok.AllArgsConstructor;
-import lombok.Builder;
-import lombok.Data;
-import lombok.NoArgsConstructor;
-
-import java.io.Serializable;
-import java.util.List;
-
-/**
- * 微信V3接口
- * 请求分账API请求实体
- *
- * @author pg
- * created on  2021-6-24
- */
-@Data
-@Builder(builderMethodName = "newBuilder")
-@NoArgsConstructor
-@AllArgsConstructor
-public class ProfitSharingRequest implements Serializable {
-  private static final long serialVersionUID = 3644929701624280800L;
-
-  /**
-   * <pre>
-   * 字段名:子商户号
-   * 是否必填:是
-   * 描述:微信支付分配的子商户号,即分账的出资商户号。
-   * </pre>
-   */
-  @SerializedName("sub_mchid")
-  private String subMchId;
-
-  /**
-   * <pre>
-   * 字段名:应用ID
-   * 是否必填:是
-   * 描述:微信分配的商户appid
-   * </pre>
-   */
-  @SerializedName("appid")
-  private String appid;
-
-  /**
-   * <pre>
-   * 字段名:子商户应用ID
-   * 是否必填:否
-   * 描述:子商户的公众账号ID,分账接收方类型包含PERSONAL_SUB_OPENID时必填
-   * </pre>
-   */
-  @SerializedName("sub_appid")
-  private String subAppid;
-
-  /**
-   * <pre>
-   * 字段名:微信订单号
-   * 是否必填:是
-   * 描述:微信支付订单号
-   * </pre>
-   */
-  @SerializedName("transaction_id")
-  private String transactionId;
-
-  /**
-   * <pre>
-   * 字段名:商户分账单号
-   * 是否必填:是
-   * 描述:商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@
-   * </pre>
-   */
-  @SerializedName("out_order_no")
-  private String outOrderNo;
-
-  /**
-   * <pre>
-   * 字段名:分账接收方列表
-   * 是否必填:是
-   * 描述:分账接收方列表,可以设置出资商户作为分账接受方,最多可有50个分账接收方
-   * </pre>
-   */
-  @SpecEncrypt
-  @SerializedName("receivers")
-  private List<ProfitSharingReceiver> receivers;
-
-  /**
-   * <pre>
-   * 字段名:是否解冻剩余未分资金
-   * 是否必填:是
-   * 描述:
-   * 1、如果为true,该笔订单剩余未分账的金额会解冻回分账方商户;
-   * 2、如果为false,该笔订单剩余未分账的金额不会解冻回分账方商户,可以对该笔订单再次进行分账。
-   * </pre>
-   */
-  @SerializedName("unfreeze_unsplit")
-  private boolean unfreezeUnsplit;
-}

+ 271 - 4
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/ProfitSharingService.java

@@ -1,6 +1,10 @@
 package com.github.binarywang.wxpay.service;
 
-import com.github.binarywang.wxpay.bean.profitsharing.*;
+import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
+import com.github.binarywang.wxpay.bean.profitsharing.notify.ProfitSharingNotifyV3Response;
+import com.github.binarywang.wxpay.bean.profitsharing.notify.ProfitSharingNotifyV3Result;
+import com.github.binarywang.wxpay.bean.profitsharing.request.*;
+import com.github.binarywang.wxpay.bean.profitsharing.result.*;
 import com.github.binarywang.wxpay.exception.WxPayException;
 
 /**
@@ -43,6 +47,26 @@ public interface ProfitSharingService {
 
   /**
    * <pre>
+   * 请求分账API
+   *
+   * 微信订单支付成功后,商户发起分账请求,将结算后的资金分到分账接收方
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_1.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders
+   *
+   * 注意:
+   * 对同一笔订单最多能发起20次分账请求,每次请求最多分给50个接收方
+   * 此接口采用异步处理模式,即在接收到商户请求后,优先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
+   * </pre>
+   *
+   * @param request {@link ProfitSharingV3Request} 针对某一笔支付订单的分账方法
+   * @return {@link ProfitSharingV3Result} 微信返回的分账结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_1.shtml">微信文档</a>
+   */
+  ProfitSharingV3Result profitSharingV3(ProfitSharingV3Request request) throws WxPayException;
+
+  /**
+   * <pre>
    * 1、不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给特约商户
    * 2、调用多次分账接口后,需要解冻剩余资金时,调用本接口将剩余的分账金额全部解冻给特约商户
    * 3、已调用请求单次分账后,剩余待分账金额为零,不需要再调用此接口。
@@ -55,7 +79,7 @@ public interface ProfitSharingService {
    * @return .
    * @throws WxPayException the wx pay exception
    */
-  ProfitSharingResult profitSharingFinish(ProfitSharingFinishRequest request) throws WxPayException;
+  ProfitSharingResult profitSharingFinish(ProfitSharingUnfreezeRequest request) throws WxPayException;
 
   /**
    * <pre>
@@ -84,6 +108,38 @@ public interface ProfitSharingService {
   ProfitSharingReceiverResult removeReceiver(ProfitSharingReceiverRequest request) throws WxPayException;
 
   /**
+   * <pre>
+   * 添加分账接收方API
+   *
+   * 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_8.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add
+   * </pre>
+   *
+   * @param request 分账接收方实体 {@link ProfitSharingReceiverV3Request}
+   * @return {@link ProfitSharingReceiverV3Result} 微信返回的分账接收方结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_8.shtml">微信文档</a>
+   */
+  ProfitSharingReceiverV3Result addReceiverV3(ProfitSharingReceiverV3Request request) throws WxPayException;
+
+  /**
+   * <pre>
+   * 删除分账接收方API
+   *
+   * 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_9.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/receivers/delete
+   * </pre>
+   *
+   * @param request 分账接收方实体 {@link ProfitSharingReceiverV3Request}
+   * @return {@link ProfitSharingReceiverV3Result} 微信返回的删除的分账接收方结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_9.shtml">微信文档</a>
+   */
+  ProfitSharingReceiverV3Result removeReceiverV3(ProfitSharingReceiverV3Request request) throws WxPayException;
+
+  /**
    * TODO:微信返回签名失败
    * <pre>
    * 发起分账请求后,可调用此接口查询分账结果;发起分账完结请求后,可调用此接口查询分账完结的执行结果。
@@ -98,6 +154,66 @@ public interface ProfitSharingService {
 
   /**
    * <pre>
+   * 查询分账结果API(商户平台)
+   *
+   * 发起分账请求后,可调用此接口查询分账结果
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
+   *
+   * 注意:
+   * • 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
+   * </pre>
+   *
+   * @param outOrderNo    商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ 。
+   * @param transactionId 微信支付订单号
+   * @return {@link ProfitSharingV3Result} 微信返回的分账结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml">微信文档</a>
+   */
+  ProfitSharingV3Result profitSharingQueryV3(String outOrderNo, String transactionId) throws WxPayException;
+
+  /**
+   * <pre>
+   * 查询分账结果API(服务商平台)
+   *
+   * 发起分账请求后,可调用此接口查询分账结果
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_2.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
+   *
+   * 注意:
+   * • 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
+   * </pre>
+   *
+   * @param outOrderNo    商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ 。
+   * @param transactionId 微信支付订单号
+   * @param subMchId      微信支付分配的子商户号,即分账的出资商户号。
+   * @return {@link ProfitSharingV3Result} 微信返回的分账结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_2.shtml">微信文档</a>
+   */
+  ProfitSharingV3Result profitSharingQueryV3(String outOrderNo, String transactionId, String subMchId) throws WxPayException;
+
+  /**
+   * <pre>
+   * 请求分账查询API
+   *
+   * 发起分账请求后,可调用此接口查询分账结果
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
+   *
+   * 注意:
+   * 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
+   * </pre>
+   *
+   * @param request {@link ProfitSharingQueryV3Request} 针对某一笔分账订单的分账方法
+   * @return {@link ProfitSharingV3Result} 微信返回的分账查询结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml">微信文档</a>
+   */
+  ProfitSharingV3Result profitSharingQueryV3(ProfitSharingQueryV3Request request) throws WxPayException;
+
+  /**
+   * <pre>
    * 服务商可通过调用此接口查询订单剩余待分金额。
    * 接口频率:30QPS
    * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_10&index=7
@@ -112,6 +228,22 @@ public interface ProfitSharingService {
 
   /**
    * <pre>
+   * 查询剩余待分金额API
+   *
+   * 可调用此接口查询订单剩余待分金额
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_6.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/transactions/{transaction_id}/amounts
+   * </pre>
+   *
+   * @param transactionId 微信订单号,微信支付订单号
+   * @return {@link ProfitSharingOrderAmountQueryV3Result} 微信返回的订单剩余待分金额结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_6.shtml">微信文档</a>
+   */
+  ProfitSharingOrderAmountQueryV3Result profitSharingUnsplitAmountQueryV3(String transactionId) throws WxPayException;
+
+  /**
+   * <pre>
    * 服务商可以查询子商户设置的允许服务商分账的最大比例。
    * 接口频率:30QPS
    * 文档详见: https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_11&index=8
@@ -125,6 +257,24 @@ public interface ProfitSharingService {
   ProfitSharingMerchantRatioQueryResult profitSharingMerchantRatioQuery(ProfitSharingMerchantRatioQueryRequest request) throws WxPayException;
 
   /**
+   * <pre>
+   * 查询最大分账比例
+   *
+   * 可调用此接口查询特约商户设置的允许服务商分账的最大比例
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_7.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/merchant-configs/{sub_mchid}
+   * </pre>
+   *
+   * @param subMchId 子商户号(微信支付分配的子商户号,即分账的出资商户号)
+   * @return {@link ProfitSharingMerchantRatioQueryV3Result} 特约商户设置的允许服务商分账的最大比例结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_7.shtml">服务商平台>>API字典>>资金应用>>分账>>查询最大分账比例</a>
+   * @since 4.4.0
+   * @date 2022-12-09
+   */
+  ProfitSharingMerchantRatioQueryV3Result profitSharingMerchantRatioQueryV3(String subMchId) throws WxPayException;
+
+  /**
    * TODO:这个接口用真实的数据返回【参数不正确】,我对比官方文档除了缺少sub_mch_id,和sub_appid之外其他相同,当我随便填了一个商户id的时候,提示【回退方没有开通分账回退功能】
    * <pre>
    * 仅对订单进行退款时,如果订单已经分账,可以先调用此接口将指定的金额从分账接收方(仅限商户类型的分账接收方)回退给特约商户,然后再退款。
@@ -143,6 +293,29 @@ public interface ProfitSharingService {
   ProfitSharingReturnResult profitSharingReturn(ProfitSharingReturnRequest returnRequest) throws WxPayException;
 
   /**
+   * <pre>
+   * 请求分账回退API
+   *
+   * 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_3.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/return-orders
+   *
+   * 注意:
+   * • 分账回退以原分账单为依据,支持多次回退,申请回退总金额不能超过原分账单分给该接收方的金额
+   * • 此接口采用同步处理模式,即在接收到商户请求后,会实时返回处理结果
+   * • 对同一笔分账单最多能发起20次分账回退请求
+   * • 退款和分账回退没有耦合,分账回退可以先于退款请求,也可以后于退款请求
+   * • 此功能需要接收方在商户平台-交易中心-分账-分账接收设置下,开启同意分账回退后,才能使用
+   * </pre>
+   *
+   * @param request {@link ProfitSharingReturnV3Request} 针对某一笔支付订单的分账方法
+   * @return {@link ProfitSharingReturnV3Result} 微信返回的分账回退结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_3.shtml">微信文档</a>
+   */
+  ProfitSharingReturnV3Result profitSharingReturnV3(ProfitSharingReturnV3Request request) throws WxPayException;
+
+  /**
    * TODO:因profitsharingReturn接口无法使用,没有办法对这里进行真实的测试,模拟数据这里返回【记录不存在】
    * <pre>
    * 商户需要核实回退结果,可调用此接口查询回退结果。
@@ -156,7 +329,101 @@ public interface ProfitSharingService {
    * @return .
    * @throws WxPayException .
    */
-  ProfitSharingReturnResult profitSharingReturnQuery(ProfitSharingReturnQueryRequest queryRequest)
-    throws WxPayException;
+  ProfitSharingReturnResult profitSharingReturnQuery(ProfitSharingReturnQueryRequest queryRequest) throws WxPayException;
 
+  /**
+   * <pre>
+   * 查询分账回退结果API(商户平台)
+   *
+   * 商户需要核实回退结果,可调用此接口查询回退结果
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_4.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/return-orders/{out_return_no}
+   *
+   * 注意:
+   * • 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
+   * </pre>
+   *
+   * @param outOrderNo  原发起分账请求时使用的商户系统内部的分账单号
+   * @param outReturnNo 调用回退接口提供的商户系统内部的回退单号
+   * @return {@link ProfitSharingReturnV3Result} 微信返回的分账回退结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_4.shtml">微信文档</a>
+   */
+  ProfitSharingReturnV3Result profitSharingReturnQueryV3(String outOrderNo, String outReturnNo) throws WxPayException;
+
+  /**
+   * <pre>
+   * 查询分账回退结果API(服务商平台)
+   *
+   * 商户需要核实回退结果,可调用此接口查询回退结果
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_3.shtml
+   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/return-orders/{out_return_no}
+   *
+   * 注意:
+   * • 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
+   * </pre>
+   *
+   * @param outOrderNo  原发起分账请求时使用的商户系统内部的分账单号
+   * @param outReturnNo 调用回退接口提供的商户系统内部的回退单号
+   * @param subMchId      微信支付分配的子商户号,即分账的回退方商户号。
+   * @return {@link ProfitSharingReturnV3Result} 微信返回的分账回退结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_3.shtml">微信文档</a>
+   */
+  ProfitSharingReturnV3Result profitSharingReturnQueryV3(String outOrderNo, String outReturnNo, String subMchId) throws WxPayException;
+
+  /**
+   * <pre>
+   * 解冻剩余资金API
+   *
+   * 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给特约商户
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_5.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders/unfreeze
+   *
+   * 注意:
+   * • 调用分账接口后,需要解冻剩余资金时,调用本接口将剩余的分账金额全部解冻给特约商户
+   * • 此接口采用异步处理模式,即在接收到商户请求后,优先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
+   * </pre>
+   *
+   * @param request 解冻剩余资金请求实体 {@link ProfitSharingUnfreezeV3Request}
+   * @return {@link ProfitSharingReturnV3Result} 微信返回的解冻剩余资金结果
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_5.shtml">微信文档</a>
+   */
+  ProfitSharingUnfreezeV3Result profitSharingUnfreeze(ProfitSharingUnfreezeV3Request request) throws WxPayException;
+
+  /**
+   * <pre>
+   * 分账动账通知
+   *
+   * 分账或分账回退成功后,微信会把相关变动结果发送给分账接收方(只支持商户)。
+   * 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_10.shtml
+   * </pre>
+   *
+   * @param notifyData 分账通知实体
+   * @param header     分账通知头 {@link SignatureHeader}
+   * @return {@link ProfitSharingNotifyV3Response} 资源对象
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_10.shtml">微信文档</a>
+   */
+  ProfitSharingNotifyV3Result parseProfitSharingNotifyResult(String notifyData, SignatureHeader header) throws WxPayException;
+
+  /**
+   * <pre>
+   * 申请分账账单
+   *
+   * 微信支付按天提供分账账单文件,商户可以通过该接口获取账单文件的下载地址
+   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_11.shtml
+   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/bills
+   * </pre>
+   *
+   * @param request 申请分账账单请求实体({@link ProfitSharingBillV3Request})
+   * @return {@link ProfitSharingBillV3Result} 申请分账账单结果类
+   * @throws WxPayException the wx pay exception
+   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_11.shtml">服务商平台>>API字典>>资金应用>>分账>>申请分账账单API</a>
+   * @since 4.4.0
+   * @date 2022-12-09
+   */
+  ProfitSharingBillV3Result profitSharingBill(ProfitSharingBillV3Request request) throws WxPayException;
 }

+ 0 - 295
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/ProfitSharingV3Service.java

@@ -1,295 +0,0 @@
-package com.github.binarywang.wxpay.service;
-
-import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
-import com.github.binarywang.wxpay.bean.profitsharing.v3.*;
-import com.github.binarywang.wxpay.exception.WxPayException;
-
-/**
- * 微信支付V3-资金应用-分账
- *
- * @author pg 2021-6-23
- * @date 2021-6-23
- */
-public interface ProfitSharingV3Service {
-  /**
-   * <pre>
-   * 查询最大分账比例
-   *
-   * 可调用此接口查询特约商户设置的允许服务商分账的最大比例
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_7.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/merchant-configs/{sub_mchid}
-   * </pre>
-   *
-   * @param subMchId 子商户号(微信支付分配的子商户号,即分账的出资商户号)
-   * @return {@link ProfitSharingMerchantMaxRatioQueryResult} 特约商户设置的允许服务商分账的最大比例结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_7.shtml">服务商平台>>API字典>>资金应用>>分账>>查询最大分账比例</a>
-   * @since 4.4.0
-   * @date 2022-12-09
-   */
-   ProfitSharingMerchantMaxRatioQueryResult getProfitSharingMerchantMaxRatio(String subMchId) throws WxPayException;
-
-  /**
-   * <pre>
-   * 请求分账API
-   *
-   * 微信订单支付成功后,商户发起分账请求,将结算后的资金分到分账接收方
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_1.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders
-   *
-   * 注意:
-   * 对同一笔订单最多能发起20次分账请求,每次请求最多分给50个接收方
-   * 此接口采用异步处理模式,即在接收到商户请求后,优先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
-   * </pre>
-   *
-   * @param request {@link ProfitSharingRequest} 针对某一笔支付订单的分账方法
-   * @return {@link ProfitSharingResult} 微信返回的分账结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_1.shtml">微信文档</a>
-   */
-  ProfitSharingResult profitSharing(ProfitSharingRequest request) throws WxPayException;
-
-  /**
-   * <pre>
-   * 查询分账结果API(商户平台)
-   *
-   * 发起分账请求后,可调用此接口查询分账结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml
-   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
-   *
-   * 注意:
-   * • 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
-   * </pre>
-   *
-   * @param outOrderNo    商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ 。
-   * @param transactionId 微信支付订单号
-   * @return {@link ProfitSharingResult} 微信返回的分账结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml">微信文档</a>
-   */
-  ProfitSharingResult getProfitSharingResult(String outOrderNo, String transactionId) throws WxPayException;
-
-  /**
-   * <pre>
-   * 查询分账结果API(服务商平台)
-   *
-   * 发起分账请求后,可调用此接口查询分账结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_2.shtml
-   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
-   *
-   * 注意:
-   * • 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
-   * </pre>
-   *
-   * @param outOrderNo    商户系统内部的分账单号,在商户系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ 。
-   * @param transactionId 微信支付订单号
-   * @param subMchId      微信支付分配的子商户号,即分账的出资商户号。
-   * @return {@link ProfitSharingResult} 微信返回的分账结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_2.shtml">微信文档</a>
-   */
-  ProfitSharingResult getProfitSharingResult(String outOrderNo, String transactionId, String subMchId) throws WxPayException;
-
-  /**
-   * <pre>
-   * 请求分账回退API
-   *
-   * 如果订单已经分账,在退款时,可以先调此接口,将已分账的资金从分账接收方的账户回退给分账方,再发起退款
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_3.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/return-orders
-   *
-   * 注意:
-   * • 分账回退以原分账单为依据,支持多次回退,申请回退总金额不能超过原分账单分给该接收方的金额
-   * • 此接口采用同步处理模式,即在接收到商户请求后,会实时返回处理结果
-   * • 对同一笔分账单最多能发起20次分账回退请求
-   * • 退款和分账回退没有耦合,分账回退可以先于退款请求,也可以后于退款请求
-   * • 此功能需要接收方在商户平台-交易中心-分账-分账接收设置下,开启同意分账回退后,才能使用
-   * </pre>
-   *
-   * @param request {@link ProfitSharingReturnRequest} 针对某一笔支付订单的分账方法
-   * @return {@link ProfitSharingReturnResult} 微信返回的分账回退结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_3.shtml">微信文档</a>
-   */
-  ProfitSharingReturnResult profitSharingReturn(ProfitSharingReturnRequest request) throws WxPayException;
-
-  /**
-   * <pre>
-   * 查询分账回退结果API(商户平台)
-   *
-   * 商户需要核实回退结果,可调用此接口查询回退结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_4.shtml
-   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/return-orders/{out_return_no}
-   *
-   * 注意:
-   * • 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
-   * </pre>
-   *
-   * @param outOrderNo  原发起分账请求时使用的商户系统内部的分账单号
-   * @param outReturnNo 调用回退接口提供的商户系统内部的回退单号
-   * @return {@link ProfitSharingReturnResult} 微信返回的分账回退结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_4.shtml">微信文档</a>
-   */
-  ProfitSharingReturnResult getProfitSharingReturnResult(String outOrderNo, String outReturnNo) throws WxPayException;
-
-  /**
-   * <pre>
-   * 查询分账回退结果API(服务商平台)
-   *
-   * 商户需要核实回退结果,可调用此接口查询回退结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_3.shtml
-   * 接口链接:https://api.mch.weixin.qq.com/v3/profitsharing/return-orders/{out_return_no}
-   *
-   * 注意:
-   * • 如果分账回退接口返回状态为处理中,可调用此接口查询回退结果
-   * </pre>
-   *
-   * @param outOrderNo  原发起分账请求时使用的商户系统内部的分账单号
-   * @param outReturnNo 调用回退接口提供的商户系统内部的回退单号
-   * @param subMchId      微信支付分配的子商户号,即分账的回退方商户号。
-   * @return {@link ProfitSharingReturnResult} 微信返回的分账回退结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_3.shtml">微信文档</a>
-   */
-  ProfitSharingReturnResult getProfitSharingReturnResult(String outOrderNo, String outReturnNo, String subMchId) throws WxPayException;
-
-  /**
-   * <pre>
-   * 解冻剩余资金API
-   *
-   * 不需要进行分账的订单,可直接调用本接口将订单的金额全部解冻给特约商户
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_5.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders/unfreeze
-   *
-   * 注意:
-   * • 调用分账接口后,需要解冻剩余资金时,调用本接口将剩余的分账金额全部解冻给特约商户
-   * • 此接口采用异步处理模式,即在接收到商户请求后,优先受理请求再异步处理,最终的分账结果可以通过查询分账接口获取
-   * </pre>
-   *
-   * @param request 解冻剩余资金请求实体 {@link ProfitSharingUnfreezeRequest}
-   * @return {@link ProfitSharingReturnResult} 微信返回的解冻剩余资金结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_5.shtml">微信文档</a>
-   */
-  ProfitSharingUnfreezeResult profitSharingUnfreeze(ProfitSharingUnfreezeRequest request) throws WxPayException;
-
-  /**
-   * <pre>
-   * 查询剩余待分金额API
-   *
-   * 可调用此接口查询订单剩余待分金额
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_6.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/transactions/{transaction_id}/amounts
-   * </pre>
-   *
-   * @param transactionId 微信订单号,微信支付订单号
-   * @return {@link ProfitSharingUnsplitResult} 微信返回的订单剩余待分金额结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_6.shtml">微信文档</a>
-   */
-  ProfitSharingUnsplitResult getProfitSharingUnsplitAmount(String transactionId) throws WxPayException;
-
-  /**
-   * <pre>
-   * 添加分账接收方API
-   *
-   * 商户发起添加分账接收方请求,建立分账接收方列表。后续可通过发起分账请求,将分账方商户结算后的资金,分到该分账接收方
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_8.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/receivers/add
-   * </pre>
-   *
-   * @param receiver 分账接收方实体 {@link ProfitSharingReceiver}
-   * @return {@link ProfitSharingReceiver} 微信返回的分账接收方结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_8.shtml">微信文档</a>
-   */
-  ProfitSharingReceiver addProfitSharingReceiver(ProfitSharingReceiver receiver) throws WxPayException;
-
-  /**
-   * <pre>
-   * 删除分账接收方API
-   *
-   * 商户发起删除分账接收方请求。删除后,不支持将分账方商户结算后的资金,分到该分账接收方
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_9.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/receivers/delete
-   * </pre>
-   *
-   * @param receiver 分账接收方实体 {@link ProfitSharingReceiver}
-   * @return {@link ProfitSharingReceiver} 微信返回的删除的分账接收方结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_9.shtml">微信文档</a>
-   */
-  ProfitSharingReceiver deleteProfitSharingReceiver(ProfitSharingReceiver receiver) throws WxPayException;
-
-
-  /**
-   * <pre>
-   * 分账动账通知
-   *
-   * 分账或分账回退成功后,微信会把相关变动结果发送给分账接收方(只支持商户)。
-   * 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_10.shtml
-   * </pre>
-   *
-   * @param notifyData 分账通知实体
-   * @param header     分账通知头 {@link SignatureHeader}
-   * @return {@link ProfitSharingNotifyData} 资源对象
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_10.shtml">微信文档</a>
-   */
-  ProfitSharingNotifyResult getProfitSharingNotifyResult(String notifyData, SignatureHeader header) throws WxPayException;
-
-  /**
-   * <pre>
-   * 分账动账通知-服务商
-   *
-   * 分账或分账回退成功后,微信会把相关变动结果发送给分账接收方(只支持商户)。
-   * 对后台通知交互时,如果微信收到应答不是成功或超时,微信认为通知失败,微信会通过一定的策略定期重新发起通知,尽可能提高通知的成功率,但微信不保证通知最终能成功。
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_10.shtml
-   * </pre>
-   *
-   * @param notifyData 分账通知实体
-   * @param header     分账通知头 {@link SignatureHeader}
-   * @return {@link ProfitSharingNotifyData} 资源对象
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_10.shtml">微信文档</a>
-   */
-  ProfitSharingPartnerNotifyResult getProfitSharingPartnerNotifyResult(String notifyData, SignatureHeader header) throws WxPayException;
-
-  /**
-   * <pre>
-   * 申请分账账单
-   *
-   * 微信支付按天提供分账账单文件,商户可以通过该接口获取账单文件的下载地址
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_11.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/bills
-   * </pre>
-   *
-   * @param request 申请分账账单请求实体({@link ProfitSharingBillRequest})
-   * @return {@link ProfitSharingBillResult} 申请分账账单结果类
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter8_1_11.shtml">服务商平台>>API字典>>资金应用>>分账>>申请分账账单API</a>
-   * @since 4.4.0
-   * @date 2022-12-09
-   */
-  ProfitSharingBillResult getProfitSharingBill(ProfitSharingBillRequest request) throws WxPayException;
-  /**
-   * <pre>
-   * 请求分账查询API
-   *
-   * 发起分账请求后,可调用此接口查询分账结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
-   *
-   * 注意:
-   * 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
-   * </pre>
-   *
-   * @param request {@link ProfitSharingQueryRequest} 针对某一笔分账订单的分账方法
-   * @return {@link ProfitSharingResult} 微信返回的分账查询结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml">微信文档</a>
-   */
-  ProfitSharingResult profitSharingQuery(ProfitSharingQueryRequest request) throws WxPayException;
-}

+ 1 - 8
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/WxPayService.java

@@ -240,7 +240,7 @@ public interface WxPayService {
   /**
    * 获取分账服务类.
    * <p>
-   * V3接口 {@link WxPayService#getProfitSharingV3Service()}
+   * V3接口 {@link WxPayService#getProfitSharingService()}
    * </p>
    *
    * @return the ent pay service
@@ -248,13 +248,6 @@ public interface WxPayService {
   ProfitSharingService getProfitSharingService();
 
   /**
-   * 获取V3分账服务类.
-   *
-   * @return the ent pay service
-   */
-  ProfitSharingV3Service getProfitSharingV3Service();
-
-  /**
    * 获取支付分服务类.
    *
    * @return the ent pay service

+ 0 - 3
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/BaseWxPayServiceImpl.java

@@ -75,9 +75,6 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
   private final ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
 
   @Getter
-  private final ProfitSharingV3Service profitSharingV3Service = new ProfitSharingV3ServiceImpl(this);
-
-  @Getter
   private final RedpackService redpackService = new RedpackServiceImpl(this);
 
   @Getter

+ 174 - 2
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImpl.java

@@ -1,10 +1,25 @@
 package com.github.binarywang.wxpay.service.impl;
 
-import com.github.binarywang.wxpay.bean.profitsharing.*;
+import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
+import com.github.binarywang.wxpay.bean.profitsharing.notify.ProfitSharingNotifyV3Response;
+import com.github.binarywang.wxpay.bean.profitsharing.notify.ProfitSharingNotifyV3Result;
+import com.github.binarywang.wxpay.bean.profitsharing.request.*;
+import com.github.binarywang.wxpay.bean.profitsharing.result.*;
 import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.ProfitSharingService;
 import com.github.binarywang.wxpay.service.WxPayService;
+import com.github.binarywang.wxpay.v3.auth.Verifier;
+import com.github.binarywang.wxpay.v3.util.AesUtils;
+import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
+import com.google.gson.Gson;
+import com.google.gson.GsonBuilder;
+import org.apache.commons.lang3.StringUtils;
+
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.security.GeneralSecurityException;
+import java.util.Objects;
 
 /**
  * @author Wang GuangXin 2019/10/22 10:13
@@ -12,6 +27,7 @@ import com.github.binarywang.wxpay.service.WxPayService;
  */
 public class ProfitSharingServiceImpl implements ProfitSharingService {
   private WxPayService payService;
+  private static final Gson GSON = new GsonBuilder().create();
 
   public ProfitSharingServiceImpl(WxPayService payService) {
     this.payService = payService;
@@ -40,7 +56,15 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
-  public ProfitSharingResult profitSharingFinish(ProfitSharingFinishRequest request) throws WxPayException {
+  public ProfitSharingV3Result profitSharingV3(ProfitSharingV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/orders", this.payService.getPayBaseUrl());
+    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
+    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
+    return GSON.fromJson(result, ProfitSharingV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingResult profitSharingFinish(ProfitSharingUnfreezeRequest request) throws WxPayException {
     request.checkAndSign(this.payService.getConfig());
     String url = this.payService.getPayBaseUrl() + "/secapi/pay/profitsharingfinish";
 
@@ -73,6 +97,22 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
+  public ProfitSharingReceiverV3Result addReceiverV3(ProfitSharingReceiverV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/receivers/add", this.payService.getPayBaseUrl());
+    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
+    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
+    return GSON.fromJson(result, ProfitSharingReceiverV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingReceiverV3Result removeReceiverV3(ProfitSharingReceiverV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/receivers/delete", this.payService.getPayBaseUrl());
+    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
+    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
+    return GSON.fromJson(result, ProfitSharingReceiverV3Result.class);
+  }
+
+  @Override
   public ProfitSharingQueryResult profitSharingQuery(ProfitSharingQueryRequest request) throws WxPayException {
     request.setAppid(null);
 
@@ -87,6 +127,34 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
+  public ProfitSharingV3Result profitSharingQueryV3(String outOrderNo, String transactionId) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/orders/%s?transaction_id=%s", this.payService.getPayBaseUrl(),
+      outOrderNo, transactionId);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingV3Result profitSharingQueryV3(String outOrderNo, String transactionId, String subMchId)
+    throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/orders/%s?sub_mchid=%s&transaction_id=%s",
+      this.payService.getPayBaseUrl(), outOrderNo, subMchId, transactionId);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingV3Result profitSharingQueryV3(ProfitSharingQueryV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/orders/%s?transaction_id=%s", this.payService.getPayBaseUrl(),
+      request.getOutOrderNo(), request.getOutOrderNo());
+    if(StringUtils.isNotEmpty(request.getSubMchId())){
+      url += "&sub_mchid=" + request.getSubMchId();
+    }
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingV3Result.class);
+  }
+
+  @Override
   public ProfitSharingOrderAmountQueryResult profitSharingOrderAmountQuery(ProfitSharingOrderAmountQueryRequest request) throws WxPayException {
     request.checkAndSign(this.payService.getConfig());
     String url = this.payService.getPayBaseUrl() + "/pay/profitsharingorderamountquery";
@@ -98,6 +166,13 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
+  public ProfitSharingOrderAmountQueryV3Result profitSharingUnsplitAmountQueryV3(String transactionId) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/transactions/%s/amounts", this.payService.getPayBaseUrl(), transactionId);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingOrderAmountQueryV3Result.class);
+  }
+
+  @Override
   public ProfitSharingMerchantRatioQueryResult profitSharingMerchantRatioQuery(ProfitSharingMerchantRatioQueryRequest request) throws WxPayException {
     request.checkAndSign(this.payService.getConfig());
     String url = this.payService.getPayBaseUrl() + "/pay/profitsharingmerchantratioquery";
@@ -109,6 +184,13 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
+  public ProfitSharingMerchantRatioQueryV3Result profitSharingMerchantRatioQueryV3(String subMchId) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/merchant-configs/%s", this.payService.getPayBaseUrl(), subMchId);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingMerchantRatioQueryV3Result.class);
+  }
+
+  @Override
   public ProfitSharingReturnResult profitSharingReturn(ProfitSharingReturnRequest returnRequest) throws WxPayException {
     returnRequest.checkAndSign(this.payService.getConfig());
     String url = this.payService.getPayBaseUrl() + "/secapi/pay/profitsharingreturn";
@@ -120,6 +202,14 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
   }
 
   @Override
+  public ProfitSharingReturnV3Result profitSharingReturnV3(ProfitSharingReturnV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/return-orders", this.payService.getPayBaseUrl());
+    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
+    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
+    return GSON.fromJson(result, ProfitSharingReturnV3Result.class);
+  }
+
+  @Override
   public ProfitSharingReturnResult profitSharingReturnQuery(ProfitSharingReturnQueryRequest queryRequest) throws WxPayException {
     queryRequest.checkAndSign(this.payService.getConfig());
     String url = this.payService.getPayBaseUrl() + "/pay/profitsharingreturnquery";
@@ -129,4 +219,86 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
     result.checkResult(this.payService, queryRequest.getSignType(), true);
     return result;
   }
+
+  @Override
+  public ProfitSharingReturnV3Result profitSharingReturnQueryV3(String outOrderNo, String outReturnNo) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/return-orders/%s?out_order_no=%s", this.payService.getPayBaseUrl(),
+      outReturnNo, outOrderNo);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingReturnV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingReturnV3Result profitSharingReturnQueryV3(String outOrderNo, String outReturnNo, String subMchId)
+    throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/return-orders/%s?sub_mchid=%s&out_order_no=%s",
+      this.payService.getPayBaseUrl(), outReturnNo, subMchId, outOrderNo);
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingReturnV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingUnfreezeV3Result profitSharingUnfreeze(ProfitSharingUnfreezeV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/orders/unfreeze", this.payService.getPayBaseUrl());
+    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
+    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
+    return GSON.fromJson(result, ProfitSharingUnfreezeV3Result.class);
+  }
+
+  @Override
+  public ProfitSharingNotifyV3Result parseProfitSharingNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
+    ProfitSharingNotifyV3Response response = parseNotifyData(notifyData, header);
+    ProfitSharingNotifyV3Response.Resource resource = response.getResource();
+    String cipherText = resource.getCipherText();
+    String associatedData = resource.getAssociatedData();
+    String nonce = resource.getNonce();
+    String apiV3Key = this.payService.getConfig().getApiV3Key();
+    try {
+      String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
+      return GSON.fromJson(result, ProfitSharingNotifyV3Result.class);
+    } catch (GeneralSecurityException | IOException e) {
+      throw new WxPayException("解析报文异常!", e);
+    }
+  }
+
+  @Override
+  public ProfitSharingBillV3Result profitSharingBill(ProfitSharingBillV3Request request) throws WxPayException {
+    String url = String.format("%s/v3/profitsharing/bills?bill_date=%s", this.payService.getPayBaseUrl(),
+      request.getBillDate());
+
+    if (StringUtils.isNotBlank(request.getSubMchId())) {
+      url = String.format("%s&sub_mchid=%s", url, request.getSubMchId());
+    }
+    if (StringUtils.isNotBlank(request.getTarType())) {
+      url = String.format("%s&tar_type=%s", url, request.getTarType());
+    }
+    String result = this.payService.getV3(url);
+    return GSON.fromJson(result, ProfitSharingBillV3Result.class);
+  }
+
+
+
+  private ProfitSharingNotifyV3Response parseNotifyData(String data, SignatureHeader header) throws WxPayException {
+    if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
+      throw new WxPayException("非法请求,头部信息验证失败");
+    }
+    return GSON.fromJson(data, ProfitSharingNotifyV3Response.class);
+  }
+
+  /**
+   * 校验通知签名
+   *
+   * @param header 通知头信息
+   * @param data   通知数据
+   * @return true:校验通过 false:校验不通过
+   */
+  private boolean verifyNotifySign(SignatureHeader header, String data) throws WxPayException {
+    String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
+    Verifier verifier = this.payService.getConfig().getVerifier();
+    if (verifier == null) {
+      throw new WxPayException("证书检验对象为空");
+    }
+    return verifier.verify(header.getSerial(),
+      beforeSign.getBytes(StandardCharsets.UTF_8), header.getSignature());
+  }
 }

+ 0 - 220
weixin-java-pay/src/main/java/com/github/binarywang/wxpay/service/impl/ProfitSharingV3ServiceImpl.java

@@ -1,220 +0,0 @@
-package com.github.binarywang.wxpay.service.impl;
-
-import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
-import com.github.binarywang.wxpay.bean.profitsharing.v3.*;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.ProfitSharingV3Service;
-import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.v3.auth.Verifier;
-import com.github.binarywang.wxpay.v3.util.AesUtils;
-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 java.io.IOException;
-import java.nio.charset.StandardCharsets;
-import java.security.GeneralSecurityException;
-import java.util.Objects;
-
-/**
- * 微信支付V3-资金应用-分账Service
- *
- * @author pg 2021-6-23
- * @version 1.0
- */
-@Slf4j
-@RequiredArgsConstructor
-public class ProfitSharingV3ServiceImpl implements ProfitSharingV3Service {
-  private static final Gson GSON = new GsonBuilder().create();
-  private final WxPayService payService;
-
-  @Override
-  public ProfitSharingMerchantMaxRatioQueryResult getProfitSharingMerchantMaxRatio(String subMchId) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/merchant-configs/%s", this.payService.getPayBaseUrl(), subMchId);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingMerchantMaxRatioQueryResult.class);
-  }
-
-  @Override
-  public ProfitSharingResult profitSharing(ProfitSharingRequest request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/orders", this.payService.getPayBaseUrl());
-    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
-    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
-    return GSON.fromJson(result, ProfitSharingResult.class);
-  }
-
-  @Override
-  public ProfitSharingResult getProfitSharingResult(String outOrderNo, String transactionId) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/orders/%s?transaction_id=%s", this.payService.getPayBaseUrl(),
-      outOrderNo, transactionId);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingResult.class);
-  }
-
-  @Override
-  public ProfitSharingResult getProfitSharingResult(String outOrderNo, String transactionId, String subMchId)
-    throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/orders/%s?sub_mchid=%s&transaction_id=%s",
-      this.payService.getPayBaseUrl(), outOrderNo, subMchId, transactionId);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingResult.class);
-  }
-
-  @Override
-  public ProfitSharingReturnResult profitSharingReturn(ProfitSharingReturnRequest request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/return-orders", this.payService.getPayBaseUrl());
-    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
-    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
-    return GSON.fromJson(result, ProfitSharingReturnResult.class);
-  }
-
-  @Override
-  public ProfitSharingReturnResult getProfitSharingReturnResult(String outOrderNo, String outReturnNo) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/return-orders/%s?out_order_no=%s", this.payService.getPayBaseUrl(),
-      outReturnNo, outOrderNo);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingReturnResult.class);
-  }
-
-  @Override
-  public ProfitSharingReturnResult getProfitSharingReturnResult(String outOrderNo, String outReturnNo, String subMchId)
-    throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/return-orders/%s?sub_mchid=%s&out_order_no=%s",
-      this.payService.getPayBaseUrl(), outReturnNo, subMchId, outOrderNo);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingReturnResult.class);
-  }
-
-  @Override
-  public ProfitSharingUnfreezeResult profitSharingUnfreeze(ProfitSharingUnfreezeRequest request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/orders/unfreeze", this.payService.getPayBaseUrl());
-    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
-    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
-    return GSON.fromJson(result, ProfitSharingUnfreezeResult.class);
-  }
-
-  @Override
-  public ProfitSharingUnsplitResult getProfitSharingUnsplitAmount(String transactionId) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/transactions/%s/amounts", this.payService.getPayBaseUrl(), transactionId);
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingUnsplitResult.class);
-  }
-
-  @Override
-  public ProfitSharingReceiver addProfitSharingReceiver(ProfitSharingReceiver request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/receivers/add", this.payService.getPayBaseUrl());
-    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
-    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
-    return GSON.fromJson(result, ProfitSharingReceiver.class);
-  }
-
-  @Override
-  public ProfitSharingReceiver deleteProfitSharingReceiver(ProfitSharingReceiver request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/receivers/delete", this.payService.getPayBaseUrl());
-    RsaCryptoUtil.encryptFields(request, this.payService.getConfig().getVerifier().getValidCertificate());
-    String result = this.payService.postV3WithWechatpaySerial(url, GSON.toJson(request));
-    return GSON.fromJson(result, ProfitSharingReceiver.class);
-  }
-
-  @Override
-  public ProfitSharingNotifyResult getProfitSharingNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
-    ProfitSharingNotifyData response = parseNotifyData(notifyData, header);
-    ProfitSharingNotifyData.Resource resource = response.getResource();
-    String cipherText = resource.getCipherText();
-    String associatedData = resource.getAssociatedData();
-    String nonce = resource.getNonce();
-    String apiV3Key = this.payService.getConfig().getApiV3Key();
-    try {
-      String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
-      return GSON.fromJson(result, ProfitSharingNotifyResult.class);
-    } catch (GeneralSecurityException | IOException e) {
-      throw new WxPayException("解析报文异常!", e);
-    }
-  }
-
-  @Override
-  public ProfitSharingPartnerNotifyResult getProfitSharingPartnerNotifyResult(String notifyData, SignatureHeader header) throws WxPayException {
-    ProfitSharingNotifyData response = parseNotifyData(notifyData, header);
-    ProfitSharingNotifyData.Resource resource = response.getResource();
-    String cipherText = resource.getCipherText();
-    String associatedData = resource.getAssociatedData();
-    String nonce = resource.getNonce();
-    String apiV3Key = this.payService.getConfig().getApiV3Key();
-    try {
-      String result = AesUtils.decryptToString(associatedData, nonce, cipherText, apiV3Key);
-      return GSON.fromJson(result, ProfitSharingPartnerNotifyResult.class);
-    } catch (GeneralSecurityException | IOException e) {
-      throw new WxPayException("解析报文异常!", e);
-    }
-  }
-
-  @Override
-  public ProfitSharingBillResult getProfitSharingBill(ProfitSharingBillRequest request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/bills?bill_date=%s", this.payService.getPayBaseUrl(),
-      request.getBillDate());
-
-    if (StringUtils.isNotBlank(request.getSubMchId())) {
-      url = String.format("%s&sub_mchid=%s", url, request.getSubMchId());
-    }
-    if (StringUtils.isNotBlank(request.getTarType())) {
-      url = String.format("%s&tar_type=%s", url, request.getTarType());
-    }
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingBillResult.class);
-  }
-
-  /**
-   * <pre>
-   * 请求分账查询API
-   *
-   * 发起分账请求后,可调用此接口查询分账结果
-   * 文档详见: https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml
-   * 接口链接: https://api.mch.weixin.qq.com/v3/profitsharing/orders/{out_order_no}
-   *
-   * 注意:
-   * 发起解冻剩余资金请求后,可调用此接口查询解冻剩余资金的结果
-   * </pre>
-   *
-   * @param request {@link ProfitSharingQueryRequest} 针对某一笔分账订单的分账方法
-   * @return {@link ProfitSharingResult} 微信返回的分账查询结果
-   * @throws WxPayException the wx pay exception
-   * @see <a href="https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter8_1_2.shtml">微信文档</a>
-   */
-  @Override
-  public ProfitSharingResult profitSharingQuery(ProfitSharingQueryRequest request) throws WxPayException {
-    String url = String.format("%s/v3/profitsharing/orders/%s?transaction_id=%s", this.payService.getPayBaseUrl(),
-      request.getOutOrderNo(), request.getOutOrderNo());
-    if(StringUtils.isNotEmpty(request.getSubMchId())){
-      url += "&sub_mchid=" + request.getSubMchId();
-    }
-    String result = this.payService.getV3(url);
-    return GSON.fromJson(result, ProfitSharingResult.class);
-  }
-
-  private ProfitSharingNotifyData parseNotifyData(String data, SignatureHeader header) throws WxPayException {
-    if (Objects.nonNull(header) && !this.verifyNotifySign(header, data)) {
-      throw new WxPayException("非法请求,头部信息验证失败");
-    }
-    return GSON.fromJson(data, ProfitSharingNotifyData.class);
-  }
-
-  /**
-   * 校验通知签名
-   *
-   * @param header 通知头信息
-   * @param data   通知数据
-   * @return true:校验通过 false:校验不通过
-   */
-  private boolean verifyNotifySign(SignatureHeader header, String data) throws WxPayException {
-    String beforeSign = String.format("%s%n%s%n%s%n", header.getTimeStamp(), header.getNonce(), data);
-    Verifier verifier = this.payService.getConfig().getVerifier();
-    if (verifier == null) {
-      throw new WxPayException("证书检验对象为空");
-    }
-    return verifier.verify(header.getSerial(),
-      beforeSign.getBytes(StandardCharsets.UTF_8), header.getSignature());
-  }
-}

+ 1 - 0
weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingQueryResultTest.java

@@ -1,5 +1,6 @@
 package com.github.binarywang.wxpay.bean.profitsharing;
 
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingQueryResult;
 import org.testng.annotations.Test;
 
 import java.util.List;

+ 2 - 1
weixin-java-pay/src/test/java/com/github/binarywang/wxpay/bean/profitsharing/ProfitSharingResultTest.java

@@ -1,12 +1,13 @@
 package com.github.binarywang.wxpay.bean.profitsharing;
 
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingResult;
 import org.testng.annotations.Test;
 
 import java.util.List;
 
 import static org.assertj.core.api.Assertions.assertThat;
 
-public class ProfitSharingResultTest {
+public class ProfitSharingV3ResultTest {
 
   @Test
   public void testGetReceiverList() {

+ 17 - 1
weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingServiceImplTest.java

@@ -1,6 +1,11 @@
 package com.github.binarywang.wxpay.service.impl;
 
+import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
 import com.github.binarywang.wxpay.bean.profitsharing.*;
+import com.github.binarywang.wxpay.bean.profitsharing.request.*;
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingMerchantRatioQueryResult;
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingOrderAmountQueryResult;
+import com.github.binarywang.wxpay.bean.profitsharing.result.ProfitSharingQueryResult;
 import com.github.binarywang.wxpay.constant.WxPayConstants;
 import com.github.binarywang.wxpay.exception.WxPayException;
 import com.github.binarywang.wxpay.service.WxPayService;
@@ -52,7 +57,7 @@ public class ProfitSharingServiceImplTest {
 
   @Test
   public void testProfitSharingFinish() throws WxPayException {
-    ProfitSharingFinishRequest request = ProfitSharingFinishRequest
+    ProfitSharingUnfreezeRequest request = ProfitSharingUnfreezeRequest
       .newBuilder()
       .outOrderNo("20191023103251431856285")
       .transactionId("4200000441201910238267278073")
@@ -140,4 +145,15 @@ public class ProfitSharingServiceImplTest {
     log.info(this.payService.getProfitSharingService().profitSharingReturnQuery(request).toString());
   }
 
+  @Test
+  public void testProfitSharingNotifyData() throws WxPayException {
+    SignatureHeader header = new SignatureHeader();
+    header.setSerial("Wechatpay-Serial");
+    header.setTimeStamp("Wechatpay-Timestamp");
+    header.setNonce("Wechatpay-Nonce");
+    header.setSignature("Wechatpay-Signature");
+    String data = "body";
+    log.info(this.payService.getProfitSharingService().parseProfitSharingNotifyResult(data,header).toString());
+  }
+
 }

+ 0 - 35
weixin-java-pay/src/test/java/com/github/binarywang/wxpay/service/impl/ProfitSharingV3ServiceImplTest.java

@@ -1,35 +0,0 @@
-package com.github.binarywang.wxpay.service.impl;
-
-import com.github.binarywang.wxpay.bean.notify.SignatureHeader;
-import com.github.binarywang.wxpay.exception.WxPayException;
-import com.github.binarywang.wxpay.service.WxPayService;
-import com.github.binarywang.wxpay.testbase.ApiTestModule;
-import com.google.inject.Inject;
-import lombok.extern.slf4j.Slf4j;
-import org.testng.annotations.Guice;
-import org.testng.annotations.Test;
-
-/**
- * 测试类
- *
- * @author yuanbo
- * @since 2022-04-26-22:33 PM
- */
-@Test
-@Slf4j
-@Guice(modules = ApiTestModule.class)
-public class ProfitSharingV3ServiceImplTest {
-  @Inject
-  private WxPayService payService;
-
-  @Test
-  public void testProfitSharingNotifyData() throws WxPayException {
-    SignatureHeader header = new SignatureHeader();
-    header.setSerial("Wechatpay-Serial");
-    header.setTimeStamp("Wechatpay-Timestamp");
-    header.setNonce("Wechatpay-Nonce");
-    header.setSignature("Wechatpay-Signature");
-    String data = "body";
-    log.info(this.payService.getProfitSharingV3Service().getProfitSharingNotifyResult(data,header).toString());
-  }
-}