mirror of
https://gitee.com/binary/weixin-java-tools.git
synced 2025-08-24 16:18:51 +08:00
✨ #1010 微信支付模块增加单次分账接口
This commit is contained in:
parent
70ce3a2ff9
commit
81df397536
@ -0,0 +1,33 @@
|
|||||||
|
package com.github.binarywang.wxpay.bean.profitsharing;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.bean.result.BaseWxPayResult;
|
||||||
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
|
import lombok.Data;
|
||||||
|
import lombok.EqualsAndHashCode;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/22 10:06
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@NoArgsConstructor
|
||||||
|
@XStreamAlias("xml")
|
||||||
|
public class ProfitSharingResult extends BaseWxPayResult {
|
||||||
|
/**
|
||||||
|
* 微信订单号.
|
||||||
|
*/
|
||||||
|
@XStreamAlias("transaction_id")
|
||||||
|
private String transactionId;
|
||||||
|
/**
|
||||||
|
* 商户分账单号.
|
||||||
|
*/
|
||||||
|
@XStreamAlias("out_order_no")
|
||||||
|
private String outOrderNo;
|
||||||
|
/**
|
||||||
|
* 微信分账单号.
|
||||||
|
*/
|
||||||
|
@XStreamAlias("order_id")
|
||||||
|
private String orderId;
|
||||||
|
}
|
@ -0,0 +1,86 @@
|
|||||||
|
package com.github.binarywang.wxpay.bean.profitsharing;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.bean.request.BaseWxPayRequest;
|
||||||
|
import com.github.binarywang.wxpay.constant.WxPayConstants;
|
||||||
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||||
|
import com.thoughtworks.xstream.annotations.XStreamAlias;
|
||||||
|
import lombok.*;
|
||||||
|
import me.chanjar.weixin.common.annotation.Required;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/21 17:57
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@EqualsAndHashCode(callSuper = true)
|
||||||
|
@Builder(builderMethodName = "newBuilder")
|
||||||
|
@NoArgsConstructor
|
||||||
|
@AllArgsConstructor
|
||||||
|
@XStreamAlias("xml")
|
||||||
|
public class ProfitsharingRequest extends BaseWxPayRequest {
|
||||||
|
private static final long serialVersionUID = 212049937430575842L;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 字段名:微信订单号.
|
||||||
|
* 变量名:transaction_id
|
||||||
|
* 是否必填:是
|
||||||
|
* String(32)
|
||||||
|
* 示例值:4208450740201411110007820472
|
||||||
|
* 描述:微信支付订单号
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@XStreamAlias("transaction_id")
|
||||||
|
@Required
|
||||||
|
private String transactionId;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 字段名:商户分账单号.
|
||||||
|
* 变量名:out_order_no
|
||||||
|
* 是否必填:是
|
||||||
|
* String(64)
|
||||||
|
* 示例值:P20150806125346
|
||||||
|
* 描述:商户系统内部的分账单号,在商户系统内部唯一(单次分账、多次分账、完结分账应使用不同的商户分账单号),同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@XStreamAlias("out_order_no")
|
||||||
|
@Required
|
||||||
|
private String outOrderNo;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <pre>
|
||||||
|
* 字段名:分账接收方列表.
|
||||||
|
* 变量名:receivers
|
||||||
|
* 是否必填:是
|
||||||
|
* String(10240)
|
||||||
|
* 示例值:[
|
||||||
|
* {
|
||||||
|
* "type": "MERCHANT_ID",
|
||||||
|
* "account":"190001001",
|
||||||
|
* "amount":100,
|
||||||
|
* "description": "分到商户"
|
||||||
|
* },
|
||||||
|
* {
|
||||||
|
* "type": "PERSONAL_WECHATID",
|
||||||
|
* "account":"86693952",
|
||||||
|
* "amount":888,
|
||||||
|
* "description": "分到个人"
|
||||||
|
* }
|
||||||
|
* ]
|
||||||
|
* 描述:分账接收方列表,不超过50个json对象,不能设置分账方作为分账接受方,使用Json格式
|
||||||
|
* </pre>
|
||||||
|
*/
|
||||||
|
@XStreamAlias("receivers")
|
||||||
|
@Required
|
||||||
|
private String receivers;
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void checkConstraints() throws WxPayException {
|
||||||
|
/**
|
||||||
|
* 目前仅支持HMAC-SHA256
|
||||||
|
*/
|
||||||
|
this.setSignType(WxPayConstants.SignType.HMAC_SHA256);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,47 @@
|
|||||||
|
package com.github.binarywang.wxpay.bean.profitsharing;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/22 11:07
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class Receiver implements Serializable {
|
||||||
|
private String type;
|
||||||
|
private String account;
|
||||||
|
private Integer amount;
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @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 Receiver(String type, String account, Integer amount, String description) {
|
||||||
|
this.type = type;
|
||||||
|
this.account = account;
|
||||||
|
this.amount = amount;
|
||||||
|
this.description = description;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getAccount() {
|
||||||
|
return account;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getAmount() {
|
||||||
|
return amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package com.github.binarywang.wxpay.bean.profitsharing;
|
||||||
|
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/22 11:01
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class ReceiverList implements Serializable {
|
||||||
|
private static final long serialVersionUID = -1316860887694489921L;
|
||||||
|
ArrayList list;
|
||||||
|
|
||||||
|
private ReceiverList() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取一个实例
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static ReceiverList getInstance() {
|
||||||
|
ReceiverList receiverList = new ReceiverList();
|
||||||
|
receiverList.list = new ArrayList();
|
||||||
|
return receiverList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加一个分账条目
|
||||||
|
* 注意微信上限为50个
|
||||||
|
* @param receiver
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public ReceiverList add(Receiver receiver) {
|
||||||
|
this.list.add(receiver);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 转为JSON格式
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public String toJSONString() {
|
||||||
|
Gson gson = new Gson();
|
||||||
|
return gson.toJson(this.list);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -1,12 +1,11 @@
|
|||||||
package com.github.binarywang.wxpay.constant;
|
package com.github.binarywang.wxpay.constant;
|
||||||
|
|
||||||
|
import com.google.common.collect.Lists;
|
||||||
|
import org.apache.commons.lang3.time.FastDateFormat;
|
||||||
|
|
||||||
import java.text.Format;
|
import java.text.Format;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import org.apache.commons.lang3.time.FastDateFormat;
|
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 微信支付常量类
|
* 微信支付常量类
|
||||||
@ -273,4 +272,23 @@ public class WxPayConstants {
|
|||||||
*/
|
*/
|
||||||
public static final String CHANGE = "CHANGE";
|
public static final String CHANGE = "CHANGE";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class ReceiverType {
|
||||||
|
/**
|
||||||
|
* 商户id
|
||||||
|
*/
|
||||||
|
public static final String MERCHANT_ID = "MERCHANT_ID";
|
||||||
|
/**
|
||||||
|
* 个人微信号
|
||||||
|
*/
|
||||||
|
public static final String PERSONAL_WECHATID = "PERSONAL_WECHATID";
|
||||||
|
/**
|
||||||
|
* 个人openid
|
||||||
|
*/
|
||||||
|
public static final String PERSONAL_OPENID = "PERSONAL_OPENID";
|
||||||
|
/**
|
||||||
|
* 个人sub_openid
|
||||||
|
*/
|
||||||
|
public static final String PERSONAL_SUB_OPENID = "PERSONAL_SUB_OPENID";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package com.github.binarywang.wxpay.service;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingResult;
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ProfitsharingRequest;
|
||||||
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/22 10:05
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public interface ProfitSharingService {
|
||||||
|
/**
|
||||||
|
* 单次分账请求按照传入的分账接收方账号和资金进行分账,同时会将订单剩余的待分账金额解冻给特约商户。故操作成功后,订单不能再进行分账,也不能进行分账完结。
|
||||||
|
* <p>
|
||||||
|
* 接口频率:30QPS
|
||||||
|
* 文档详见: https://pay.weixin.qq.com/wiki/doc/api/allocation_sl.php?chapter=25_1&index=1
|
||||||
|
* 接口链接:https://api.mch.weixin.qq.com/secapi/pay/profitsharing
|
||||||
|
*
|
||||||
|
* @param profitsharingRequest
|
||||||
|
* @return
|
||||||
|
* @throws WxPayException the wx pay exception
|
||||||
|
*/
|
||||||
|
ProfitSharingResult profitsharing(ProfitsharingRequest profitsharingRequest) throws WxPayException;
|
||||||
|
|
||||||
|
;
|
||||||
|
}
|
@ -65,6 +65,13 @@ public interface WxPayService {
|
|||||||
*/
|
*/
|
||||||
EntPayService getEntPayService();
|
EntPayService getEntPayService();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取分账服务类.
|
||||||
|
*
|
||||||
|
* @return the ent pay service
|
||||||
|
*/
|
||||||
|
ProfitSharingService getProfitSharingService();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 设置企业付款服务类,允许开发者自定义实现类.
|
* 设置企业付款服务类,允许开发者自定义实现类.
|
||||||
*
|
*
|
||||||
@ -304,6 +311,7 @@ public interface WxPayService {
|
|||||||
* @throws WxPayException the wx pay exception
|
* @throws WxPayException the wx pay exception
|
||||||
*/
|
*/
|
||||||
WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException;
|
WxPayRedpackQueryResult queryRedpack(String mchBillNo) throws WxPayException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <pre>
|
* <pre>
|
||||||
* 查询红包记录.
|
* 查询红包记录.
|
||||||
|
@ -18,6 +18,7 @@ import com.github.binarywang.wxpay.constant.WxPayConstants.SignType;
|
|||||||
import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType;
|
import com.github.binarywang.wxpay.constant.WxPayConstants.TradeType;
|
||||||
import com.github.binarywang.wxpay.exception.WxPayException;
|
import com.github.binarywang.wxpay.exception.WxPayException;
|
||||||
import com.github.binarywang.wxpay.service.EntPayService;
|
import com.github.binarywang.wxpay.service.EntPayService;
|
||||||
|
import com.github.binarywang.wxpay.service.ProfitSharingService;
|
||||||
import com.github.binarywang.wxpay.service.WxPayService;
|
import com.github.binarywang.wxpay.service.WxPayService;
|
||||||
import com.github.binarywang.wxpay.util.SignUtils;
|
import com.github.binarywang.wxpay.util.SignUtils;
|
||||||
import com.google.common.base.Joiner;
|
import com.google.common.base.Joiner;
|
||||||
@ -59,7 +60,7 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
|||||||
static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>();
|
static ThreadLocal<WxPayApiData> wxApiData = new ThreadLocal<>();
|
||||||
|
|
||||||
private EntPayService entPayService = new EntPayServiceImpl(this);
|
private EntPayService entPayService = new EntPayServiceImpl(this);
|
||||||
|
private ProfitSharingService profitSharingService = new ProfitSharingServiceImpl(this);
|
||||||
/**
|
/**
|
||||||
* The Config.
|
* The Config.
|
||||||
*/
|
*/
|
||||||
@ -70,6 +71,11 @@ public abstract class BaseWxPayServiceImpl implements WxPayService {
|
|||||||
return entPayService;
|
return entPayService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProfitSharingService getProfitSharingService() {
|
||||||
|
return profitSharingService;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEntPayService(EntPayService entPayService) {
|
public void setEntPayService(EntPayService entPayService) {
|
||||||
this.entPayService = entPayService;
|
this.entPayService = entPayService;
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package com.github.binarywang.wxpay.service.impl;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ProfitSharingResult;
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ProfitsharingRequest;
|
||||||
|
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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Wang GuangXin 2019/10/22 10:13
|
||||||
|
* @version 1.0
|
||||||
|
*/
|
||||||
|
public class ProfitSharingServiceImpl implements ProfitSharingService {
|
||||||
|
private WxPayService payService;
|
||||||
|
public ProfitSharingServiceImpl(WxPayService payService) {
|
||||||
|
this.payService = payService;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ProfitSharingResult profitsharing(ProfitsharingRequest request) throws WxPayException {
|
||||||
|
request.checkAndSign(this.payService.getConfig());
|
||||||
|
String url = this.payService.getPayBaseUrl() + "/secapi/pay/profitsharing";
|
||||||
|
|
||||||
|
String responseContent = this.payService.post(url, request.toXML(), true);
|
||||||
|
ProfitSharingResult result = BaseWxPayResult.fromXML(responseContent, ProfitSharingResult.class);
|
||||||
|
result.checkResult(this.payService, request.getSignType(), true);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,40 @@
|
|||||||
|
package com.github.binarywang.wxpay.service.impl;
|
||||||
|
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ProfitsharingRequest;
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.Receiver;
|
||||||
|
import com.github.binarywang.wxpay.bean.profitsharing.ReceiverList;
|
||||||
|
import com.github.binarywang.wxpay.constant.WxPayConstants;
|
||||||
|
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 org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.testng.annotations.Guice;
|
||||||
|
import org.testng.annotations.Test;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Guice(modules = ApiTestModule.class)
|
||||||
|
public class ProfitSharingServiceImplTest {
|
||||||
|
private final Logger logger = LoggerFactory.getLogger(this.getClass());
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private WxPayService payService;
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testProfitsharing() throws WxPayException {
|
||||||
|
ReceiverList instance = ReceiverList.getInstance();
|
||||||
|
instance.add(new Receiver(WxPayConstants.ReceiverType.PERSONAL_OPENID,
|
||||||
|
"oyOUE5ql4TtzrBg5cVOwxq6tbjOs",
|
||||||
|
100,
|
||||||
|
"分到用户"));
|
||||||
|
ProfitsharingRequest request = ProfitsharingRequest
|
||||||
|
.newBuilder()
|
||||||
|
.outOrderNo("P20150806125346")
|
||||||
|
.transactionId("4208450740201411110007820472")
|
||||||
|
// .receivers("[{\"type\": \"PERSONAL_OPENID\",\"account\":\"oyOUE5ql4TtzrBg5cVOwxq6tbjOs\",\"amount\":100,\"description\": \"分到用户\"}]")
|
||||||
|
.receivers(instance.toJSONString())
|
||||||
|
.build();
|
||||||
|
this.logger.info(this.payService.getProfitSharingService().profitsharing(request).toString());
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user