From 9b82bcabefed0bb584a8c1889e70e26acb1ac770 Mon Sep 17 00:00:00 2001 From: egzosn Date: Wed, 6 Oct 2021 23:32:37 +0800 Subject: [PATCH] =?UTF-8?q?=E5=88=86=E8=B4=A6=E5=8A=9F=E8=83=BD=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../WxV3ProfitSharingController.java | 264 ++++++++++++++++++ .../WxV3ProfitSharingMessageHandler.java | 29 ++ 2 files changed, 293 insertions(+) create mode 100644 pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/WxV3ProfitSharingController.java create mode 100644 pay-java-demo/src/main/java/com/egzosn/pay/demo/service/handler/WxV3ProfitSharingMessageHandler.java diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/WxV3ProfitSharingController.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/WxV3ProfitSharingController.java new file mode 100644 index 0000000..299fea1 --- /dev/null +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/controller/WxV3ProfitSharingController.java @@ -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 orders() { + ProfitSharingOrder order = new ProfitSharingOrder(); + order.setTransactionType(WxProfitSharingTransactionType.ORDERS); + order.setSubMchid("服务商必填----微信支付分配的子商户号,即分账的出资商户号。"); + order.setSubAppid("服务商必填----微信分配的子商户公众账号ID,分账接收方类型包含PERSONAL_SUB_OPENID时必填。"); + order.setTransactionId("微信支付订单号"); + order.setOutOrderNo("务商系统内部的分账单号,在服务商系统内部唯一,同一分账单号多次请求等同一次。只能是数字、大小写字母_-|*@ "); + List 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 orderInfo = service.orderInfo(order); + orderInfo.put("code", 0); + return orderInfo; + } + + + /** + * 获取支付预订单信息 + * + * @return 支付预订单信息 + */ + @RequestMapping("unfreeze") + public Map 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 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 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 是否成功 + *

+ * 业务处理在对应的PayMessageHandler里面处理,在哪里设置PayMessageHandler,详情查看{@link com.egzosn.pay.common.api.PayService#setPayMessageHandler(com.egzosn.pay.common.api.PayMessageHandler)} + *

+ * 如果未设置 {@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 query() { + AssistOrder assistOrder = new AssistOrder(); + assistOrder.setOutTradeNo("商户分账单号"); + assistOrder.setTradeNo("微信订单号"); + assistOrder.addAttr("sub_mchid", "服务商必填---子商户号"); + return service.query(assistOrder); + } + + + /** + * 查询剩余待分金额 + * + * @return 返回查询回来的结果集,支付方原值返回 + */ + @RequestMapping("amounts") + public Map amounts() { + AssistOrder assistOrder = new AssistOrder(); + assistOrder.setTradeNo("微信订单号"); + return service.query(assistOrder); + } + + + /** + * 查询最大分账比例 + * 服务商使用 + * @return 返回查询回来的结果集,支付方原值返回 + */ + @RequestMapping("merchantConfigs") + public Map 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 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); + } + + +} diff --git a/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/handler/WxV3ProfitSharingMessageHandler.java b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/handler/WxV3ProfitSharingMessageHandler.java new file mode 100644 index 0000000..ad083cc --- /dev/null +++ b/pay-java-demo/src/main/java/com/egzosn/pay/demo/service/handler/WxV3ProfitSharingMessageHandler.java @@ -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 { + + private final Logger LOG = LoggerFactory.getLogger(DefaultPayMessageHandler.class); + + @Override + public PayOutMessage handle(ProfitSharingPayMessage payMessage, Map context, PayService payService) throws PayErrorException { + LOG.info("回调支付消息处理器,回调消息:{}", JSON.toJSONString(payMessage)); + return payService.successPayOutMessage(payMessage); + } +}