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..a303f45ff 100644 --- a/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java +++ b/mallinkAdmin/src/main/java/com/iformall/controller/base/BaseController.java @@ -46,11 +46,17 @@ 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"); return user; } public Long getUserId(){ Long userId = (Long) SecurityUtils.getSubject().getSession().getAttribute(UserSession.userId); +// Long userId = 463627091581734912L; return userId; } 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..974e1438d --- /dev/null +++ b/mallinkAdmin/src/main/resources/db/migration/V20220801000001_cashout.sql @@ -0,0 +1,105 @@ +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需实名'; + +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'; +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 9cdd9c3e6..3da2a8ca8 100644 --- a/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java +++ b/mallinkBApi/src/main/java/com/iformall/controller/WxCashOutController.java @@ -1,10 +1,13 @@ 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; @@ -179,6 +182,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()); @@ -196,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/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/domain/po/WxPayAccount.java b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java index 904177093..8cd635d1e 100644 --- a/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java +++ b/mallinkService/src/main/java/com/iformall/domain/po/WxPayAccount.java @@ -29,10 +29,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="EnumPayMchType 0:总分1:直连",name="mchType") @@ -63,14 +71,14 @@ 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") - 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/WxCashOutPV3.java b/mallinkService/src/main/java/com/iformall/pay/WxCashOutPV3.java new file mode 100644 index 000000000..eb2186fc0 --- /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 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 new file mode 100644 index 000000000..8b0727084 --- /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 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/pay/WxPay.java b/mallinkService/src/main/java/com/iformall/pay/WxPay.java index 7f58d9256..eeb873e3a 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPay.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPay.java @@ -1,8 +1,19 @@ 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.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; +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; @@ -36,6 +47,10 @@ 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 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"; @@ -211,8 +226,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 +239,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 +254,47 @@ 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} + * @throws WxPayException + * @throws IllegalBlockSizeException + */ + 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) { + 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)); + } + + /** + * 查询商家转账到零钱 + * 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/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/impl/WxRentContractServiceImpl.java b/mallinkService/src/main/java/com/iformall/service/impl/WxRentContractServiceImpl.java index 7e9f82f14..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).multiply(new BigDecimal(12)).divide(new BigDecimal(100)); + BigDecimal priceD = new BigDecimal(perMonthMoney).multiply(new BigDecimal(100)); priceArrs[i] = priceD.setScale(0, RoundingMode.HALF_EVEN).longValue(); }else{ priceArrs[i] = 0; @@ -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); 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..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 @@ -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; @@ -11,6 +12,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 +21,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; @@ -30,11 +34,14 @@ 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.WxCashOutPV3Item; import com.iformall.pay.WxCashOutQueryP; 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 +49,8 @@ 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; @@ -50,6 +59,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,152 +202,292 @@ 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())) { return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户证书为空。请联系管理员配置。", null); } - if (StringUtils.isBlank(payAccount.getMerchantApiKey())) { + if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { 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); + if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); + } + + WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); + if (null == payService) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } - - String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); - signMap.put("sign", signAgent); String response = null; try { - response = WxPay.transfers(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); + response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, 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); + log.info("微信零钱支付:, response: " + response.toString()); + return generateResult(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(); - 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 WxCashOutPV3 generateWxCashOutPV3(WxPayAccount payAccount,WxAppinfo appInfo,WxCashOut cashOut) { + WxCashOutPV3 wxCashOutPv3 = new WxCashOutPV3(); + wxCashOutPv3.setAppid(appInfo.getAppId()); + wxCashOutPv3.setOut_batch_no(String.valueOf(cashOut.getId())); + wxCashOutPv3.setBatch_name(cashOut.getMerchantName()+"提现"); + 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; } - 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); - } + 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.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(), "零钱支付签名异常"); + if (StringUtils.isBlank(payAccount.getMerchantKeyPath())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥为空。请联系管理员配置。", null); + } + if (StringUtils.isBlank(payAccount.getMerchantApiv3Key())) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。商户密钥ApiV3为空。请联系管理员配置。", null); + } + WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo,payAccount); + if (null == payService) { + return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "零钱支付失败。当前小程序未查询到payService。", null); } - - String signAgent = WxPayment.createSign(signMap, payAccount.getMerchantApiKey()); - signMap.put("sign", signAgent); String response = null; try { - response = WxPay.getTransferInfo(signMap, payAccount.getMerchantCertPath(), payAccount.getSubMchId()); + response = WxPay.merchantTransferInfo(String.valueOf(cashOut.getId()), payService); } catch (Exception e) { log.error("零钱支付查询异常: " + e.getMessage(),e); - throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常"); + throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage()); } - log.info("微信零钱支付查询:" + wxCashOutP.toString() + ", response: " + response.toString()); - return getReusltFromQueryp(response,cashOut); + log.info("微信零钱支付查询:"+ response.toString()); + return getReusltFromQuery(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"); + 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 = returnMap.get("transfer_time"); + String wxPayTime = transferBatch.getString("create_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 { + return new CashOutAdapterResult(true,EnumCashOutStatus.SUCCESS.getCode(),"转账已完成",result); + }else { log.error("微信零钱支付查询失败,微信返回未知状态: " + response); - throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+realStatus); + throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), "微信零钱支付查询失败, 微信返回未知状态:"+batchStatus); } - } 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); + }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 +// * +// * 在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(); +// 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); +// } +// } } 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); diff --git a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java index 124d3ec73..772d2db4f 100644 --- a/mallinkService/src/main/java/com/iformall/utils/MaUtil.java +++ b/mallinkService/src/main/java/com/iformall/utils/MaUtil.java @@ -92,31 +92,57 @@ 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()); - 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()); + //服务商,取平台的 + 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.getPrivateCertPemPath()); + //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.getMerchantCertPemPath()); + //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/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} diff --git a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml index d2fa5049e..14afd4f82 100644 --- a/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml +++ b/mallinkService/src/main/resources/mapper/WxPayAccountMapper.xml @@ -10,11 +10,14 @@ + + + @@ -27,13 +30,14 @@ - + `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`,`mch_type`,`open_pay`,`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`, + `private_cert_pem_path`,`merchant_key_path`,`merchant_apiv3_key`,`merchant_cert_pem_path`