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 ce38b0ef2..e4f11512c 100644 --- a/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java +++ b/mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java @@ -19,6 +19,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; +import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.RestController; @@ -125,9 +126,9 @@ public class WxPayController extends BaseController { * @return 接收微信异步通知 * @throws Exception 可能产生的任何异常 */ - @RequestMapping(value = "/pay/v3", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) + @RequestMapping(value = "/pay/v3/{tenantId}", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @ResponseBody - public void _payV3Notify(HttpServletRequest request,HttpServletResponse response) throws IOException, JDOMException { + public void _payV3Notify(@PathVariable String tenantId,HttpServletRequest request,HttpServletResponse response) throws IOException, JDOMException { response.setStatus(200); } @@ -186,8 +187,8 @@ public class WxPayController extends BaseController { * @return 接收微信退款异步通知 * @throws Exception 可能产生的任何异常 */ - @RequestMapping(value = "/refund/v3") - public String __refundV3Notify(HttpServletRequest request) throws Exception { + @RequestMapping(value = "/refund/v3/{tenantId}") + public String __refundV3Notify(@PathVariable String tenantId,HttpServletRequest request) throws Exception { logger.info("[" +getIpAddr() + "]微信退款回调"); Map paramMap = null; String response = ""; @@ -275,8 +276,8 @@ public class WxPayController extends BaseController { * @return 接收微信分账异步通知 * @throws Exception 可能产生的任何异常 */ - @RequestMapping(value = "/sharing/v3") - public String __shareV3Notify(HttpServletRequest request) throws Exception { + @RequestMapping(value = "/sharing/v3/{tenantId}") + public String __shareV3Notify(@PathVariable String tenantId,HttpServletRequest request) throws Exception { logger.info("[" +getIpAddr() + "]微信分账回调"); Map paramMap = null; String response = ""; @@ -284,8 +285,9 @@ public class WxPayController extends BaseController { try { xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8")); paramMap = WxPayment.xmlToMap(xml); + paramMap.put("tenantId", tenantId); logger.info("share wxpay, notify, param: " + xml ); - response = wxPayOrderService.shareNotify(paramMap, EnumPayWay.PAY_WAY_WECHAT,EnumPayVersion.WX_PAY_V2); + response = wxPayOrderService.shareNotify(paramMap, EnumPayWay.PAY_WAY_WECHAT,EnumPayVersion.WX_PAY_V3); logger.info("share wxpay, notify success, req : " + xml + ", resp: " + response.toString()); return response; } catch (BizMessageException e) { diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java index a4f722592..25d7f7da2 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxProfitSharingOrderServiceImpl.java @@ -26,6 +26,7 @@ import com.iformall.service.WxProfitSharingOrderService; import com.iformall.service.pay.PayServiceFactory; import com.iformall.service.pay.service.share.PayShareAdapterService; import com.iformall.service.pay.service.share.entity.PayShareQueryResult; +import com.iformall.service.pay.service.share.entity.PayShareQueryResultReceivers; import com.iformall.service.pay.service.share.entity.PayShareResult; import com.iformall.utils.BeanUtils; import com.iformall.utils.DateUtils; @@ -359,23 +360,20 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ return new ResultData(shareResult.getData()); } - String receivers = shareResult.getReceivers(); + List receivers = shareResult.getReceivers(); if (receivers != null) { - JSONArray jReceivers = JSONArray.parseArray(receivers); - WxProfitSharingResult result = new WxProfitSharingResult(); result.setSharingOrderId(record.getId()); result.updateTenantInfo(wxProfitSharingOrder); List wxProfitSharingResultList = wxProfitSharingResultMapper.findList(result); - - for(int j = 0; j < jReceivers.size() ; j++) { - JSONObject res = (JSONObject) jReceivers.get(j); + for(int j = 0; j < receivers.size() ; j++) { + PayShareQueryResultReceivers res = receivers.get(j); JSONObject des = new JSONObject(); - des.put("type", res.getString("type")); - des.put("account", res.getString("account")); - des.put("description", res.getString("description")); - des.put("amount", res.getString("amount")); + des.put("type", res.getType()); + des.put("account", res.getAccount()); + des.put("description", res.getDescription()); + des.put("amount", res.getAmount()); int i = 0; for (i = 0; i < wxProfitSharingResultList.size(); i++) { @@ -383,12 +381,12 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ WxProfitSharingReceiver wxProfitSharingReceiver = wxProfitSharingReceiverMapper.selectById(wxProfitSharingResult.getSharingReceiverId()); if (wxProfitSharingReceiver == null) continue; - if (res.getString("type").equals(EnumProfitSharingReceiverType.getEnum(wxProfitSharingReceiver.getReceiverType()).getMessage()) - && res.getString("account").equals(wxProfitSharingReceiver.getReceiverAccount())) { - wxProfitSharingResult.setFinishTime(res.getString("finish_time")); + if (res.getType().equals(EnumProfitSharingReceiverType.getEnum(wxProfitSharingReceiver.getReceiverType()).getMessage()) + && res.getAccount().equals(wxProfitSharingReceiver.getReceiverAccount())) { + wxProfitSharingResult.setFinishTime(res.getFinish_time()); wxProfitSharingResult.setUpdateTime(new Date()); - wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getString("result"))); - wxProfitSharingResult.setFailedReason(res.getString("fail_reason")); + wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getResult())); + wxProfitSharingResult.setFailedReason(res.getFail_reason()); wxProfitSharingResult.setDescription(des.toJSONString()); wxProfitSharingResultMapper.updateById(wxProfitSharingResult); break; @@ -408,10 +406,10 @@ public class WxProfitSharingOrderServiceImpl implements WxProfitSharingOrderServ wxProfitSharingResult = list.get(0); } - wxProfitSharingResult.setPayAmount(Integer.valueOf(res.getString("amount"))); - wxProfitSharingResult.setFinishTime(res.getString("finish_time")); - wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getString("result"))); - wxProfitSharingResult.setFailedReason(res.getString("fail_reason")); + wxProfitSharingResult.setPayAmount(Integer.valueOf(res.getAmount())); + wxProfitSharingResult.setFinishTime(res.getFinish_time()); + wxProfitSharingResult.setSharingStatus(resultStatusMap.getIntValue(res.getResult())); + wxProfitSharingResult.setFailedReason(res.getFail_reason()); wxProfitSharingResult.setDescription(des.toJSONString()); if (wxProfitSharingResult.getId() != null) { wxProfitSharingResult.setUpdateTime(new Date()); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareBaseAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareBaseAdapterService.java index 9053b492d..11d54f858 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareBaseAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/PayShareBaseAdapterService.java @@ -1,14 +1,15 @@ package com.iformall.service.pay.service.share; import java.util.List; - import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; +import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.iformall.common.ErrorCode; import com.iformall.domain.dto.WxSharingOrderDto; import com.iformall.domain.po.WxProfitSharingReceiver; import com.iformall.enums.EnumProfitSharingReceiverType; import com.iformall.exception.MallinkException; +import com.iformall.service.pay.service.share.entity.PayShareQueryResultReceivers; public abstract class PayShareBaseAdapterService implements PayShareAdapterService{ @Override @@ -16,6 +17,13 @@ public abstract class PayShareBaseAdapterService implements PayShareAdapterServi return EnumProfitSharingReceiverType.getEnum(accountType); } + protected List getReceivers(String response) { + if (StringUtils.isBlank(response)) { + return null; + } + return JSONArray.parseArray(response,PayShareQueryResultReceivers.class); + } + protected String calReceiversAmount(WxSharingOrderDto sharingOrderDto,List psReceiverList) { if (psReceiverList != null && psReceiverList.size() > 50) { throw new MallinkException(ErrorCode.PROFIT_SHARING_RECEIVER_INVALID); diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResult.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResult.java index 878cbc1f9..ae72704d0 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResult.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResult.java @@ -1,6 +1,7 @@ package com.iformall.service.pay.service.share.entity; import java.io.Serializable; +import java.util.List; import lombok.AllArgsConstructor; import lombok.Data; @@ -15,7 +16,7 @@ public class PayShareQueryResult implements Serializable{ private Integer code; private String msg; private Object data; - private String receivers;//数组字符串,平台查询返回的分账账户列表 + private List receivers;//数组字符串,平台查询返回的分账账户列表 diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResultReceivers.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResultReceivers.java new file mode 100644 index 000000000..7ecbf4e39 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/entity/PayShareQueryResultReceivers.java @@ -0,0 +1,33 @@ +package com.iformall.service.pay.service.share.entity; + +import java.io.Serializable; + +import lombok.AllArgsConstructor; +import lombok.Data; + +@Data +public class PayShareQueryResultReceivers implements Serializable{ + + private static final long serialVersionUID = -3701322871877301001L; + + private int amount; + private String description; + private String type;//1、MERCHANT_ID:商户号 2、PERSONAL_OPENID:个人openid(由父商户APPID转换得到)3、PERSONAL_SUB_OPENID: 个人sub_openid(由子商户APPID转换得到) + private String account;//分账接收方账号 + private String result;//分账结果 + private String detail_id;//分账明细单号 + /** + * 枚举值: + 1、ACCOUNT_ABNORMAL:分账接收账户异常 + 2、NO_RELATION:分账关系已解除 + 3、RECEIVER_HIGH_RISK:高风险接收方 + 4、RECEIVER_REAL_NAME_NOT_VERIFIED:接收方未实名 + 5、NO_AUTH:分账权限已解除 + 6、RECEIVER_RECEIPT_LIMIT:接收方已达收款限额 + 7、PAYER_ACCOUNT_ABNORMAL:分出方账户异常 + 8、INVALID_REQUEST: 描述参数设置失败 + */ + private String fail_reason;//分账失败原因.当分账结果result为CLOSED(已关闭)时,返回该字段 + private String create_time;//分账创建时间 + private String finish_time;//分账完成时间 +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v2/WxPayShareService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v2/WxPayShareService.java index 071010d05..9cae6b194 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v2/WxPayShareService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v2/WxPayShareService.java @@ -205,7 +205,7 @@ public class WxPayShareService extends PayShareBaseAdapterService{ } Integer code = (Integer) statusMap.get(returnMap.get("status")); - return new PayShareQueryResult(true, code, "success",returnMap, returnMap.get("receivers")); + return new PayShareQueryResult(true, code, "success",returnMap, getReceivers(returnMap.get("receivers"))); } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v3/WxPayShareV3Service.java b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v3/WxPayShareV3Service.java index 5e85d0e85..1b7eae812 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v3/WxPayShareV3Service.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/share/wx/v3/WxPayShareV3Service.java @@ -1,5 +1,8 @@ package com.iformall.service.pay.service.share.wx.v3; +import java.io.IOException; +import java.security.GeneralSecurityException; +import java.text.ParseException; import java.util.*; import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; import com.github.binarywang.wxpay.exception.WxPayException; @@ -23,6 +26,7 @@ import com.iformall.exception.MallinkException; import com.iformall.pay.WxPayV3; import com.iformall.pay.WxPayment; import com.iformall.pay.WxProfitSharing; +import com.iformall.service.WxPayAccountService; import com.iformall.service.WxProfitSharingReceiverService; import com.iformall.service.order.util.OrderHelper; import com.iformall.service.pay.service.share.PayShareBaseAdapterService; @@ -36,6 +40,7 @@ import com.iformall.service.pay.service.share.wx.v3.entity.V3PayShareReq; import com.iformall.service.pay.service.share.wx.v3.entity.V3PayShareUnfreezeReq; import com.iformall.utils.BeanUtils; import com.iformall.utils.MaUtil; +import com.iformall.utils.Utility; import com.iformall.utils.XmlUtil; import lombok.extern.slf4j.Slf4j; @@ -53,6 +58,10 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ @Autowired MaUtil maUtil; + + @Lazy + @Autowired + WxPayAccountService wxPayAccountService; @Override public Integer getSubsidyType() { @@ -137,7 +146,7 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ req.setSub_mchid(payAccount.getSubMchId()); } req.setTransaction_id(transcationId); - req.setOut_order_no(String.valueOf(record.getId())); + req.setOut_order_no(String.valueOf(record.getOrderId())); req.setDescription(appInfo.getName()+"支付订单:"+record.getOrderId()); WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); @@ -169,7 +178,7 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ req.setAppid(appInfo.getParentAppId()); req.setSub_appid(appInfo.getAppId()); req.setTransaction_id(transcationId); - req.setOut_order_no(String.valueOf(record.getId())); + req.setOut_order_no(String.valueOf(record.getOrderId())); req.setReceivers(receivers); WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); String response = null; @@ -199,7 +208,7 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ req.setSub_mchid(payAccount.getSubMchId()); } req.setTransaction_id(record.getTransactionId()); - req.setOut_order_no(String.valueOf(record.getId())); + req.setOut_order_no(String.valueOf(record.getOrderId())); WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); String response = null; try { @@ -220,8 +229,7 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ if (StringUtils.isBlank(out_order_no) || !out_order_no.equals(record.getId().toString())){ throw new MallinkException(ErrorCode.PROFIT_SHARING_QUERY_RETURN_INVALID.getCode(),"out_order_no:["+out_order_no+"] WxProfitSharingOrder:["+record.getId()+"]"); } - 111111111111111 - return new PayShareQueryResult(true, 200, "success",result, JSON.toJSONString(result.get("receivers"))); + return new PayShareQueryResult(true, 200, "success",result, this.getReceivers(JSON.toJSONString(result.get("receivers")))); } @@ -248,9 +256,57 @@ public class WxPayShareV3Service extends PayShareBaseAdapterService{ @Override public ShareNotifyAdapterResult notify(Map paramMap,EnumPayWay payWay) { - + String tenantId = paramMap.get("tenantId"); + String resource = paramMap.get("resource"); + JSONObject reObj = JSON.parseObject(resource); + WxPayService wxPayService = wxPayAccountService.getWxPayService(tenantId); + try { + String decryptContent = WxPayV3.decrypt(wxPayService, reObj.getString("ciphertext"), reObj.getString("nonce"), reObj.getString("associated_data")); + JSONObject decryptObj = JSON.parseObject(decryptContent); + String spMchId = decryptObj.getString("sp_mchid"); + String subMchId = decryptObj.getString("sub_mchid"); + String transactionId = decryptObj.getString("transaction_id"); + String orderId = decryptObj.getString("order_id"); + String outOrderNo = decryptObj.getString("out_order_no"); + String successTime = decryptObj.getString("success_time"); + JSONObject rObj = decryptObj.getJSONObject("receiver"); + String type = rObj.getString("type"); + String account = rObj.getString("account"); + int amount = rObj.getIntValue("amount"); + String description = rObj.getString("description"); + + Long payOrderId = Long.valueOf(outOrderNo); + WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,tenantId); + if (payOrder == null) { + log.warn("notify order, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return getErrorResult("订单不存在"); + } + // 验证支付金额 + if (!paramMap.get("total_fee").equals(payOrder.getPayAmount().toString())) { + log.warn("notify order, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return getErrorResult("订单总金额不一致"); + } + + Date timeEnd = null; - return getErrorResult("FAILED"); + try { + timeEnd = Utility.getDateFromString(successTime); + } catch (ParseException e) { + log.error("解析timeEnd失败"); + timeEnd = new Date(); + } + payOrder.setPayTimeEnd(timeEnd); + + log.info("notify order, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString()); + return getSuccessResult(payOrder, transactionId); + + } catch (GeneralSecurityException e1) { + log.error("pay v3 share nofify error.",e1); + throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"分账通知错误"+e1.getMessage()); + } catch (IOException e1) { + log.error("pay v3 share nofify error.",e1); + throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"分账通知错误"+e1.getMessage()); + } } @Override