From 0ed88a700cfa5a052a5c284005dc0797c4aeb130 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Mon, 1 Aug 2022 17:22:40 +0800 Subject: [PATCH 01/16] fix rent --- .../java/com/iformall/config/ShiroConfig.java | 2 +- .../controller/base/BaseController.java | 10 +++++++-- .../src/main/java/com/iformall/pay/WxPay.java | 22 ++++++++++++++++--- .../impl/WxRentContractServiceImpl.java | 2 +- .../cashout/wx/WxCashOutAdapterService.java | 2 +- 5 files changed, 30 insertions(+), 8 deletions(-) diff --git a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java index a56a0e016..f31510822 100644 --- a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java +++ b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java @@ -162,7 +162,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/logout", "authc"); filterChainDefinitionMap.put("/**", "corsFilter,token,authc"); -// filterChainDefinitionMap.put("/**", "anon"); + filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java index b74a94c86..3bb15abb9 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java @@ -45,12 +45,18 @@ public class BaseController { }); } public MallUserInfo getUser(){ - MallUserInfo user = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); + //MallUserInfo user = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); + MallUserInfo user = new MallUserInfo(); + user.setId(463627091581734912L); + user.setName("富茂光谷测试版管理员"); + user.setTenantId("1025"); + user.setParentTenantId("1024"); return user; } public Long getUserId(){ - Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId); + //Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId); + Long userId = 463627091581734912L; return userId; } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index 7f58d9256..ae341abe5 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -36,6 +36,8 @@ public class WxPay { private static final String TRANSFERS_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers"; // 查询企业付款 private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; + //商家转账到零钱 + private static final String MERCHANT_TRANSFER_CHANGE_URL = "https://api.mch.weixin.qq.com/v3/transfer/batches"; // 查询代金券批次 private static final String GETCOUPONSTOCK_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock"; @@ -211,8 +213,8 @@ public class WxPay { } /** - * 企业付款 - * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 + *企业付款到零钱:https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2, + *微信后来改为 商家转账到零钱 产品 * @param params * 请求参数 * @param certPath @@ -224,7 +226,7 @@ public class WxPay { public static String transfers(Map params, String certPath, String certPassword) { return WxPay.doPostSSL(TRANSFERS_URL, params, certPath, certPassword); } - + /** * 查询企业付款 * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_3 @@ -239,6 +241,20 @@ public class WxPay { public static String getTransferInfo(Map params, String certPath, String certPassword) { return WxPay.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword); } + + /** + * 商家转账到零钱 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter4_3_1.shtml + * @param params + * 请求参数 + * @param certPath + * 证书文件目录 + * @param certPassword + * 证书密码 + * @return {String} + */ + public static String merchantTranferChange(Map params, String certPath, String certPassword) { + return WxPay.doPostSSL(MERCHANT_TRANSFER_CHANGE_URL, params, certPath, certPassword); + } /** * 商户模式下 扫码模式一之生成二维码 diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 7e9f82f14..7a7a9e8de 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java @@ -1223,7 +1223,7 @@ public class WxRentContractServiceImpl implements WxRentContractService { JSONObject jsonObject = array.getJSONObject(i); String perMonthMoney = jsonObject.getString("perMonthMoney"); if(StringUtils.isNotBlank(perMonthMoney) && !"0".equals(perMonthMoney)){ - BigDecimal priceD = new BigDecimal(perMonthMoney).multiply(new BigDecimal(12)).divide(new BigDecimal(100)); + BigDecimal priceD = new BigDecimal(perMonthMoney).divide(new BigDecimal(100)); priceArrs[i] = priceD.setScale(0, RoundingMode.HALF_EVEN).longValue(); }else{ priceArrs[i] = 0; diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index 23d92f324..77faa2430 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -213,7 +213,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ signMap.put("sign", signAgent); String response = null; try { - response = WxPay.transfers(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); + response = WxPay.merchantTranferChange(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); } catch (Exception e) { log.error("零钱支付异常: " + e.getMessage(),e); return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); From 63f39a55e88d9a0406395226999f0011f823cd82 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Mon, 1 Aug 2022 18:11:39 +0800 Subject: [PATCH 02/16] fix cashout --- .../java/com/iformall/config/ShiroConfig.java | 2 +- .../controller/base/BaseController.java | 16 ++-- .../java/com/iformall/pay/WxCashOutPV3.java | 20 +++++ .../com/iformall/pay/WxCashOutPV3Item.java | 15 ++++ .../src/main/java/com/iformall/pay/WxPay.java | 7 +- .../cashout/wx/WxCashOutAdapterService.java | 78 +++++++++++++++---- 6 files changed, 110 insertions(+), 28 deletions(-) create mode 100644 mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java create mode 100644 mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java diff --git a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java index f31510822..a56a0e016 100644 --- a/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java +++ b/mallinkAdmin/src/main/java/com/iformall/config/ShiroConfig.java @@ -162,7 +162,7 @@ public class ShiroConfig { filterChainDefinitionMap.put("/logout", "authc"); filterChainDefinitionMap.put("/**", "corsFilter,token,authc"); - filterChainDefinitionMap.put("/**", "anon"); +// filterChainDefinitionMap.put("/**", "anon"); shiroFilterFactoryBean.setFilterChainDefinitionMap(filterChainDefinitionMap); diff --git a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java index 3bb15abb9..a303f45ff 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java @@ -45,18 +45,18 @@ public class BaseController { }); } public MallUserInfo getUser(){ - //MallUserInfo user = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); - MallUserInfo user = new MallUserInfo(); - user.setId(463627091581734912L); - user.setName("富茂光谷测试版管理员"); - user.setTenantId("1025"); - user.setParentTenantId("1024"); + MallUserInfo user = (MallUserInfo) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userInfo); +// MallUserInfo user = new MallUserInfo(); +// user.setId(463627091581734912L); +// user.setName("富茂光谷测试版管理员"); +// user.setTenantId("1025"); +// user.setParentTenantId("1024"); return user; } public Long getUserId(){ - //Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId); - Long userId = 463627091581734912L; + Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId); +// Long userId = 463627091581734912L; return userId; } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java new file mode 100644 index 000000000..16eb68f10 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java @@ -0,0 +1,20 @@ +package com.iformall.pay; + +import java.util.List; + +import lombok.Data; + +/** + * Created by Stormeye on 2018/8/10. + */ +@Data +public class WxCashOutPV3 { + private String appid; // 直连商户的appid,商户号绑定的appid + private String out_batch_no; // 商家批次单号 + private String batch_name; // 批次名称 + private String batch_remark; // 批次备注 + private String total_amount; // 转账总金额 + private String total_num; // 转账总笔数 + private List transfer_detail_list; // 转账明细列表,最多三千笔 + +} diff --git a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java new file mode 100644 index 000000000..6919ba5ec --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java @@ -0,0 +1,15 @@ +package com.iformall.pay; + +import lombok.Data; + +/** + * Created by Stormeye on 2018/8/10. + */ +@Data +public class WxCashOutPV3Item { + private String out_detail_no; // 商家明细单号 + private String transfer_amount; // 转账金额 + private String transfer_remark; // 转账备注 + private String openid; // 用户在直连商户应用下的用户标示 + private String user_name; // 收款用户姓名,明细转账金额 >= 2,000,收款用户姓名必填, 该字段需进行加密处理 +} diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index ae341abe5..d408c4044 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -3,6 +3,8 @@ package com.iformall.pay; import java.util.HashMap; import java.util.Map; +import com.github.binarywang.wxpay.exception.WxPayException; +import com.github.binarywang.wxpay.service.WxPayService; import com.iformall.utils.HttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -251,9 +253,10 @@ public class WxPay { * @param certPassword * 证书密码 * @return {String} + * @throws WxPayException */ - public static String merchantTranferChange(Map params, String certPath, String certPassword) { - return WxPay.doPostSSL(MERCHANT_TRANSFER_CHANGE_URL, params, certPath, certPassword); + public static String merchantTranferChange(WxPayService payService,String body) throws WxPayException { + return payService.postV3WithWechatpaySerial(MERCHANT_TRANSFER_CHANGE_URL, body); } /** diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index 77faa2430..d09fb52f6 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -11,6 +11,7 @@ import org.springframework.stereotype.Service; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; +import com.github.binarywang.wxpay.service.WxPayService; import com.iformall.common.ErrorCode; import com.iformall.common.Result; import com.iformall.common.ResultData; @@ -19,6 +20,8 @@ import com.iformall.domain.po.WxCashOut; import com.iformall.domain.po.WxPayAccount; import com.iformall.domain.po.WxPayOrder; import com.iformall.domain.po.WxRefundOrder; +import com.iformall.domain.po.base.TenantEntity; +import com.iformall.enums.EnumAppPlat; import com.iformall.enums.EnumCashOutStatus; import com.iformall.enums.EnumPayMode; import com.iformall.enums.EnumPayType; @@ -35,6 +38,7 @@ import com.iformall.pay.WxPay; import com.iformall.pay.WxPayment; import com.iformall.pay.WxRefundOrderP; import com.iformall.pay.WxRefundOrderSP; +import com.iformall.service.WxAppinfoService; import com.iformall.service.pay.service.cashout.CashOutAdapterService; import com.iformall.service.pay.service.cashout.entity.CashOutAdapterResult; import com.iformall.service.pay.service.refund.RefundPayAdapterService; @@ -42,6 +46,7 @@ import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; import com.iformall.utils.BeanUtils; import com.iformall.utils.CipherUtil; +import com.iformall.utils.MaUtil; import com.iformall.utils.Utility; import com.iformall.utils.XmlUtil; @@ -50,6 +55,12 @@ import lombok.extern.slf4j.Slf4j; @Slf4j @Service public class WxCashOutAdapterService implements CashOutAdapterService{ + + @Autowired + WxAppinfoService wxAppinfoService; + + @Autowired + MaUtil maUtil; JSONObject errorRefundReqMap = JSON.parseObject("{\n" + " \"NO_AUTH\": {\n" + @@ -187,11 +198,6 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ " }\n" + "}"); - /** - * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 - * - * 在wx_pay_account里面要设置merchant_cert_path,登陆特约商户的商户后台,账号中心-API安全。 - */ @Override public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { @@ -200,25 +206,23 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ if (StringUtils.isBlank(payAccount.getMerchantApiKey())) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); } - WxCashOutP wxCashOutP = generateWxCashOutP(payAccount, appInfo, cashOut); - Map signMap = null; - try { - signMap = BeanUtils.toStringMap(wxCashOutP); - } catch (Exception e) { - log.error("零钱支付命令生辰: " + e.getMessage(),e); - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付签名异常", null); - } - String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); - signMap.put("sign", signAgent); + WxAppinfo cAppInfo = wxAppinfoService.getCAppInfo(payAccount, EnumAppPlat.WX); + if(cAppInfo == null){ + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前商场未查询到微信C端小程序配置。", null); + } + WxPayService payService = maUtil.getWxPayService(cAppInfo,payAccount); + if (null == payService) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); + } String response = null; try { - response = WxPay.merchantTranferChange(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); + response = WxPay.merchantTranferChange(payService,""); } catch (Exception e) { log.error("零钱支付异常: " + e.getMessage(),e); return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); } - log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); + //log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); return getReusltFromp(response,cashOut); // if (payAccount.getType() == EnumPayMode.MCH.getCode()) { @@ -226,6 +230,46 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ // } } +// /** +// * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 +// * +// * 在wx_pay_account里面要设置merchant_cert_path,登陆特约商户的商户后台,账号中心-API安全。 +// */ +// @Deprecated +// @Override +// public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { +// if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); +// } +// if (StringUtils.isBlank(payAccount.getMerchantApiKey())) { +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); +// } +// WxCashOutP wxCashOutP = generateWxCashOutP(payAccount, appInfo, cashOut); +// Map signMap = null; +// try { +// signMap = BeanUtils.toStringMap(wxCashOutP); +// } catch (Exception e) { +// log.error("零钱支付命令生辰: " + e.getMessage(),e); +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付签名异常", null); +// } +// +// String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); +// signMap.put("sign", signAgent); +// String response = null; +// try { +// response = WxPay.merchantTranferChange(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); +// } catch (Exception e) { +// log.error("零钱支付异常: " + e.getMessage(),e); +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); +// } +// log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); +// return getReusltFromp(response,cashOut); +// +//// if (payAccount.getType() == EnumPayMode.MCH.getCode()) { +// // 普通商户模式 +//// } +// } + private WxCashOutP generateWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { String noncestr = Utility.generate32UUID(); WxCashOutP wxCashOutP = new WxCashOutP(); From 011a812f17b69e654647b52a654efb35907429b0 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Mon, 1 Aug 2022 19:24:29 +0800 Subject: [PATCH 03/16] fix bug --- .../src/main/java/com/iformall/pay/WxPay.java | 16 +++++++++++-- .../cashout/wx/WxCashOutAdapterService.java | 23 ++++++++++++++++++- .../java/com/iformall/utils/DateUtils.java | 2 ++ 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index d408c4044..57723f1b7 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -1,10 +1,16 @@ package com.iformall.pay; +import java.security.cert.X509Certificate; import java.util.HashMap; +import java.util.List; import java.util.Map; +import javax.crypto.IllegalBlockSizeException; + +import com.alibaba.fastjson.JSON; 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.utils.HttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -254,9 +260,15 @@ public class WxPay { * 证书密码 * @return {String} * @throws WxPayException + * @throws IllegalBlockSizeException */ - public static String merchantTranferChange(WxPayService payService,String body) throws WxPayException { - return payService.postV3WithWechatpaySerial(MERCHANT_TRANSFER_CHANGE_URL, body); + public static String merchantTranferChange(WxPayService payService,WxCashOutPV3 cashOutV3) throws WxPayException, IllegalBlockSizeException { + X509Certificate certificate = payService.getConfig().getVerifier().getValidCertificate(); + List items = cashOutV3.getTransfer_detail_list(); + for (WxCashOutPV3Item it : items) { + it.setUser_name(RsaCryptoUtil.encryptOAEP(it.getUser_name(), certificate)); + } + return payService.postV3WithWechatpaySerial(MERCHANT_TRANSFER_CHANGE_URL, JSON.toJSONString(cashOutV3)); } /** diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index d09fb52f6..b563a0e66 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -33,6 +33,7 @@ import com.iformall.mapper.WxPayAccountMapper; import com.iformall.mapper.WxPayOrderMapper; import com.iformall.mapper.WxRefundOrderMapper; import com.iformall.pay.WxCashOutP; +import com.iformall.pay.WxCashOutPV3; import com.iformall.pay.WxCashOutQueryP; import com.iformall.pay.WxPay; import com.iformall.pay.WxPayment; @@ -46,6 +47,7 @@ import com.iformall.service.pay.service.refund.entity.RefundAdapterResult; import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult; import com.iformall.utils.BeanUtils; import com.iformall.utils.CipherUtil; +import com.iformall.utils.DateUtils; import com.iformall.utils.MaUtil; import com.iformall.utils.Utility; import com.iformall.utils.XmlUtil; @@ -217,7 +219,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ } String response = null; try { - response = WxPay.merchantTranferChange(payService,""); + response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, cAppInfo, cashOut)); } catch (Exception e) { log.error("零钱支付异常: " + e.getMessage(),e); return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); @@ -230,6 +232,25 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ // } } + private WxCashOutPV3 generateWxCashOutPV3(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { + String noncestr = Utility.generate32UUID(); + WxCashOutPV3 wxCashOutPv3 = new WxCashOutPV3(); + wxCashOutPv3.setAppid(appInfo.getAppId()); + wxCashOutPv3.setOut_batch_no(String.valueOf(cashOut.getId())); + wxCashOutPv3.setBatch_name(cashOut.getMerchantName()+"提现"); + +// wxCashOutP.setMch_appid(appInfo.getAppId()); +// wxCashOutP.setMchid(payAccount.getSubMchId()); +// wxCashOutP.setNonce_str(noncestr); +// wxCashOutP.setAmount(cashOut.getTotalFee()); +// wxCashOutP.setCheck_name("NO_CHECK"); +// wxCashOutP.setDesc("客户结算"); +// wxCashOutP.setOpenid(cashOut.getReciveOpenId()); +// wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId())); + return wxCashOutPv3; + } + + // /** // * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 // * diff --git a/mallinkService/src/main/java/com/iformall/utils/DateUtils.java b/mallinkService/src/main/java/com/iformall/utils/DateUtils.java index 47217794f..7555833ea 100755 --- a/mallinkService/src/main/java/com/iformall/utils/DateUtils.java +++ b/mallinkService/src/main/java/com/iformall/utils/DateUtils.java @@ -23,6 +23,8 @@ public class DateUtils { public final static String DATE_TIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; public final static String[] weekObj=new String[]{"日","一","二","三","四","五","六"}; + + public final static String DATE_PATTERN_NOSPACE = "yyyyMMdd"; public static String format(Date date) { return format(date, DATE_PATTERN); From 2aa8efbaa8fe33b82c19e23e43fa1458b326f70b Mon Sep 17 00:00:00 2001 From: winter Date: Mon, 1 Aug 2022 23:45:04 +0800 Subject: [PATCH 04/16] fix cashout --- .../db/migration/V20220801000001_cashout.sql | 100 ++++++++++++++++++ .../controller/WxCashOutController.java | 3 + .../com/iformall/domain/po/WxCashOut.java | 3 +- .../java/com/iformall/pay/WxCashOutPV3.java | 4 +- .../com/iformall/pay/WxCashOutPV3Item.java | 2 +- .../service/impl/WxCashOutServiceImpl.java | 1 + .../cashout/wx/WxCashOutAdapterService.java | 24 +++-- .../main/resources/mapper/WxCashOutMapper.xml | 7 +- 8 files changed, 129 insertions(+), 15 deletions(-) create mode 100644 mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql diff --git a/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql new file mode 100644 index 000000000..b3ae8cb4a --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql @@ -0,0 +1,100 @@ +alter table wx_cash_out_0 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_1 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_2 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_3 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_4 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_5 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_6 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_7 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_8 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_9 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_10 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_11 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_12 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_13 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_14 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_15 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_16 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_17 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_18 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_19 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_20 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_21 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_22 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_23 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_24 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_25 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_26 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_27 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_28 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_29 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_30 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_31 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_32 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_33 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_34 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_35 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_36 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_37 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_38 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_39 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_40 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_41 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_42 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_43 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_44 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_45 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_46 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_47 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_48 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_49 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_50 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_51 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_52 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_53 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_54 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_55 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_56 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_57 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_58 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_59 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_60 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_61 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_62 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_63 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_64 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_65 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_66 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_67 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_68 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_69 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_70 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_71 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_72 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_73 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_74 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_75 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_76 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_77 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_78 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_79 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_80 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_81 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_82 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_83 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_84 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_85 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_86 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_87 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_88 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_89 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_90 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_91 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_92 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_93 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_94 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_95 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_96 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_97 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_98 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_cash_out_99 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; \ No newline at end of file diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java index 9cdd9c3e6..632c7a500 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java @@ -179,6 +179,9 @@ public class WxCashOutController extends BaseController { if (mUser == null) { return new ResultData(Result.ERROR,"请用绑定["+merchant.getLinkPhone()+"]的微信在C端完成授权手机号操作。"); } + if (wxCashOut.getTotalFee() >= 2000 && StringUtils.isBlank(wxCashOut.getRealName())) { + return new ResultData(Result.ERROR,"金额2000以上需实名。"); + } wxCashOut.setReciveOpenId(mUser.getOpenId()); wxCashOut.setReciveNickName(mUser.getNickName()); wxCashOut.setWxBOpenHeadImg(mUser.getAvatarUrl()); diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java b/mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java index 23310c9ca..21a00ea17 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxCashOut.java @@ -58,6 +58,7 @@ public class WxCashOut extends TenantEntity { private String wxPayTime; @io.swagger.annotations.ApiModelProperty(value = "失败原因", name = "failRemark") private String failRemark; - + @io.swagger.annotations.ApiModelProperty(value = "实名姓名,超2000需实名", name = "realName") + private String realName; } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java index 16eb68f10..eb2186fc0 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java @@ -13,8 +13,8 @@ public class WxCashOutPV3 { private String out_batch_no; // 商家批次单号 private String batch_name; // 批次名称 private String batch_remark; // 批次备注 - private String total_amount; // 转账总金额 - private String total_num; // 转账总笔数 + private int total_amount; // 转账总金额 + private int total_num; // 转账总笔数 private List transfer_detail_list; // 转账明细列表,最多三千笔 } diff --git a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java index 6919ba5ec..8b0727084 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3Item.java @@ -8,7 +8,7 @@ import lombok.Data; @Data public class WxCashOutPV3Item { private String out_detail_no; // 商家明细单号 - private String transfer_amount; // 转账金额 + private int transfer_amount; // 转账金额 private String transfer_remark; // 转账备注 private String openid; // 用户在直连商户应用下的用户标示 private String user_name; // 收款用户姓名,明细转账金额 >= 2,000,收款用户姓名必填, 该字段需进行加密处理 diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java index ee1d8b357..b36fb3684 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxCashOutServiceImpl.java @@ -150,6 +150,7 @@ public class WxCashOutServiceImpl implements WxCashOutService { cashout.setPhone(record.getPhone()); cashout.setWxBOpenHeadImg(record.getWxBOpenHeadImg()); cashout.updateTenantInfo(buser); + cashout.setRealName(record.getRealName()); wxCashOutMapper.insert(cashout); //TODO有没有审批 diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index b563a0e66..ed82a7f17 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -1,5 +1,6 @@ package com.iformall.service.pay.service.cashout.wx; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.SortedMap; @@ -34,6 +35,7 @@ import com.iformall.mapper.WxPayOrderMapper; import com.iformall.mapper.WxRefundOrderMapper; import com.iformall.pay.WxCashOutP; import com.iformall.pay.WxCashOutPV3; +import com.iformall.pay.WxCashOutPV3Item; import com.iformall.pay.WxCashOutQueryP; import com.iformall.pay.WxPay; import com.iformall.pay.WxPayment; @@ -233,20 +235,22 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ } private WxCashOutPV3 generateWxCashOutPV3(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { - String noncestr = Utility.generate32UUID(); WxCashOutPV3 wxCashOutPv3 = new WxCashOutPV3(); wxCashOutPv3.setAppid(appInfo.getAppId()); wxCashOutPv3.setOut_batch_no(String.valueOf(cashOut.getId())); wxCashOutPv3.setBatch_name(cashOut.getMerchantName()+"提现"); - -// wxCashOutP.setMch_appid(appInfo.getAppId()); -// wxCashOutP.setMchid(payAccount.getSubMchId()); -// wxCashOutP.setNonce_str(noncestr); -// wxCashOutP.setAmount(cashOut.getTotalFee()); -// wxCashOutP.setCheck_name("NO_CHECK"); -// wxCashOutP.setDesc("客户结算"); -// wxCashOutP.setOpenid(cashOut.getReciveOpenId()); -// wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId())); + wxCashOutPv3.setBatch_remark("提现编号:"+cashOut.getId()); + wxCashOutPv3.setTotal_amount(cashOut.getTotalFee()); + wxCashOutPv3.setTotal_num(1); + List itemList = new ArrayList(); + WxCashOutPV3Item item = new WxCashOutPV3Item(); + item.setOut_detail_no(Utility.generate32UUID()); + item.setOpenid(cashOut.getReciveOpenId()); + item.setTransfer_amount(cashOut.getTotalFee()); + item.setTransfer_remark(cashOut.getMerchantName()+"提现"); + item.setUser_name(cashOut.getRealName()); + itemList.add(item); + wxCashOutPv3.setTransfer_detail_list(itemList); return wxCashOutPv3; } diff --git a/mallinkService/src/main/resources/mapper/WxCashOutMapper.xml b/mallinkService/src/main/resources/mapper/WxCashOutMapper.xml index 0d4a48de5..fa4dda4c8 100644 --- a/mallinkService/src/main/resources/mapper/WxCashOutMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxCashOutMapper.xml @@ -22,12 +22,13 @@ + `id`,`tenant_id`,`parent_tenant_id`,`total_fee`,`status`,`audio_remark`,`create_date`,`update_date`,`b_user_id`,`phone`, `wx_b_open_id`,`wx_b_open_head_img`,`audio_date`,`merchant_id`,`merchant_name`,`recive_open_id`,`recive_nick_name`, - `wx_pay_no`,`wx_pay_time`,`fail_remark` + `wx_pay_no`,`wx_pay_time`,`fail_remark`,`real_name` @@ -59,6 +60,10 @@ and `merchant_name` like concat('%', #{merchantName},'%') + + + and `real_name` like concat('%', #{realName},'%') + and `status` = #{status} From 68153a5267fd7c161b953fd609a7dc7e8058f3a6 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 11:59:01 +0800 Subject: [PATCH 05/16] fix cashout --- .../service/pay/service/cashout/wx/WxCashOutAdapterService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index b563a0e66..0c3b9c014 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -222,7 +222,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, cAppInfo, cashOut)); } catch (Exception e) { log.error("零钱支付异常: " + e.getMessage(),e); - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常", null); + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常."+e.getMessage(), null); } //log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); return getReusltFromp(response,cashOut); From 2b4dd4d071ab039a49abd462b426b029b359380b Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 13:11:14 +0800 Subject: [PATCH 06/16] fix cashout --- .../src/main/java/com/iformall/pay/WxPay.java | 20 ++ .../cashout/wx/WxCashOutAdapterService.java | 318 +++++++++++------- 2 files changed, 222 insertions(+), 116 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index 57723f1b7..7879ea763 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -46,6 +46,8 @@ public class WxPay { private static final String GETTRANSFERINFO_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo"; //商家转账到零钱 private static final String MERCHANT_TRANSFER_CHANGE_URL = "https://api.mch.weixin.qq.com/v3/transfer/batches"; + //查询商家转账到零钱 + private static final String MERCHANT_TRANSFER_QUERY_URL = "https://api.mch.weixin.qq.com/v3/transfer/batches/out-batch-no/%s"; // 查询代金券批次 private static final String GETCOUPONSTOCK_URL = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock"; @@ -270,6 +272,24 @@ public class WxPay { } return payService.postV3WithWechatpaySerial(MERCHANT_TRANSFER_CHANGE_URL, JSON.toJSONString(cashOutV3)); } + + /** + * 查询商家转账到零钱 + * https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter4_3_5.shtml + * @param params + * 请求参数 + * @param certPath + * 证书文件目录 + * @param certPassword + * 证书密码 + * @return {String} + * @throws WxPayException + */ + public static String merchantTransferInfo(String batchNo, WxPayService payService) throws WxPayException { + Map param = new HashMap(); + param.put("need_query_detail", false); + return payService.postV3WithWechatpaySerial(String.format(MERCHANT_TRANSFER_QUERY_URL, batchNo), JSON.toJSONString(param)); + } /** * 商户模式下 扫码模式一之生成二维码 diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index e08faf6ef..353b0daf3 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -204,30 +204,29 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ @Override public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { - if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getPrivateCertPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。证书PrivateCertPath为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getMerchantApiKey())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getPrivateKeyPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥PrivateKeyPath为空。请联系管理员配置。", null); } - - WxAppinfo cAppInfo = wxAppinfoService.getCAppInfo(payAccount, EnumAppPlat.WX); - if(cAppInfo == null){ - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前商场未查询到微信C端小程序配置。", null); - } - WxPayService payService = maUtil.getWxPayService(cAppInfo,payAccount); + if (StringUtils.isBlank(payAccount.getApiV3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥ApiV3Key为空。请联系管理员配置。", null); + } + + WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); if (null == payService) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } String response = null; try { - response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, cAppInfo, cashOut)); + response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut)); } catch (Exception e) { log.error("零钱支付异常: " + e.getMessage(),e); return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常."+e.getMessage(), null); } //log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); - return getReusltFromp(response,cashOut); + return generateResult(response,cashOut); // if (payAccount.getType() == EnumPayMode.MCH.getCode()) { // 普通商户模式 @@ -254,6 +253,93 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ return wxCashOutPv3; } + private CashOutAdapterResult generateResult(String response,WxCashOut cashOut) { + JSONObject result = JSON.parseObject(response); + String batchId = result.getString("batch_id"); + if (!StringUtils.isBlank(batchId)) { + cashOut.setWxPayNo(batchId); + String payTime = result.getString("create_time"); + cashOut.setWxPayTime(payTime); + return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",result); + }else { + //log.error("微信零钱支付申请失败: " + response); + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付申请失败:微信接口未返回值", result); + } + } + + + @Override + public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { + if (StringUtils.isBlank(payAccount.getPrivateCertPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。证书PrivateCertPath为空。请联系管理员配置。", null); + } + if (StringUtils.isBlank(payAccount.getPrivateKeyPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥PrivateKeyPath为空。请联系管理员配置。", null); + } + if (StringUtils.isBlank(payAccount.getApiV3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥ApiV3Key为空。请联系管理员配置。", null); + } + WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); + if (null == payService) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); + } + String response = null; + try { + response = WxPay.merchantTransferInfo(String.valueOf(cashOut.getId()), payService); + } catch (Exception e) { + log.error("零钱支付查询异常: " + e.getMessage(),e); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage()); + } + //log.info("微信零钱支付查询:"+ response.toString()); + return getReusltFromQuery(response,cashOut); + } + + private CashOutAdapterResult getReusltFromQuery(String response,WxCashOut cashOut) throws MallinkException{ + JSONObject result = JSON.parseObject(response); + JSONObject transferBatch = result.getJSONObject("transfer_batch"); + if (null != transferBatch) { + /** + * WAIT_PAY:待付款,商户员工确认付款阶段 + * ACCEPTED:已受理。批次已受理成功,若发起批量转账的30分钟后,转账批次单仍处于该状态,可能原因是商户账户余额不足等 + * PROCESSING:转账中。已开始处理批次内的转账明细单 + * FINISHED:已完成。批次内的所有转账明细单都已处理完成 + * CLOSED:已关闭。可查询具体的批次关闭原因确认 + */ + String batchStatus = transferBatch.getString("batch_status"); + if ("WAIT_PAY".equals(batchStatus)) { + throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "待商户付款:"); + }else if ("ACCEPTED".equals(batchStatus)) { + throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "已受理,待转账:"); + }else if ("PROCESSING".equals(batchStatus)) { + throw new MallinkException(EnumCashOutStatus.FAIL.getCode(), "待转账中"); + }else if ("CLOSED".equals(batchStatus)) { + /** + * MERCHANT_REVOCATION:商户主动撤销 OVERDUE_CLOSE:系统超时关闭 + */ + String close_reason = transferBatch.getString("close_reason"); + if ("MERCHANT_REVOCATION".equals(close_reason)) { + close_reason = "商户主动撤销"; + }else if ("OVERDUE_CLOSE".equals(close_reason)) { + close_reason = "系统超时关闭"; + } + return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),"转账已关闭:"+close_reason,result); + }else if ("FINISHED".equals(batchStatus)) { + String detailId = transferBatch.getString("out_batch_no"); + cashOut.setWxPayNo(detailId); + String wxPayTime = transferBatch.getString("create_time"); + cashOut.setWxPayTime(wxPayTime); + return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"转账已完成",result); + }else { + log.error("微信零钱支付查询失败,微信返回未知状态: " + response); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+batchStatus); + } + }else { + log.error("微信零钱支付查询失败,微信未返回值: " + response); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败,微信未返回值:"); + } + } + + // /** // * https://pay.weixin.qq.com/wiki/doc/api/tools/mch_pay.php?chapter=14_2 @@ -294,114 +380,114 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ // // 普通商户模式 //// } // } - - private WxCashOutP generateWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { - String noncestr = Utility.generate32UUID(); - WxCashOutP wxCashOutP = new WxCashOutP(); - wxCashOutP.setMch_appid(appInfo.getAppId()); - wxCashOutP.setMchid(payAccount.getSubMchId()); - wxCashOutP.setNonce_str(noncestr); - wxCashOutP.setAmount(cashOut.getTotalFee()); - wxCashOutP.setCheck_name("NO_CHECK"); - wxCashOutP.setDesc("客户结算"); - wxCashOutP.setOpenid(cashOut.getReciveOpenId()); - wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId())); - return wxCashOutP; - } - - private CashOutAdapterResult getReusltFromp(String response,WxCashOut cashOut) throws MallinkException{ - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - if ("SUCCESS".equals(result_no)) { - log.info("微信零钱支付申请成功: " + returnMap.toString()); - String wxPayNo = returnMap.get("payment_no"); - String payTime = returnMap.get("payment_time"); - cashOut.setWxPayNo(wxPayNo); - cashOut.setWxPayTime(payTime); - return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",returnMap); - } else { - log.error("微信零钱支付申请失败: " + response); - String errMsg = ""; - JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); - if (errObj != null) { - errMsg = errObj.toJSONString(); - } else { - errMsg = returnMap.get("err_code_des"); - } - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), errMsg, returnMap); - } - } - - @Override - public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { - if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); - } - WxCashOutQueryP wxCashOutP = generateQueryWxCashOutP(payAccount, appInfo, cashOut); - Map signMap = null; - try { - signMap = BeanUtils.toStringMap(wxCashOutP); - } catch (Exception e) { - log.error("零钱支付命令生辰: " + e.getMessage(),e); - throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "零钱支付签名异常"); - } - - String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); - signMap.put("sign", signAgent); - String response = null; - try { - response = WxPay.getTransferInfo(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); - } catch (Exception e) { - log.error("零钱支付查询异常: " + e.getMessage(),e); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常"); - } - log.info("微信零钱支付查询:" + wxCashOutP.toString() + ", response: " + response.toString()); - return getReusltFromQueryp(response,cashOut); - } - - private WxCashOutQueryP generateQueryWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { - String noncestr = Utility.generate32UUID(); - WxCashOutQueryP wxCashOutQueryP = new WxCashOutQueryP(); - wxCashOutQueryP.setAppid(appInfo.getAppId()); - wxCashOutQueryP.setMch_id(payAccount.getSubMchId()); - wxCashOutQueryP.setNonce_str(noncestr); - wxCashOutQueryP.setPartner_trade_no(String.valueOf(cashOut.getId())); - return wxCashOutQueryP; - } - - private CashOutAdapterResult getReusltFromQueryp(String response,WxCashOut cashOut) throws MallinkException{ - Map returnMap = WxPayment.xmlToMap(response); - String result_no = returnMap.get("result_code"); - if ("SUCCESS".equals(result_no)) { - String realStatus = returnMap.get("status"); - if ("SUCCESS".equals(realStatus) || "PROCESSING".equals(realStatus)) { - String detailId = returnMap.get("detail_id"); - cashOut.setWxPayNo(detailId); - String wxPayTime = returnMap.get("transfer_time"); - cashOut.setWxPayTime(wxPayTime); - return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付查询成功",returnMap); - }else if("FAILED".equals(realStatus)) { - String msg = returnMap.get("reason"); - return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),msg,returnMap); - }else { - log.error("微信零钱支付查询失败,微信返回未知状态: " + response); - throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+realStatus); - } - } else { - log.error("微信零钱支付查询失败: " + response); - String errMsg = returnMap.get("err_code_des"); - String errCode = returnMap.get("err_code"); - if ("NOT_FOUND".equals(errCode)) { - return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),errMsg,returnMap); - } -// JSONObject errObj = errorQueryReqMap.getJSONObject(result_no); +// +// private WxCashOutP generateWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { +// String noncestr = Utility.generate32UUID(); +// WxCashOutP wxCashOutP = new WxCashOutP(); +// wxCashOutP.setMch_appid(appInfo.getAppId()); +// wxCashOutP.setMchid(payAccount.getSubMchId()); +// wxCashOutP.setNonce_str(noncestr); +// wxCashOutP.setAmount(cashOut.getTotalFee()); +// wxCashOutP.setCheck_name("NO_CHECK"); +// wxCashOutP.setDesc("客户结算"); +// wxCashOutP.setOpenid(cashOut.getReciveOpenId()); +// wxCashOutP.setPartner_trade_no(String.valueOf(cashOut.getId())); +// return wxCashOutP; +// } +// +// private CashOutAdapterResult getReusltFromp(String response,WxCashOut cashOut) throws MallinkException{ +// Map returnMap = WxPayment.xmlToMap(response); +// String result_no = returnMap.get("result_code"); +// if ("SUCCESS".equals(result_no)) { +// log.info("微信零钱支付申请成功: " + returnMap.toString()); +// String wxPayNo = returnMap.get("payment_no"); +// String payTime = returnMap.get("payment_time"); +// cashOut.setWxPayNo(wxPayNo); +// cashOut.setWxPayTime(payTime); +// return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付申请成功",returnMap); +// } else { +// log.error("微信零钱支付申请失败: " + response); +// String errMsg = ""; +// JSONObject errObj = errorRefundReqMap.getJSONObject(result_no); // if (errObj != null) { // errMsg = errObj.toJSONString(); // } else { // errMsg = returnMap.get("err_code_des"); // } - throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败:"+errMsg); - } - } +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), errMsg, returnMap); +// } +// } +// +// @Override +// public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { +// if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { +// return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); +// } +// WxCashOutQueryP wxCashOutP = generateQueryWxCashOutP(payAccount, appInfo, cashOut); +// Map signMap = null; +// try { +// signMap = BeanUtils.toStringMap(wxCashOutP); +// } catch (Exception e) { +// log.error("零钱支付命令生辰: " + e.getMessage(),e); +// throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "零钱支付签名异常"); +// } +// +// String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); +// signMap.put("sign", signAgent); +// String response = null; +// try { +// response = WxPay.getTransferInfo(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); +// } catch (Exception e) { +// log.error("零钱支付查询异常: " + e.getMessage(),e); +// throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常"); +// } +// log.info("微信零钱支付查询:" + wxCashOutP.toString() + ", response: " + response.toString()); +// return getReusltFromQueryp(response,cashOut); +// } +// +// private WxCashOutQueryP generateQueryWxCashOutP(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { +// String noncestr = Utility.generate32UUID(); +// WxCashOutQueryP wxCashOutQueryP = new WxCashOutQueryP(); +// wxCashOutQueryP.setAppid(appInfo.getAppId()); +// wxCashOutQueryP.setMch_id(payAccount.getSubMchId()); +// wxCashOutQueryP.setNonce_str(noncestr); +// wxCashOutQueryP.setPartner_trade_no(String.valueOf(cashOut.getId())); +// return wxCashOutQueryP; +// } +// +// private CashOutAdapterResult getReusltFromQueryp(String response,WxCashOut cashOut) throws MallinkException{ +// Map returnMap = WxPayment.xmlToMap(response); +// String result_no = returnMap.get("result_code"); +// if ("SUCCESS".equals(result_no)) { +// String realStatus = returnMap.get("status"); +// if ("SUCCESS".equals(realStatus) || "PROCESSING".equals(realStatus)) { +// String detailId = returnMap.get("detail_id"); +// cashOut.setWxPayNo(detailId); +// String wxPayTime = returnMap.get("transfer_time"); +// cashOut.setWxPayTime(wxPayTime); +// return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"微信零钱支付查询成功",returnMap); +// }else if("FAILED".equals(realStatus)) { +// String msg = returnMap.get("reason"); +// return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),msg,returnMap); +// }else { +// log.error("微信零钱支付查询失败,微信返回未知状态: " + response); +// throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+realStatus); +// } +// } else { +// log.error("微信零钱支付查询失败: " + response); +// String errMsg = returnMap.get("err_code_des"); +// String errCode = returnMap.get("err_code"); +// if ("NOT_FOUND".equals(errCode)) { +// return new CashOutAdapterResult(false,EnumCashOutStatus.FAIL.getCode(),errMsg,returnMap); +// } +//// JSONObject errObj = errorQueryReqMap.getJSONObject(result_no); +//// if (errObj != null) { +//// errMsg = errObj.toJSONString(); +//// } else { +//// errMsg = returnMap.get("err_code_des"); +//// } +// throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败:"+errMsg); +// } +// } } From 08a22a6d0a0fb3eb480ba6f397e76dacef7a118e Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 15:13:43 +0800 Subject: [PATCH 07/16] fix bug --- .../com/iformall/service/impl/WxRentContractServiceImpl.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 7a7a9e8de..3256f45b8 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java @@ -1298,7 +1298,8 @@ public class WxRentContractServiceImpl implements WxRentContractService { } long rentPrice = 0l, siteMoney = 0l, facilityMoney = 0l, administratorMoney = 0l; if(!wxRentContract.getType().equals(EnumRentContractType.RENT_BY_JOINT.getCode()) && - !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode())){ + !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode()) + && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_CUSTOMIZE.getCode())){ if(wxRentContract.getRentInputWay().equals(EnumRentContractRentInputWay.PART.getCode())){ String rentInfo = wxRentContract.getRentInfo(); JSONArray rentInfoArray = JSONArray.parseArray(rentInfo); From 0559b2b6ab7033f8c2aec5b2a44bd53b0ed190cf Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 15:34:23 +0800 Subject: [PATCH 08/16] fix jinmaorentcontract --- .../com/iformall/service/impl/WxRentContractServiceImpl.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 3256f45b8..2edf94716 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java @@ -1223,7 +1223,7 @@ public class WxRentContractServiceImpl implements WxRentContractService { JSONObject jsonObject = array.getJSONObject(i); String perMonthMoney = jsonObject.getString("perMonthMoney"); if(StringUtils.isNotBlank(perMonthMoney) && !"0".equals(perMonthMoney)){ - BigDecimal priceD = new BigDecimal(perMonthMoney).divide(new BigDecimal(100)); + BigDecimal priceD = new BigDecimal(perMonthMoney); priceArrs[i] = priceD.setScale(0, RoundingMode.HALF_EVEN).longValue(); }else{ priceArrs[i] = 0; @@ -1299,7 +1299,7 @@ public class WxRentContractServiceImpl implements WxRentContractService { long rentPrice = 0l, siteMoney = 0l, facilityMoney = 0l, administratorMoney = 0l; if(!wxRentContract.getType().equals(EnumRentContractType.RENT_BY_JOINT.getCode()) && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode()) - && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_CUSTOMIZE.getCode())){ + && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode())){ if(wxRentContract.getRentInputWay().equals(EnumRentContractRentInputWay.PART.getCode())){ String rentInfo = wxRentContract.getRentInfo(); JSONArray rentInfoArray = JSONArray.parseArray(rentInfo); From 10e8e1593fb61a803413625dcf9174af37a6b4dc Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 15:42:30 +0800 Subject: [PATCH 09/16] fix jinmao rentcontract --- .../com/iformall/service/impl/WxRentContractServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 2edf94716..2e029e27f 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java @@ -1299,7 +1299,7 @@ public class WxRentContractServiceImpl implements WxRentContractService { long rentPrice = 0l, siteMoney = 0l, facilityMoney = 0l, administratorMoney = 0l; if(!wxRentContract.getType().equals(EnumRentContractType.RENT_BY_JOINT.getCode()) && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode()) - && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_COUNT.getCode())){ + && !wxRentContract.getType().equals(EnumRentContractType.RENT_BY_CUSTOMIZE.getCode())){ if(wxRentContract.getRentInputWay().equals(EnumRentContractRentInputWay.PART.getCode())){ String rentInfo = wxRentContract.getRentInfo(); JSONArray rentInfoArray = JSONArray.parseArray(rentInfo); From d457b3a8c7836cf6abeaf6c3e614a95a93862ba5 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 16:28:00 +0800 Subject: [PATCH 10/16] fix bug --- .../com/iformall/service/impl/WxRentContractServiceImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 2e029e27f..62745eb3d 100644 --- a/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java +++ b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java @@ -1223,7 +1223,7 @@ public class WxRentContractServiceImpl implements WxRentContractService { JSONObject jsonObject = array.getJSONObject(i); String perMonthMoney = jsonObject.getString("perMonthMoney"); if(StringUtils.isNotBlank(perMonthMoney) && !"0".equals(perMonthMoney)){ - BigDecimal priceD = new BigDecimal(perMonthMoney); + BigDecimal priceD = new BigDecimal(perMonthMoney).multiply(new BigDecimal(100)); priceArrs[i] = priceD.setScale(0, RoundingMode.HALF_EVEN).longValue(); }else{ priceArrs[i] = 0; From 5a9b890fd7f35ce5014bb9fd97e222aaa1b979ef Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Tue, 2 Aug 2022 20:03:42 +0800 Subject: [PATCH 11/16] fix cashout --- .../db/migration/V20220801000001_cashout.sql | 5 ++- .../com/iformall/domain/po/WxPayAccount.java | 12 ++++-- .../src/main/java/com/iformall/pay/WxPay.java | 2 + .../cashout/wx/WxCashOutAdapterService.java | 16 ++++---- .../main/java/com/iformall/utils/MaUtil.java | 39 ++++++++++++++----- .../resources/mapper/WxPayAccountMapper.xml | 4 +- 6 files changed, 55 insertions(+), 23 deletions(-) diff --git a/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql index b3ae8cb4a..00b634cf1 100644 --- a/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql +++ b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql @@ -97,4 +97,7 @@ alter table wx_cash_out_95 ADD COLUMN `real_name` varchar(32) COMMENT '实 alter table wx_cash_out_96 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; alter table wx_cash_out_97 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; alter table wx_cash_out_98 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; -alter table wx_cash_out_99 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; \ No newline at end of file +alter table wx_cash_out_99 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; + +alter table wx_pay_account add COLUMN `merchant_key_path` varchar(100) COMMENT '商户key证书路径'; +alter table wx_pay_account add COLUMN `merchant_apiv3_key` varchar(100) COMMENT '商户apiV3Key'; \ No newline at end of file diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java index 5ba30326d..66b3631e2 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java @@ -30,6 +30,10 @@ public class WxPayAccount extends TenantEntity { private String certPath; @io.swagger.annotations.ApiModelProperty(value="商户自己的证书",name="merchantCertPath") private String merchantCertPath; + @io.swagger.annotations.ApiModelProperty(value="商户自己的密钥文件",name="merchantKeyPath") + private String merchantKeyPath; + @io.swagger.annotations.ApiModelProperty(value="商户自己的apiv3密钥",name="merchantApiv3Key") + private String merchantApiv3Key; @io.swagger.annotations.ApiModelProperty(value="商户模式-0:普通商户模式1:服务商模式",name="type") private Integer type; @io.swagger.annotations.ApiModelProperty(value="是否开启分账(0:未开启分账1:开启分账)",name="type") @@ -56,13 +60,13 @@ public class WxPayAccount extends TenantEntity { private String serviceId; @io.swagger.annotations.ApiModelProperty(value="微信支付分回调地址",name="payScoreNotifyUrl") private String payScoreNotifyUrl; - @io.swagger.annotations.ApiModelProperty(value="apiV3秘钥",name="apiV3Key") + @io.swagger.annotations.ApiModelProperty(value="平台apiV3秘钥",name="apiV3Key") private String apiV3Key; - @io.swagger.annotations.ApiModelProperty(value="证书序列号",name="certSerialNo") + @io.swagger.annotations.ApiModelProperty(value="平台证书序列号",name="certSerialNo") private String certSerialNo; - @io.swagger.annotations.ApiModelProperty(value="apiv3 商户apiclient_key.pem 商户私钥",name="privateKeyPath") + @io.swagger.annotations.ApiModelProperty(value="平台私钥文件",name="privateKeyPath") private String privateKeyPath; - @io.swagger.annotations.ApiModelProperty(value="apiv3 商户apiclient_cert.pem",name="privateCertPath") + @io.swagger.annotations.ApiModelProperty(value="平台证书文件,同certPath",name="privateCertPath") private String privateCertPath; // @io.swagger.annotations.ApiModelProperty(value="app平台 EnumAppPlat ",name="plat") diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index 7879ea763..dbd3f0149 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -8,9 +8,11 @@ import java.util.Map; import javax.crypto.IllegalBlockSizeException; import com.alibaba.fastjson.JSON; +import com.github.binarywang.wxpay.config.WxPayConfig; 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.domain.po.WxPayAccount; import com.iformall.utils.HttpUtil; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index 353b0daf3..be2f2c73d 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -204,17 +204,17 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ @Override public CashOutAdapterResult cashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { - if (StringUtils.isBlank(payAccount.getPrivateCertPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。证书PrivateCertPath为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getPrivateKeyPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥PrivateKeyPath为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getApiV3Key())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥ApiV3Key为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); } - WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); + WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); if (null == payService) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } @@ -279,7 +279,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ if (StringUtils.isBlank(payAccount.getApiV3Key())) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥ApiV3Key为空。请联系管理员配置。", null); } - WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); + WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); if (null == payService) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } diff --git a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java index 124d3ec73..d0e8269fe 100644 --- a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java @@ -92,6 +92,16 @@ public class MaUtil { } public WxPayService getWxPayService(WxAppinfo appinfo, WxPayAccount payAccount) { + return getWxPayService(appinfo,payAccount,true); + } + + //自研非服务商模式 + public WxPayService getWxPayServiceBySelfModel(WxAppinfo appinfo, WxPayAccount payAccount) { + return getWxPayService(appinfo,payAccount,false); + } + + //@isService 是否服务商模式 + private WxPayService getWxPayService(WxAppinfo appinfo, WxPayAccount payAccount,boolean isService) { WxPayConfig config = new WxPayConfig(); config.setAppId(appinfo.getAppId()); config.setMchId(payAccount.getMchId()); @@ -103,20 +113,31 @@ public class MaUtil { //以下是apiv3以及支付分相关 // config.setServiceId(payAccount.getServiceId()); // config.setPayScoreNotifyUrl(payAccount.getPayScoreNotifyUrl()); + //服务商,取平台的 + int iss = 0; + if (isService) { + iss = 1; + config.setPrivateKeyPath(payAccount.getPrivateKeyPath()); + config.setPrivateCertPath(payAccount.getPrivateCertPath()); + //config.setCertSerialNo(payAccount.getCertSerialNo()); + config.setApiV3Key(payAccount.getApiV3Key()); + }else { + config.setPrivateKeyPath(payAccount.getMerchantKeyPath()); + config.setPrivateCertPath(payAccount.getMerchantCertPath()); + //config.setCertSerialNo(payAccount.getCertSerialNo()); + config.setApiV3Key(payAccount.getMerchantApiv3Key()); + } + + String key = new StringBuffer(appinfo.getAppId()).append("_").append(iss).toString(); - config.setPrivateKeyPath(payAccount.getPrivateKeyPath());//apiv3 商户apiclient_key.pem 商户私钥 - config.setPrivateCertPath(payAccount.getPrivateCertPath());//apiv3 商户apiclient_cert.pem - config.setCertSerialNo(payAccount.getCertSerialNo());//证书序列号 - config.setApiV3Key(payAccount.getApiV3Key());//apiV3秘钥 - - WxPayService service = payServiceMap.get(appinfo.getAppId()); + WxPayService service = payServiceMap.get(key); if ( null == service ) { - synchronized("getWxPayServiceBlock"+appinfo.getAppId()) { - service = payServiceMap.get(appinfo.getAppId()); + synchronized("getWxPayServiceBlock"+key) { + service = payServiceMap.get(key); if (null == service) { service = new WxPayServiceImpl(); service.setConfig(config); - payServiceMap.put(appinfo.getAppId(), service); + payServiceMap.put(key, service); } } } diff --git a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml index dc8105d8c..7a90cde46 100644 --- a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml @@ -10,6 +10,8 @@ + + @@ -31,7 +33,7 @@ `id`,`tenant_id`,`parent_tenant_id`,`mch_id`,`sub_mch_id`,`sub_app_id`,`api_key`,`merchant_api_key`,`notify_url`,`notify_token`,`cert_path`, `merchant_cert_path`,`type`,`share`,`rate`,`real_rate`, - `service_id`,`pay_score_notify_url`,`api_v3_key`,`cert_serial_no`,`private_key_path`,`private_cert_path` + `service_id`,`pay_score_notify_url`,`api_v3_key`,`cert_serial_no`,`private_key_path`,`private_cert_path`,`merchant_key_path`,`merchant_apiv3_key` From f2dc500d2a07049c34153fd7c06fb4bad532be23 Mon Sep 17 00:00:00 2001 From: winter Date: Tue, 2 Aug 2022 23:03:26 +0800 Subject: [PATCH 12/16] fix cashout --- .../main/java/com/iformall/utils/MaUtil.java | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java index d0e8269fe..97d12d7b7 100644 --- a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java @@ -103,13 +103,6 @@ public class MaUtil { //@isService 是否服务商模式 private WxPayService getWxPayService(WxAppinfo appinfo, WxPayAccount payAccount,boolean isService) { WxPayConfig config = new WxPayConfig(); - config.setAppId(appinfo.getAppId()); - config.setMchId(payAccount.getMchId()); - config.setMchKey(payAccount.getApiKey()); - config.setSubAppId(appinfo.getAppId()); - config.setSubMchId(payAccount.getSubMchId()); - config.setKeyPath(payAccount.getCertPath()); - //以下是apiv3以及支付分相关 // config.setServiceId(payAccount.getServiceId()); // config.setPayScoreNotifyUrl(payAccount.getPayScoreNotifyUrl()); @@ -117,11 +110,23 @@ public class MaUtil { int iss = 0; if (isService) { iss = 1; + config.setAppId(appinfo.getAppId()); + config.setMchId(payAccount.getMchId()); + config.setMchKey(payAccount.getApiKey()); + config.setSubAppId(appinfo.getAppId()); + config.setSubMchId(payAccount.getSubMchId()); + config.setKeyPath(payAccount.getCertPath()); config.setPrivateKeyPath(payAccount.getPrivateKeyPath()); config.setPrivateCertPath(payAccount.getPrivateCertPath()); //config.setCertSerialNo(payAccount.getCertSerialNo()); config.setApiV3Key(payAccount.getApiV3Key()); }else { + config.setAppId(appinfo.getAppId()); + config.setMchId(payAccount.getSubMchId()); + config.setMchKey(payAccount.getMerchantApiKey()); + config.setSubAppId(appinfo.getAppId()); + config.setSubMchId(payAccount.getSubMchId()); + config.setKeyPath(payAccount.getMerchantKeyPath()); config.setPrivateKeyPath(payAccount.getMerchantKeyPath()); config.setPrivateCertPath(payAccount.getMerchantCertPath()); //config.setCertSerialNo(payAccount.getCertSerialNo()); From 0bb9f9eab6ceaf243e690aecd0a4aa222820adaf Mon Sep 17 00:00:00 2001 From: winter Date: Tue, 2 Aug 2022 23:14:12 +0800 Subject: [PATCH 13/16] fix cashout --- .../service/pay/service/cashout/wx/WxCashOutAdapterService.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index be2f2c73d..5133d098b 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -214,7 +214,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); } - WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); + WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); if (null == payService) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } From ff62f03b711075e6129c076ed778a5362b36ba0e Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Wed, 3 Aug 2022 10:43:21 +0800 Subject: [PATCH 14/16] fix cashout --- .../service/cashout/wx/WxCashOutAdapterService.java | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index be2f2c73d..7b8984b54 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -270,14 +270,14 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ @Override public CashOutAdapterResult queryCashOut(WxAppinfo appInfo, WxPayAccount payAccount, WxCashOut cashOut) { - if (StringUtils.isBlank(payAccount.getPrivateCertPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。证书PrivateCertPath为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantCertPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getPrivateKeyPath())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥PrivateKeyPath为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getApiV3Key())) { - return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。密钥ApiV3Key为空。请联系管理员配置。", null); + if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); } WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); if (null == payService) { From 83cb26dacbbd1e70ce3f5904c25fa783b0eb3476 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Wed, 3 Aug 2022 10:47:41 +0800 Subject: [PATCH 15/16] fix cashout --- .../main/java/com/iformall/controller/WxCashOutController.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java index 632c7a500..3a7945d89 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java @@ -1,5 +1,6 @@ package com.iformall.controller; +import com.alibaba.fastjson.JSON; import com.github.pagehelper.PageInfo; import com.iformall.common.Result; import com.iformall.common.ResultData; @@ -164,6 +165,7 @@ public class WxCashOutController extends BaseController { @ApiOperation("微信B端提现") @PostMapping("cashout") public ResultData cashout(@RequestBody WxCashOut wxCashOut) { + logger.info(">>>cashout>>>"+JSON.toJSONString(wxCashOut)); WxMerchantBUser buser = getLoginBUser(); CUser user = getCUser(); WxMerchant merchant = wxMerchantService.getById(buser.getMerchantId()); From 4824e80756ae87c749c4f94f5e7fa909f187fe61 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Wed, 3 Aug 2022 13:07:22 +0800 Subject: [PATCH 16/16] fix cashout --- .../db/migration/V20220801000001_cashout.sql | 4 +++- .../com/iformall/controller/WxBillController.java | 6 +++++- .../iformall/controller/WxCashOutController.java | 13 +++++++++++-- .../java/com/iformall/domain/po/WxPayAccount.java | 10 +++++++--- .../src/main/java/com/iformall/pay/WxPay.java | 5 ++++- .../service/cashout/wx/WxCashOutAdapterService.java | 6 +++--- .../src/main/java/com/iformall/utils/MaUtil.java | 4 ++-- .../main/resources/mapper/WxPayAccountMapper.xml | 7 ++++--- 8 files changed, 39 insertions(+), 16 deletions(-) diff --git a/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql index 00b634cf1..974e1438d 100644 --- a/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql +++ b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql @@ -99,5 +99,7 @@ alter table wx_cash_out_97 ADD COLUMN `real_name` varchar(32) COMMENT '实 alter table wx_cash_out_98 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; alter table wx_cash_out_99 ADD COLUMN `real_name` varchar(32) COMMENT '实名姓名,超2000需实名'; +alter table wx_pay_account change column private_cert_path private_cert_pem_path varchar(255); alter table wx_pay_account add COLUMN `merchant_key_path` varchar(100) COMMENT '商户key证书路径'; -alter table wx_pay_account add COLUMN `merchant_apiv3_key` varchar(100) COMMENT '商户apiV3Key'; \ No newline at end of file +alter table wx_pay_account add COLUMN `merchant_apiv3_key` varchar(100) COMMENT '商户apiV3Key'; +alter table wx_pay_account add COLUMN `merchant_cert_pem_path` varchar(100) COMMENT '商户证书密钥文件'; \ No newline at end of file diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java index 11c923e7e..a142c3be8 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxBillController.java @@ -123,7 +123,6 @@ public class WxBillController extends BaseController { map.put("businessType", EnumFlowKey.BILL_FINISH.getCode()); //map.put("payMoney", wxBillAll.getNewPrice()); map.put("businessId", wxBillAll.getId()); - map.put("payImg", wxBillAll.getPayImg()); List variablesList = new ArrayList(); Map billTypeMap = new HashMap(); billTypeMap.put("key","billType"); @@ -145,6 +144,11 @@ public class WxBillController extends BaseController { newPriceMap.put("value",wxBillAll.getNewPrice()); variablesList.add(newPriceMap); + Map payImgMap = new HashMap(); + payImgMap.put("key","payImg"); + payImgMap.put("value",wxBillAll.getPayImg()); + variablesList.add(payImgMap); + map.put("variables", variablesList); map.put("phone", buser.getPhone()); wxFlowService.start(map, buser.getId(), buser.getName(), this.getTenantInfo()); diff --git a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java index 3a7945d89..3da2a8ca8 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java @@ -2,10 +2,12 @@ package com.iformall.controller; import com.alibaba.fastjson.JSON; import com.github.pagehelper.PageInfo; +import com.iformall.annotation.AuthIgnore; import com.iformall.common.Result; import com.iformall.common.ResultData; import com.iformall.domain.po.*; import com.iformall.domain.po.base.BaseEntity.SortField; +import com.iformall.domain.po.base.TenantEntity; import com.iformall.enums.EnumCashOutStatus; import com.iformall.enums.EnumPayShare; import com.iformall.enums.EnumPayWay; @@ -165,7 +167,6 @@ public class WxCashOutController extends BaseController { @ApiOperation("微信B端提现") @PostMapping("cashout") public ResultData cashout(@RequestBody WxCashOut wxCashOut) { - logger.info(">>>cashout>>>"+JSON.toJSONString(wxCashOut)); WxMerchantBUser buser = getLoginBUser(); CUser user = getCUser(); WxMerchant merchant = wxMerchantService.getById(buser.getMerchantId()); @@ -201,5 +202,13 @@ public class WxCashOutController extends BaseController { // WxMerchantBUser buser = getLoginBUser(); // return wxCashOutService.reCashout(buser, wxCashOut,EnumPayWay.PAY_WAY_WECHAT); // } - + + @AuthIgnore + @GetMapping("test") + public String test() { + TenantEntity te = new TenantEntity(); + te.setTenantId("789"); + wxCashOutService.cashOutToWx(EnumPayWay.PAY_WAY_WECHAT,te, 714465978943332352L); + return "ok"; + } } diff --git a/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java index 66b3631e2..91ddf3b81 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java @@ -26,14 +26,18 @@ public class WxPayAccount extends TenantEntity { private String notifyUrl; @io.swagger.annotations.ApiModelProperty(value="tt回调token",name="notifyToken") private String notifyToken; - @io.swagger.annotations.ApiModelProperty(value="证书本地存放位置",name="certPath") + @io.swagger.annotations.ApiModelProperty(value="平台证书本地存放位置",name="certPath") private String certPath; @io.swagger.annotations.ApiModelProperty(value="商户自己的证书",name="merchantCertPath") private String merchantCertPath; + @io.swagger.annotations.ApiModelProperty(value="商户自己的证书密钥文件",name="merchantCertPemPath") + private String merchantCertPemPath; @io.swagger.annotations.ApiModelProperty(value="商户自己的密钥文件",name="merchantKeyPath") private String merchantKeyPath; @io.swagger.annotations.ApiModelProperty(value="商户自己的apiv3密钥",name="merchantApiv3Key") private String merchantApiv3Key; + + @io.swagger.annotations.ApiModelProperty(value="商户模式-0:普通商户模式1:服务商模式",name="type") private Integer type; @io.swagger.annotations.ApiModelProperty(value="是否开启分账(0:未开启分账1:开启分账)",name="type") @@ -66,8 +70,8 @@ public class WxPayAccount extends TenantEntity { private String certSerialNo; @io.swagger.annotations.ApiModelProperty(value="平台私钥文件",name="privateKeyPath") private String privateKeyPath; - @io.swagger.annotations.ApiModelProperty(value="平台证书文件,同certPath",name="privateCertPath") - private String privateCertPath; + @io.swagger.annotations.ApiModelProperty(value="平台证书密钥文件",name="privateCertPemPath") + private String privateCertPemPath; // @io.swagger.annotations.ApiModelProperty(value="app平台 EnumAppPlat ",name="plat") // private Integer plat; diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index dbd3f0149..eeb873e3a 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -8,6 +8,7 @@ import java.util.Map; import javax.crypto.IllegalBlockSizeException; import com.alibaba.fastjson.JSON; +import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.github.binarywang.wxpay.config.WxPayConfig; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; @@ -270,7 +271,9 @@ public class WxPay { X509Certificate certificate = payService.getConfig().getVerifier().getValidCertificate(); List items = cashOutV3.getTransfer_detail_list(); for (WxCashOutPV3Item it : items) { - it.setUser_name(RsaCryptoUtil.encryptOAEP(it.getUser_name(), certificate)); + if (!StringUtils.isBlank(it.getUser_name())) { + it.setUser_name(RsaCryptoUtil.encryptOAEP(it.getUser_name(), certificate)); + } } return payService.postV3WithWechatpaySerial(MERCHANT_TRANSFER_CHANGE_URL, JSON.toJSONString(cashOutV3)); } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java index 57838385f..4dd968577 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/WxCashOutAdapterService.java @@ -214,7 +214,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); } - WxPayService payService = maUtil.getWxPayService(appInfo,payAccount); + WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); if (null == payService) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } @@ -225,7 +225,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ log.error("零钱支付异常: " + e.getMessage(),e); return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常."+e.getMessage(), null); } - //log.info("微信零钱支付:" + wxCashOutP.toString() +", response: " + response.toString()); + log.info("微信零钱支付:, response: " + response.toString()); return generateResult(response,cashOut); // if (payAccount.getType() == EnumPayMode.MCH.getCode()) { @@ -290,7 +290,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{ log.error("零钱支付查询异常: " + e.getMessage(),e); throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage()); } - //log.info("微信零钱支付查询:"+ response.toString()); + log.info("微信零钱支付查询:"+ response.toString()); return getReusltFromQuery(response,cashOut); } diff --git a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java index 97d12d7b7..772d2db4f 100644 --- a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java @@ -117,7 +117,7 @@ public class MaUtil { config.setSubMchId(payAccount.getSubMchId()); config.setKeyPath(payAccount.getCertPath()); config.setPrivateKeyPath(payAccount.getPrivateKeyPath()); - config.setPrivateCertPath(payAccount.getPrivateCertPath()); + config.setPrivateCertPath(payAccount.getPrivateCertPemPath()); //config.setCertSerialNo(payAccount.getCertSerialNo()); config.setApiV3Key(payAccount.getApiV3Key()); }else { @@ -128,7 +128,7 @@ public class MaUtil { config.setSubMchId(payAccount.getSubMchId()); config.setKeyPath(payAccount.getMerchantKeyPath()); config.setPrivateKeyPath(payAccount.getMerchantKeyPath()); - config.setPrivateCertPath(payAccount.getMerchantCertPath()); + config.setPrivateCertPath(payAccount.getMerchantCertPemPath()); //config.setCertSerialNo(payAccount.getCertSerialNo()); config.setApiV3Key(payAccount.getMerchantApiv3Key()); } diff --git a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml index 7a90cde46..3a6ace6ae 100644 --- a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml @@ -17,6 +17,7 @@ + @@ -27,13 +28,13 @@ - + `id`,`tenant_id`,`parent_tenant_id`,`mch_id`,`sub_mch_id`,`sub_app_id`,`api_key`,`merchant_api_key`,`notify_url`,`notify_token`,`cert_path`, - `merchant_cert_path`,`type`,`share`,`rate`,`real_rate`, - `service_id`,`pay_score_notify_url`,`api_v3_key`,`cert_serial_no`,`private_key_path`,`private_cert_path`,`merchant_key_path`,`merchant_apiv3_key` + `merchant_cert_path`,`type`,`share`,`rate`,`real_rate`,`service_id`,`pay_score_notify_url`,`api_v3_key`,`cert_serial_no`,`private_key_path`, + `private_cert_pem_path`,`merchant_key_path`,`merchant_apiv3_key`,`merchant_cert_pem_path`