分账功能实现

This commit is contained in:
egzosn
2021-10-06 23:32:37 +08:00
parent 973a469850
commit 9b82bcabef
2 changed files with 293 additions and 0 deletions

View File

@@ -0,0 +1,264 @@
package com.egzosn.pay.demo.controller;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import com.egzosn.pay.common.bean.AssistOrder;
import com.egzosn.pay.common.bean.CertStoreType;
import com.egzosn.pay.common.bean.RefundResult;
import com.egzosn.pay.demo.request.QueryOrder;
import com.egzosn.pay.demo.service.handler.WxV3ProfitSharingMessageHandler;
import com.egzosn.pay.web.support.HttpRequestNoticeParams;
import com.egzosn.pay.wx.v3.api.WxPayConfigStorage;
import com.egzosn.pay.wx.v3.api.WxProfitSharingService;
import com.egzosn.pay.wx.v3.bean.WxProfitSharingTransactionType;
import com.egzosn.pay.wx.v3.bean.sharing.ProfitSharingBillType;
import com.egzosn.pay.wx.v3.bean.sharing.ProfitSharingOrder;
import com.egzosn.pay.wx.v3.bean.sharing.ProfitSharingReturnOrder;
import com.egzosn.pay.wx.v3.bean.sharing.Receiver;
import com.egzosn.pay.wx.v3.bean.sharing.ReceiverType;
import com.egzosn.pay.wx.v3.bean.sharing.ReceiversOrder;
import com.egzosn.pay.wx.v3.bean.sharing.RelationType;
/**
* 微信V3分账发起支付入口
*
* @author egan
* email egzosn@gmail.com
* date 2016/11/18 0:25
*/
@RestController
@RequestMapping("wxV3profitSharing")
public class WxV3ProfitSharingController {
private WxProfitSharingService service = null;
@PostConstruct //没有证书的情况下注释掉,避免启动报错
public void init() {
WxPayConfigStorage wxPayConfigStorage = new WxPayConfigStorage();
wxPayConfigStorage.setAppId("wxc7b993ff15a9f26c");
wxPayConfigStorage.setMchId("1602947765");
//V3密钥 https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_2.shtml
wxPayConfigStorage.setV3ApiKey("9bd8f0e7af4841299d782406b7774f57");
wxPayConfigStorage.setNotifyUrl("http://sailinmu.iok.la/wxV3profitSharing/payBack.json");
wxPayConfigStorage.setReturnUrl("http://sailinmu.iok.la/wxV3profitSharing/payBack.json");
wxPayConfigStorage.setInputCharset("utf-8");
//使用证书时设置为true
wxPayConfigStorage.setCertSign(true);
//商户API证书 https://pay.weixin.qq.com/wiki/doc/apiv3/wechatpay/wechatpay3_1.shtml
wxPayConfigStorage.setApiClientKeyP12("yifenli_mall.p12");
wxPayConfigStorage.setCertStoreType(CertStoreType.PATH);
service = new WxProfitSharingService(wxPayConfigStorage);
//设置回调消息处理
//TODO {@link com.egzosn.pay.demo.controller.WxPayController#payBack}
service.setPayMessageHandler(new WxV3ProfitSharingMessageHandler());
}
/**
* 请求分账API
*
* @return 分账
*/
@RequestMapping(value = "orders")
public Map<String, Object> orders() {
ProfitSharingOrder order = new ProfitSharingOrder();
order.setTransactionType(WxProfitSharingTransactionType.ORDERS);
order.setSubMchid("服务商必填----微信支付分配的子商户号,即分账的出资商户号。");
order.setSubAppid("服务商必填----微信分配的子商户公众账号ID分账接收方类型包含PERSONAL_SUB_OPENID时必填。");
order.setTransactionId("微信支付订单号");
order.setOutOrderNo("务商系统内部的分账单号在服务商系统内部唯一同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ ");
List<Receiver> receivers = new ArrayList<>();
Receiver receiver = new Receiver();
//1、MERCHANT_ID商户号
//2、PERSONAL_OPENID个人openid由父商户APPID转换得到
//3、PERSONAL_SUB_OPENID: 个人sub_openid由子商户APPID转换得到
//示例值MERCHANT_ID
receiver.setType(ReceiverType.MERCHANT_ID);
receiver.setName("分账个人接收方姓名");
receiver.setAccount("分账接收方账号");
//分账金额,单位为分,只能为整数,不能超过原订单支付金额及最大分账比例金额
receiver.setAmount(1);
receiver.setDescription("分账的原因描述,分账账单中需要体现");
order.setReceivers(receivers);
//1、如果为true该笔订单剩余未分账的金额会解冻回分账方商户
//2、如果为false该笔订单剩余未分账的金额不会解冻回分账方商户可以对该笔订单再次进行分账。
order.setUnfreezeUnsplit(true);
Map<String, Object> orderInfo = service.orderInfo(order);
orderInfo.put("code", 0);
return orderInfo;
}
/**
* 获取支付预订单信息
*
* @return 支付预订单信息
*/
@RequestMapping("unfreeze")
public Map<String, Object> unfreeze() {
ProfitSharingOrder order = new ProfitSharingOrder();
order.setTransactionType(WxProfitSharingTransactionType.ORDERS_UNFREEZE);
order.setSubMchid("服务商必填----微信支付分配的子商户号,即分账的出资商户号。");
order.setTransactionId("微信支付订单号");
order.setOutOrderNo("务商系统内部的分账单号在服务商系统内部唯一同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ ");
order.setSubject("分账的原因描述,分账账单中需要体现");
return service.orderInfo(order);
}
/**
* 添加分账接收方
*
* @return 添加分账接收方
*/
@RequestMapping("add")
public Map<String, Object> add() {
ReceiversOrder order = new ReceiversOrder();
order.setTransactionType(WxProfitSharingTransactionType.RECEIVERS_ADD);
order.setSubMchid("服务商必填----微信支付分配的子商户号,即分账的出资商户号。");
order.setSubAppid("服务商必填----子商户应用ID");
//分账接收方类型:
order.setType(ReceiverType.MERCHANT_ID);
order.setAccount("分账接收方账号");
order.setName("分账个人接收方姓名");
//与分账方的关系类型
order.setRelationType(RelationType.BRAND);
order.setCustomRelation("自定义的分账关系,子商户与接收方具体的关系本字段最多10个字。\n" +
"当字段relation_type的值为CUSTOM时本字段必填\n" +
"当字段relation_type的值不为CUSTOM时本字段无需填写");
return service.orderInfo(order);
}
/**
* 删除分账接收方
*
* @return 删除分账接收方
*/
@RequestMapping("delete")
public Map<String, Object> delete() {
ReceiversOrder order = new ReceiversOrder();
order.setTransactionType(WxProfitSharingTransactionType.RECEIVERS_DELETE);
order.setSubMchid("服务商必填----微信支付分配的子商户号,即分账的出资商户号。");
order.setSubAppid("服务商必填----子商户应用ID");
//分账接收方类型:
order.setType(ReceiverType.MERCHANT_ID);
order.setAccount("分账接收方账号");
return service.orderInfo(order);
}
/**
* 分账回调地址
*
* @param request 请求
* @return 是否成功
* <p>
* 业务处理在对应的PayMessageHandler里面处理在哪里设置PayMessageHandler详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)}
* <p>
* 如果未设置 {@link com.egzosn.pay.common.api.PayMessageHandler} 那么会使用默认的 {@link com.egzosn.pay.common.api.DefaultPayMessageHandler}
* @throws IOException IOException
*/
@RequestMapping(value = "payBack.json")
public String payBack(HttpServletRequest request) {
//业务处理在对应的PayMessageHandler里面处理在哪里设置PayMessageHandler详情查看com.egzosn.pay.common.api.PayService.setPayMessageHandler()
return service.payBack(new HttpRequestNoticeParams(request)).toMessage();
}
/**
* 查询分账结果
*
* @return 返回查询回来的结果集,支付方原值返回
*/
@RequestMapping("query")
public Map<String, Object> query() {
AssistOrder assistOrder = new AssistOrder();
assistOrder.setOutTradeNo("商户分账单号");
assistOrder.setTradeNo("微信订单号");
assistOrder.addAttr("sub_mchid", "服务商必填---子商户号");
return service.query(assistOrder);
}
/**
* 查询剩余待分金额
*
* @return 返回查询回来的结果集,支付方原值返回
*/
@RequestMapping("amounts")
public Map<String, Object> amounts() {
AssistOrder assistOrder = new AssistOrder();
assistOrder.setTradeNo("微信订单号");
return service.query(assistOrder);
}
/**
* 查询最大分账比例
* 服务商使用
* @return 返回查询回来的结果集,支付方原值返回
*/
@RequestMapping("merchantConfigs")
public Map<String, Object> merchantConfigs() {
AssistOrder assistOrder = new AssistOrder();
assistOrder.addAttr("sub_mchid", "服务商必填---子商户号");
return service.query(assistOrder);
}
/**
* 请求分账回退
*
* @return 返回支付方申请退款后的结果
*/
@RequestMapping("refund")
public RefundResult refund() {
ProfitSharingReturnOrder returnOrder = new ProfitSharingReturnOrder();
returnOrder.setSubMchid("服务商必填---子商户号");
returnOrder.setRefundNo("商户回退单号");
returnOrder.setTradeNo("微信分账单号");
returnOrder.setOutTradeNo("商户分账单号");
returnOrder.setRefundAmount(new BigDecimal(1));
returnOrder.setDescription("分账回退的原因描述");
return service.refund(returnOrder);
}
/**
* 查询分账回退结果
*
* @return 返回支付方查询退款后的结果
*/
@RequestMapping("refundquery")
public Map<String, Object> refundquery() {
ProfitSharingReturnOrder returnOrder = new ProfitSharingReturnOrder();
returnOrder.setSubMchid("服务商必填---子商户号");
returnOrder.setRefundNo("商户回退单号");
returnOrder.setOutTradeNo("商户分账单号");
return service.refundquery(returnOrder);
}
/**
* 下载对账单
*
* @param order 订单的请求体
* @return 返回支付方下载对账单的结果
*/
@RequestMapping("downloadbill")
public Object downloadBill(QueryOrder order) {
return service.downloadBill(order.getBillDate(), ProfitSharingBillType.GZIP);
}
}

View File

@@ -0,0 +1,29 @@
package com.egzosn.pay.demo.service.handler;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSON;
import com.egzosn.pay.common.api.DefaultPayMessageHandler;
import com.egzosn.pay.common.api.PayMessageHandler;
import com.egzosn.pay.common.api.PayService;
import com.egzosn.pay.common.bean.PayOutMessage;
import com.egzosn.pay.common.exception.PayErrorException;
import com.egzosn.pay.wx.v3.bean.sharing.ProfitSharingPayMessage;
/**
* 微信合单支付回调处理器
* Created by ZaoSheng on 2016/6/1.
*/
public class WxV3ProfitSharingMessageHandler implements PayMessageHandler<ProfitSharingPayMessage, PayService> {
private final Logger LOG = LoggerFactory.getLogger(DefaultPayMessageHandler.class);
@Override
public PayOutMessage handle(ProfitSharingPayMessage payMessage, Map<String, Object> context, PayService payService) throws PayErrorException {
LOG.info("回调支付消息处理器,回调消息:{}", JSON.toJSONString(payMessage));
return payService.successPayOutMessage(payMessage);
}
}