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

This commit is contained in:
四叶草
2023-08-23 06:11:17 +00:00
committed by Binary Wang
parent f5ac3b181e
commit bcc4839ff0
42 changed files with 904 additions and 897 deletions

View File

@@ -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;
/**
@@ -41,6 +45,26 @@ public interface ProfitSharingService {
*/
ProfitSharingResult multiProfitSharing(ProfitSharingRequest request) 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 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、不需要进行分账的订单可直接调用本接口将订单的金额全部解冻给特约商户
@@ -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>
@@ -83,6 +107,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>
@@ -96,6 +152,66 @@ public interface ProfitSharingService {
*/
ProfitSharingQueryResult profitSharingQuery(ProfitSharingQueryRequest 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 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>
* 服务商可通过调用此接口查询订单剩余待分金额。
@@ -110,6 +226,22 @@ public interface ProfitSharingService {
*/
ProfitSharingOrderAmountQueryResult profitSharingOrderAmountQuery(ProfitSharingOrderAmountQueryRequest 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 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>
* 服务商可以查询子商户设置的允许服务商分账的最大比例。
@@ -124,6 +256,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>
@@ -142,6 +292,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;
}

View File

@@ -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;
}

View File

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

View File

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

View File

@@ -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";
@@ -72,6 +96,22 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
return result;
}
@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);
@@ -86,6 +126,34 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
return result;
}
@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());
@@ -97,6 +165,13 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
return result;
}
@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());
@@ -108,6 +183,13 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
return result;
}
@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());
@@ -119,6 +201,14 @@ public class ProfitSharingServiceImpl implements ProfitSharingService {
return result;
}
@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());
@@ -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());
}
}

View File

@@ -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());
}
}