From af9e4f70ec671b562a08c01a039c599d37c4352e Mon Sep 17 00:00:00 2001 From: lin <642018748@qq.com> Date: Sun, 14 Aug 2022 13:46:07 +0800 Subject: [PATCH] fix pay v3 --- .../controller/callback/WxPayController.java | 14 ++-- .../com/iformall/domain/po/WxPayOrder.java | 83 ++++++++++++------- .../main/java/com/iformall/pay/WxPayV3.java | 25 +++++- .../service/impl/WxPayOrderServiceImpl.java | 2 +- .../entity/WxComposeChildOrderShare.java | 7 +- .../wx/v3/entity/CombineCloseItemOrder.java | 11 +++ .../pay/wx/v3/entity/CombineCloseReq.java | 39 +++++++++ .../service/pay/wx/v3/entity/PayQueryReq.java | 4 + .../appPay/WxMiniAppPayV3AdapterService.java | 26 +++++- 9 files changed, 165 insertions(+), 46 deletions(-) create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseItemOrder.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseReq.java diff --git a/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java b/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java index b281e43d0..ce38b0ef2 100644 --- a/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java @@ -24,6 +24,8 @@ import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; @@ -117,18 +119,16 @@ public class WxPayController extends BaseController { /** - * 微信支付3.0版本 + * 微信支付3.0版本 + * 普通支付 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_11.shtml + * 合单支付 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_13.shtml * @return 接收微信异步通知 * @throws Exception 可能产生的任何异常 */ @RequestMapping(value = "/pay/v3", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody - public String _payV3Notify(HttpServletRequest request) throws IOException, JDOMException { - logger.info("[" +getIpAddr() + "]微信支付回调"); - SortedMap resultMap = new TreeMap(); - resultMap.put("return_code", "SUCCESS"); - resultMap.put("return_msg", "OK"); - return XmlUtil.getRequestXml(resultMap); + public void _payV3Notify(HttpServletRequest request,HttpServletResponse response) throws IOException, JDOMException { + response.setStatus(200); } /** diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java b/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java index 96e040964..d6ea96d60 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxPayOrder.java @@ -75,33 +75,78 @@ public class WxPayOrder extends TenantEntity { // private String storeId; @io.swagger.annotations.ApiModelProperty(value="子订单分账金额json",name="childOrderShare") private String childOrderShare; + @io.swagger.annotations.ApiModelProperty(value="支付失败原因",name="failReason") + private String failReason; + @io.swagger.annotations.ApiModelProperty(value="支付后结果来源(0:callback, 1:query)",name="payEndFrom") + private Integer payEndFrom; + + @io.swagger.annotations.ApiModelProperty(value="是否为组合订单,1-是 0-不是",name="composeOrder") + private Integer composeOrder; + + @io.swagger.annotations.ApiModelProperty(value="支付后结果来源(0:inside, 1:POS支付)",name="payFrom") + private Integer payFrom; + + @io.swagger.annotations.ApiModelProperty(value="抖音支付实际支付方式--1-微信支付,2-支付宝支付,10-抖音支付",name="ttPayWay") + private Integer ttPayWay; + @io.swagger.annotations.ApiModelProperty(value="支付订单号,来源于POS, inside时,填写couponOrderId",name="posPayOrderId") + private Long posPayOrderId; + @io.swagger.annotations.ApiModelProperty(value="支付订单创建时间,来源于POS",name="posPayOrderTime") + private Long posPayOrderTime; + @io.swagger.annotations.ApiModelProperty(value="支付方式: 0微信;1支付宝;2现金;3会员折扣;4优惠券;5预付卡;6银行卡,来源于POS",name="posPaymentType") + private Integer posPaymentType; + @io.swagger.annotations.ApiModelProperty(value="支付订单流水号, 来源于POS, 第三方(微信、支付宝、富茂预付卡)支付订单流水号,富茂优惠券ID,现金和富茂会员折扣时为空",name="posPayOrderNo") + private String posPayOrderNo; + @io.swagger.annotations.ApiModelProperty(value="POS支付描述",name="posPayDes") + private String posPayDes; public WxComposeChildOrderShare getChildOrderShare(Long wxOrderId) { if (StringUtils.isBlank(this.childOrderShare)) { - return new WxComposeChildOrderShare(this.payAmount, this.shareAmount, this.rateAmount,null,null,null,null); + return new WxComposeChildOrderShare(this.payAmount, this.shareAmount, this.rateAmount,null,null,null,null,null); } Map childs = JSON.parseObject(this.childOrderShare, Map.class); JSONObject childOrderShare = (JSONObject) childs.get(String.valueOf(wxOrderId)); if (null != childOrderShare) { return new WxComposeChildOrderShare(childOrderShare.getInteger("realPayMent"), childOrderShare.getInteger("shareAmount"), childOrderShare.getInteger("rateAmount"), childOrderShare.getInteger("realRateAmount"), childOrderShare.getInteger("commissionAmount"), - childOrderShare.getLong("merchantId"),childOrderShare.getString("merchantUid")); + childOrderShare.getLong("merchantId"),childOrderShare.getString("merchantUid"),childOrderShare.getLong("orderId")); } return null; } - public WxComposeChildOrderShare getSingleChildOrderShare() { + private List getAllChilds(Integer index) { if (StringUtils.isBlank(this.childOrderShare)) { - return new WxComposeChildOrderShare(this.payAmount, this.shareAmount, this.rateAmount,null,null,null,null); + return null; } Map childs = JSON.parseObject(this.childOrderShare, Map.class); + List childList = new ArrayList(); + int _index = 0; for (Iterator it = childs.keySet().iterator();it.hasNext();) { JSONObject childOrderShare = (JSONObject) childs.get(it.hasNext()); - return new WxComposeChildOrderShare(childOrderShare.getInteger("realPayMent"), childOrderShare.getInteger("shareAmount"), childOrderShare.getInteger("rateAmount"), + WxComposeChildOrderShare child = new WxComposeChildOrderShare(childOrderShare.getInteger("realPayMent"), childOrderShare.getInteger("shareAmount"), childOrderShare.getInteger("rateAmount"), childOrderShare.getInteger("realRateAmount"), childOrderShare.getInteger("commissionAmount"), - childOrderShare.getLong("merchantId"),childOrderShare.getString("merchantUid")); + childOrderShare.getLong("merchantId"),childOrderShare.getString("merchantUid"),childOrderShare.getLong("orderId")); + childList.add(child); + if (null != index && index.intValue() == _index) { + return childList; + } + _index ++; } - return null; + if (childList.size() <= 0 ) { + return null; + } + return childList; + } + + public WxComposeChildOrderShare getSingleChildOrderShare() { + List childs = getAllChilds(0); + if (null == childs) { + return null; + } + return childs.get(0); + } + + public List getAllChilds() { + return getAllChilds(null); } public boolean isMulity() { @@ -115,30 +160,6 @@ public class WxPayOrder extends TenantEntity { } return false; } - - @io.swagger.annotations.ApiModelProperty(value="支付失败原因",name="failReason") - private String failReason; - @io.swagger.annotations.ApiModelProperty(value="支付后结果来源(0:callback, 1:query)",name="payEndFrom") - private Integer payEndFrom; - - @io.swagger.annotations.ApiModelProperty(value="是否为组合订单,1-是 0-不是",name="composeOrder") - private Integer composeOrder; - - @io.swagger.annotations.ApiModelProperty(value="支付后结果来源(0:inside, 1:POS支付)",name="payFrom") - private Integer payFrom; - - @io.swagger.annotations.ApiModelProperty(value="抖音支付实际支付方式--1-微信支付,2-支付宝支付,10-抖音支付",name="ttPayWay") - private Integer ttPayWay; - @io.swagger.annotations.ApiModelProperty(value="支付订单号,来源于POS, inside时,填写couponOrderId",name="posPayOrderId") - private Long posPayOrderId; - @io.swagger.annotations.ApiModelProperty(value="支付订单创建时间,来源于POS",name="posPayOrderTime") - private Long posPayOrderTime; - @io.swagger.annotations.ApiModelProperty(value="支付方式: 0微信;1支付宝;2现金;3会员折扣;4优惠券;5预付卡;6银行卡,来源于POS",name="posPaymentType") - private Integer posPaymentType; - @io.swagger.annotations.ApiModelProperty(value="支付订单流水号, 来源于POS, 第三方(微信、支付宝、富茂预付卡)支付订单流水号,富茂优惠券ID,现金和富茂会员折扣时为空",name="posPayOrderNo") - private String posPayOrderNo; - @io.swagger.annotations.ApiModelProperty(value="POS支付描述",name="posPayDes") - private String posPayDes; } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java index f5469b966..0e8f3e634 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java @@ -10,6 +10,7 @@ import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.iformall.service.pay.service.pay.wx.v3.entity.CombineCloseReq; import com.iformall.service.pay.service.pay.wx.v3.entity.CombinePayCommonMiniAppReq; import com.iformall.service.pay.service.pay.wx.v3.entity.PayCommonMiniAppReq; import com.iformall.service.pay.service.pay.wx.v3.entity.PayQueryReq; @@ -28,11 +29,14 @@ public class WxPayV3 { private static final String PAY_COMMON_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi"; //电商收付通-普通支付-查询 private static final String PAY_COMMON_QUERY_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s"; - //电商收付通-普合单支付-小程序下单 + //电商收付通-合单支付-小程序下单 private static final String PAY_COMBINE_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi"; //电商收付通-合单支付-查询 private static final String PAY_COMBINE_QUERY_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/%s"; - + //电商收付通-普通支付-关闭订单 + private static final String PAY_COMMON_CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/out-trade-no/%s/close"; + //电商收付通-合单支付-关闭订单 + private static final String PAY_COMBINE_CLOSE_ORDER_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/out-trade-no/%s/close"; private WxPayV3() { } @@ -114,4 +118,21 @@ public class WxPayV3 { } + /** + * 电商收付通-普通支付-关闭 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_11.shtml + * @throws WxPayException + */ + public static String payCommonClose(WxPayService payService,PayQueryReq payQuery) throws WxPayException { + return payService.postV3WithWechatpaySerial(String.format(PAY_COMMON_CLOSE_ORDER_URL, payQuery.getOut_trade_no()), JSON.toJSONString(payQuery)); + + } + + /** + * 电商收付通-合单支付-关闭 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_12.shtml + * @throws WxPayException + */ + public static String payCombineClose(WxPayService payService,CombineCloseReq closeOrder) throws WxPayException { + return payService.postV3WithWechatpaySerial(String.format(PAY_COMBINE_CLOSE_ORDER_URL, closeOrder.getCombine_out_trade_no()), JSON.toJSONString(closeOrder)); + } + } diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java index 09a0d41bc..fc2798c59 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxPayOrderServiceImpl.java @@ -466,7 +466,7 @@ public class WxPayOrderServiceImpl implements WxPayOrderService { logger.info("佣金明细"+ JSON.toJSONString(oShareAmount)); share_amount += oShareAmount.getShareAmount(); rate_amount += oShareAmount.getRateAmount(); - childShares.put(String.valueOf(o.getId()), new WxComposeChildOrderShare(oShareAmount,merchant_id,merchant_uid)); + childShares.put(String.valueOf(o.getId()), new WxComposeChildOrderShare(oShareAmount,merchant_id,merchant_uid,o.getId())); } record.setShareAmount(share_amount); record.setRateAmount(rate_amount); diff --git a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeChildOrderShare.java b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeChildOrderShare.java index bd64577e7..eee36cb6e 100644 --- a/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeChildOrderShare.java +++ b/mallinkService/src/main/java/com/iformall/service/order/entity/WxComposeChildOrderShare.java @@ -12,7 +12,7 @@ import lombok.Data; public class WxComposeChildOrderShare { public WxComposeChildOrderShare(Integer realPayMent,Integer shareAmount,Integer rateAmount,Integer realRateAmount,Integer commissionAmount, - Long merchantId,String merchantUid) { + Long merchantId,String merchantUid,Long orderId) { this.realPayMent = realPayMent; this.shareAmount = shareAmount; this.rateAmount = rateAmount; @@ -20,9 +20,10 @@ public class WxComposeChildOrderShare { this.commissionAmount = commissionAmount; this.merchantId = merchantId; this.merchantUid = merchantUid; + this.orderId = orderId; } - public WxComposeChildOrderShare(PayShareCalculateAmount shareCalculateAmount,Long merchantId,String merchantUid) { + public WxComposeChildOrderShare(PayShareCalculateAmount shareCalculateAmount,Long merchantId,String merchantUid,Long orderId) { this.realPayMent = shareCalculateAmount.getPayAmount(); this.shareAmount = shareCalculateAmount.getShareAmount(); this.rateAmount = shareCalculateAmount.getRateAmount(); @@ -30,8 +31,10 @@ public class WxComposeChildOrderShare { this.commissionAmount = shareCalculateAmount.getCommissionAmount(); this.merchantId = merchantId; this.merchantUid = merchantUid; + this.orderId = orderId; } + private Long orderId;//订单编号,v3要用 private Integer realPayMent;//付款金额 private Integer shareAmount;//分账的钱(分给商户的) diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseItemOrder.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseItemOrder.java new file mode 100644 index 000000000..34fc646df --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseItemOrder.java @@ -0,0 +1,11 @@ +package com.iformall.service.pay.service.pay.wx.v3.entity; + +import lombok.Data; + +@Data +public class CombineCloseItemOrder { + + private String mchid;//子单发起方商户号,必须与发起方appid有绑定关系 + private String out_trade_no;//子单商户订单号 + private String sub_mchid;//二级商户号,服务商子商户的商户号,被合单方。直连商户不用传二级商户号 +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseReq.java new file mode 100644 index 000000000..9791e293e --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/CombineCloseReq.java @@ -0,0 +1,39 @@ +package com.iformall.service.pay.service.pay.wx.v3.entity; + +import java.util.ArrayList; +import java.util.List; +import com.alibaba.fastjson.annotation.JSONField; +import com.iformall.domain.po.WxPayAccount; +import com.iformall.domain.po.WxPayOrder; +import com.iformall.service.order.entity.WxComposeChildOrderShare; +import lombok.Data; + +@Data +public class CombineCloseReq { + + private String combine_appid;//合单发起方的appid + + @JSONField(serialize = false) + private String combine_out_trade_no;//不放到body + + private List sub_orders; + + public void initSubOrders(WxPayAccount payAccount,WxPayOrder payOrder) { + List childs = payOrder.getAllChilds(); + if (null != childs) { + List suborders = new ArrayList(); + for (WxComposeChildOrderShare child : childs) { + CombineCloseItemOrder ccio = new CombineCloseItemOrder(); + ccio.setMchid(payAccount.getMchId()); + ccio.setSub_mchid(child.getMerchantUid()); + ccio.setOut_trade_no(String.valueOf(child.getOrderId())); + suborders.add(ccio); + } + if (suborders.size() > 0) { + this.setSub_orders(suborders); + } + } + } + + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/PayQueryReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/PayQueryReq.java index 18e5bd455..628250d5d 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/PayQueryReq.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/entity/PayQueryReq.java @@ -1,5 +1,7 @@ package com.iformall.service.pay.service.pay.wx.v3.entity; +import com.alibaba.fastjson.annotation.JSONField; + import lombok.Data; @Data @@ -7,6 +9,8 @@ public class PayQueryReq { private String sp_mchid;//服务商户号。 private String sub_mchid;//二级商户号 + + @JSONField(serialize = false) private String out_trade_no;//商户订单号 } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java index 3d3ba5599..c7d9f1bfe 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java @@ -38,6 +38,7 @@ import com.iformall.service.pay.service.pay.CDrivingPayService; import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; +import com.iformall.service.pay.service.pay.wx.v3.entity.CombineCloseReq; import com.iformall.service.pay.service.pay.wx.v3.entity.CombineItemOrder; import com.iformall.service.pay.service.pay.wx.v3.entity.CombinePayCommonMiniAppReq; import com.iformall.service.pay.service.pay.wx.v3.entity.CombinePayerReq; @@ -200,8 +201,10 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ private PayQueryAdapterResult getPayCombineQueryResult(String response) { JSONObject result = JSON.parseObject(response); - //只有各子订单的状态,没有统一的状态,暂时无法处理 + //TODO 只有各子订单的状态,没有统一的状态,暂时无法处理 JSONArray subOrders = result.getJSONArray("sub_orders"); + + ///######待处理 String transtionId = result.getString("transaction_id"); String tradeState = result.getString("trade_state"); String tradeStateDesc = result.getString("trade_state_desc"); @@ -254,8 +257,25 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ @Override public PayAdapterResult payOrderClose(WxAppinfo appInfo, WxPayOrder record,WxPayAccount payAccount) throws Exception { - //return super.closeOrder(appInfo, record, payAccount); - return null; + WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); + if (!record.isMulity()) { + PayQueryReq req = new PayQueryReq(); + req.setSp_mchid(payAccount.getMchId()); + req.setSub_mchid(record.getSingleChildOrderShare().getMerchantUid()); + req.setOut_trade_no(String.valueOf(record.getId())); + WxPayV3.payCommonClose(payService, req); + return new PayAdapterResult(true, "close success", req, null); + }else { + throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"因电商收付通合单查询无法处理,暂时不支持合单支付关闭"); + +// CombineCloseReq req = new CombineCloseReq(); +// req.setCombine_appid(appInfo.getAppId()); +// req.setCombine_out_trade_no(String.valueOf(record.getId())); +// req.initSubOrders(payAccount, record); +// +// String response = WxPayV3.payCombineClose(payService, req); +// return new PayAdapterResult(true, "close success", req, null); + } } @Override