From 6a74dd15542123da1d40ce94c6ce4ee169ead800 Mon Sep 17 00:00:00 2001 From: zhengfangyuan Date: Thu, 11 Aug 2022 18:43:41 +0800 Subject: [PATCH] fix pay v3 --- .../main/java/com/iformall/pay/WxPayV3.java | 27 +++- .../wx/v3/entity/CombineItemOrder.java | 15 ++ .../wx/v3/entity/CombinePayAmountReq.java | 11 ++ .../v3/entity/CombinePayCommonMiniAppReq.java | 16 +++ .../cashout/wx/v3/entity/CombinePayerReq.java | 10 ++ .../cashout/wx/v3/entity/PayAmountReq.java | 11 ++ .../wx/v3/entity/PayCommonMiniAppReq.java | 17 +++ .../cashout/wx/v3/entity/PaySettleReq.java | 11 ++ .../cashout/wx/v3/entity/PayerReq.java | 10 ++ .../appPay/WxMiniAppPayV3AdapterService.java | 130 ++++++------------ 10 files changed, 167 insertions(+), 91 deletions(-) create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombineItemOrder.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayAmountReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayCommonMiniAppReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayerReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayAmountReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayCommonMiniAppReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PaySettleReq.java create mode 100644 mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayerReq.java diff --git a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java index 587a00437..ca9e16e85 100644 --- a/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java +++ b/mallinkService/src/main/java/com/iformall/pay/WxPayV3.java @@ -10,6 +10,9 @@ import com.aliyun.openservices.shade.org.apache.commons.lang3.StringUtils; import com.github.binarywang.wxpay.exception.WxPayException; import com.github.binarywang.wxpay.service.WxPayService; import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil; +import com.iformall.service.pay.service.cashout.wx.v3.entity.CombinePayCommonMiniAppReq; +import com.iformall.service.pay.service.cashout.wx.v3.entity.PayCommonMiniAppReq; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -20,7 +23,11 @@ public class WxPayV3 { 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 PAY_COMMON_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/pay/partner/transactions/jsapi"; + //电商收付通-普合单支付-小程序下单 + private static final String PAY_COMBINE_MINIAPP_URL = "https://api.mch.weixin.qq.com/v3/combine-transactions/jsapi"; + private WxPayV3() { } @@ -44,6 +51,7 @@ public class WxPayV3 { 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)); } } @@ -67,4 +75,21 @@ public class WxPayV3 { param.put("need_query_detail", false); return payService.postV3WithWechatpaySerial(String.format(MERCHANT_TRANSFER_QUERY_URL, batchNo), JSON.toJSONString(param)); } + + /** + * 电商收付通-普通支付-小程序下单 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_3.shtml + * @throws WxPayException + */ + public static String payCommonWithMiniApp(WxPayService payService,PayCommonMiniAppReq payReq) throws WxPayException { + return payService.postV3WithWechatpaySerial(PAY_COMMON_MINIAPP_URL, JSON.toJSONString(payReq)); + } + + /** + * 电商收付通-合单支付-小程序下单https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_3_4.shtml + * @throws WxPayException + */ + public static String payCombineCommonWithMiniApp(WxPayService payService,CombinePayCommonMiniAppReq payReq) throws WxPayException { + return payService.postV3WithWechatpaySerial(PAY_COMBINE_MINIAPP_URL, JSON.toJSONString(payReq)); + } + } diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombineItemOrder.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombineItemOrder.java new file mode 100644 index 000000000..8f4b2ca62 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombineItemOrder.java @@ -0,0 +1,15 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class CombineItemOrder { + + private String mchid;//子单商户号 + private String attach;//附加数据,在查询API和支付通知中原样返回,可作为自定义参数使用 + private CombinePayAmountReq amount;//订单金额 + private String out_trade_no;//子单商户订单号 + private String sub_mchid;//二级商户号,服务商子商户的商户号,被合单方。直连商户不用传二级商户号 + private String description;//商品描述,需传入应用市场上的APP名字-实际商品名称 + private PaySettleReq settle_info;//结算信息 +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayAmountReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayAmountReq.java new file mode 100644 index 000000000..9055b4502 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayAmountReq.java @@ -0,0 +1,11 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class CombinePayAmountReq { + + private int total_amount;//总金额,单位为分。 + private String currency="CNY";//货币类型 + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayCommonMiniAppReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayCommonMiniAppReq.java new file mode 100644 index 000000000..4be8ebb20 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayCommonMiniAppReq.java @@ -0,0 +1,16 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import java.util.List; + +import lombok.Data; + +@Data +public class CombinePayCommonMiniAppReq { + + private String combine_appid;//合单发起方的appid + private String combine_mchid;//合单发起方商户号,服务商和电商模式下,传服务商商户号 + private String combine_out_trade_no;//合单支付总订单号 + private List sub_orders;//商品描述 + private CombinePayerReq combine_payer_info;// 支付者信息 + private String notify_url;//接收微信支付异步通知回调地址 +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayerReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayerReq.java new file mode 100644 index 000000000..e6e10ba24 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/CombinePayerReq.java @@ -0,0 +1,10 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class CombinePayerReq { + + private String openid;//使用合单appid获取的对应用户openid + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayAmountReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayAmountReq.java new file mode 100644 index 000000000..b49d9bc47 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayAmountReq.java @@ -0,0 +1,11 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class PayAmountReq { + + private int total;//总金额,单位为分。 + private String currency="CNY";//货币类型 + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayCommonMiniAppReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayCommonMiniAppReq.java new file mode 100644 index 000000000..f8b5efb38 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayCommonMiniAppReq.java @@ -0,0 +1,17 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class PayCommonMiniAppReq { + + private String sp_appid;//服务商应用ID + private String sp_mchid;//服务商户号 + private String sub_mchid;//二级商户号 + private String description;//商品描述 + private String out_trade_no;//商户订单号 + private String notify_url;//通知地址,不允许携带查询串 + private PaySettleReq settle_info;//结算信息 + private PayAmountReq amount;//订单金额 + private PayerReq payer;//支付者 +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PaySettleReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PaySettleReq.java new file mode 100644 index 000000000..187397377 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PaySettleReq.java @@ -0,0 +1,11 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class PaySettleReq { + + private boolean profit_sharing;//是否指定分账 + private int subsidy_amount = 0;//补差金额,单笔订单最高补差金额为5000元.SettleInfo.profit_sharing为true时,该金额才生效 + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayerReq.java b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayerReq.java new file mode 100644 index 000000000..6427f80f5 --- /dev/null +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/entity/PayerReq.java @@ -0,0 +1,10 @@ +package com.iformall.service.pay.service.cashout.wx.v3.entity; + +import lombok.Data; + +@Data +public class PayerReq { + + private String sp_openid;//用户在服务商appid下的唯一标识 + +} diff --git a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java index 6ea9a07bb..8f458de32 100644 --- a/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java +++ b/mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java @@ -7,10 +7,12 @@ import java.util.Map; import com.iformall.domain.po.*; import org.apache.commons.lang3.StringUtils; +import org.springframework.beans.factory.annotation.Autowired; 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; @@ -23,14 +25,18 @@ import com.iformall.exception.MallinkException; import com.iformall.pay.WxPay; import com.iformall.pay.WxPayOrderP; import com.iformall.pay.WxPayOrderSP; +import com.iformall.pay.WxPayV3; import com.iformall.pay.WxPayment; import com.iformall.service.order.entity.WxComposeOrder; import com.iformall.service.pay.entity.PayExtraParam; +import com.iformall.service.pay.service.cashout.wx.v3.entity.CombinePayCommonMiniAppReq; +import com.iformall.service.pay.service.cashout.wx.v3.entity.PayCommonMiniAppReq; import com.iformall.service.pay.service.pay.CDrivingPayService; import com.iformall.service.pay.service.pay.entity.PayAdapterResult; import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult; import com.iformall.service.pay.service.pay.wx.v2.BaseWxPayAdapterService; import com.iformall.utils.BeanUtils; +import com.iformall.utils.MaUtil; import com.iformall.utils.MapUtil; import com.iformall.utils.Utility; @@ -40,10 +46,14 @@ import lombok.extern.slf4j.Slf4j; @Service public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ + @Autowired + MaUtil maUtil; - private WxPayOrderP generateWxPayOrderP(WxPayAccount payAccount,WxComposeOrder composeOrder,String productName, WxPayOrder record,String openId,String appId,Date currentDate) throws Exception { - // 统一下单 普通商户模式 - String noncestr = Utility.generate32UUID(); + private PayCommonMiniAppReq generatePayCommonRequest(WxPayAccount payAccount,WxComposeOrder composeOrder,String productName, WxPayOrder record,String openId,String appId,Date currentDate) throws Exception { + PayCommonMiniAppReq req = new PayCommonMiniAppReq(); + req.setSp_appid(appId); + req.set + String noncestr = Utility.generate32UUID(); WxPayOrderP wxPayOrderP = new WxPayOrderP(); wxPayOrderP.setOpenid(openId); wxPayOrderP.setAppid(appId); @@ -66,48 +76,7 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ return wxPayOrderP; } - private PayAdapterResult getOrderPResult(Map returnMap,WxPayOrder record,WxPayAccount payAccount,String noncestr) { - PayAdapterResult par = new PayAdapterResult(); - returnMap.put("payOrderId", String.valueOf(record.getId())); - String result_code = returnMap.get("result_code"); - if ("SUCCESS".equals(result_code)) { - par.setSuccess(true); - par.setMsg("success."); - par.setData(returnMap); - String prepay_id = returnMap.get("prepay_id"); - // update payOrder with prepay_id - record.setPrepayId(prepay_id); - record.setUpdateTime(new Date()); - record.setPayOrderStatus(EnumPayStatus.PAY_STATUS_SUCCESS.getCode()); - - String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); - Map sighMap = MapUtil.getOrderMap(); - sighMap.put("appId", returnMap.get("appid")); - sighMap.put("timeStamp", timestamp); - sighMap.put("nonceStr", noncestr); - sighMap.put("package", "prepay_id=" + prepay_id); - sighMap.put("signType", "MD5"); - String signAgent = WxPayment.createSign(sighMap, payAccount.getApiKey()); - returnMap.put("timeStamp", timestamp); - returnMap.put("nonceStr", noncestr); - returnMap.put("package", "prepay_id=" + prepay_id); - returnMap.put("paySign", signAgent); - log.info("back to UI: " + returnMap.toString()); - } else { - String errMsg = ""; - record.setUpdateTime(new Date()); - - par.setSuccess(false); - par.setMsg(errMsg); - par.setData(returnMap); - } - - return par; - } - - - - private WxPayOrderSP generateWxPayOrderSP(WxPayAccount payAccount, WxComposeOrder composeOrder,String productName,WxPayOrder record,WxAppinfo appInfo,String openId,String appId,Date currentDate,EnumPayShare isShare) throws Exception { + private CombinePayCommonMiniAppReq generateCombinePayReqeust(WxPayAccount payAccount, WxComposeOrder composeOrder,String productName,WxPayOrder record,WxAppinfo appInfo,String openId,String appId,Date currentDate,EnumPayShare isShare) throws Exception { String noncestr = Utility.generate32UUID(); WxPayOrderSP wxPayOrderSP = new WxPayOrderSP(); wxPayOrderSP.setSub_openid(openId); @@ -138,41 +107,22 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ return wxPayOrderSP; } - private PayAdapterResult getOrderSPResult(Map returnMap,WxPayOrder record,WxPayAccount payAccount,WxAppinfo appInfo,String noncestr) { + private PayAdapterResult getOrderPResult(String response) { PayAdapterResult par = new PayAdapterResult(); - returnMap.put("payOrderId", String.valueOf(record.getId())); - String result_code = returnMap.get("result_code"); - if ("SUCCESS".equals(result_code)) { - par.setSuccess(true); - par.setMsg("success."); - par.setData(returnMap); - - String prepay_id = returnMap.get("prepay_id"); - // update payOrder with prepay_id - record.setPrepayId(prepay_id); - record.setUpdateTime(new Date()); - - String timestamp = String.valueOf(Utility.getCurrentTimeStamp()); - Map sighMap = MapUtil.getOrderMap(); - sighMap.put("appId", appInfo.getAppId()); - sighMap.put("timeStamp", timestamp); - sighMap.put("nonceStr", noncestr); - sighMap.put("package", "prepay_id=" + prepay_id); - sighMap.put("signType", "HMAC-SHA256"); - String signAgent = WxPayment.createSignHMAC(sighMap, payAccount.getApiKey()); - returnMap.put("timeStamp", timestamp); - returnMap.put("nonceStr", noncestr); - returnMap.put("package", "prepay_id=" + prepay_id); - returnMap.put("paySign", signAgent); - returnMap.put("signType", "HMAC-SHA256"); - log.info("back to UI: " + returnMap.toString()); - } else { - String errMsg = ""; - record.setUpdateTime(new Date()); - par.setSuccess(false); - par.setMsg(errMsg); - par.setData(returnMap); - } + if (StringUtils.isBlank(response)) { + par.setSuccess(false); + par.setMsg("pay v3 has no response."); + }else { + JSONObject result = JSON.parseObject(response); + String prepayId = result.getString("prepay_id"); + if (StringUtils.isBlank(prepayId)) { + par.setSuccess(false); + par.setMsg("pay v3 has no response."); + }else { + par.setSuccess(true); + par.setMsg("success."); + } + } return par; } @@ -193,24 +143,24 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{ if (payAccount.getType() == EnumPayMode.MCH.getCode()) { throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前商户号非服务商模式,不能使用该产品."); } + + WxPayService payService = maUtil.getWxPayService(appInfo, payAccount); + /* * 普通支付/小程序支付 * https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_2_3.shtml */ if (!EnumComposeOrder.isMulityMerchantPay(composeOrder.getComposeOrderType())) { - WxPayOrderP wxPayOrderP = generateWxPayOrderP(payAccount,composeOrder,productName,record,openId,appInfo.getAppId(),currentDate); - String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderP)); - log.info("pay order, wechat pushOrder, " + wxPayOrderP.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - return getOrderPResult(returnMap,record,payAccount,wxPayOrderP.getNonce_str()); - + PayCommonMiniAppReq payReq = generatePayCommonRequest(payAccount,composeOrder,productName,record,openId,appInfo.getAppId(),currentDate); + String response = WxPayV3.payCommonWithMiniApp(payService, payReq); + log.info("pay order v3, " + payReq.toString() + ", response: " + response.toString()); + return getOrderPResult(response); } else { //合单支付/小程序支付 - WxPayOrderSP wxPayOrderSP = generateWxPayOrderSP(payAccount,composeOrder,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare); - String response = WxPay.pushOrder(BeanUtils.toStringMap(wxPayOrderSP)); - log.info("pay order, wechat pushOrder, " + wxPayOrderSP.toString() + ", response: " + response.toString()); - Map returnMap = WxPayment.xmlToMap(response); - return getOrderSPResult(returnMap,record,payAccount,appInfo,wxPayOrderSP.getNonce_str()); + CombinePayCommonMiniAppReq payReq = generateCombinePayReqeust(payAccount,composeOrder,productName,record,appInfo,openId,appInfo.getAppId(),currentDate,isShare); + String response = WxPayV3.payCombineCommonWithMiniApp(payService, payReq); + log.info("pay order v3," + payReq.toString() + ", response: " + response.toString()); + return getOrderPResult(response); } }