Przeglądaj źródła

fix pay v3

release_toaliyun_real
zhengfangyuan 3 lat temu
rodzic
commit
9d4d2779b2
6 zmienionych plików z 99 dodań i 91 usunięć
  1. +10
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumComposeOrder.java
  2. +0
    -49
      mallinkService/src/main/java/com/iformall/pay/WxPay.java
  3. +70
    -0
      mallinkService/src/main/java/com/iformall/pay/WxPayV3.java
  4. +3
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutAdapterService.java
  5. +3
    -2
      mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/WxCashOutV3AdapterService.java
  6. +13
    -38
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java

+ 10
- 0
mallinkService/src/main/java/com/iformall/enums/EnumComposeOrder.java Wyświetl plik

@@ -47,6 +47,16 @@ public enum EnumComposeOrder {
}
}
//支付时是否是多个商家的
public static boolean isMulityMerchantPay(Integer type) {
if (type.intValue() == ONE_NUMBER_ORDER_BATCH.getCode().intValue() ||
type.intValue() == MULITY_NUMBER_ORDER_BATCH.getCode().intValue()) {
return true;
}else {
return false;
}
}
//子订单是单个还是一起,购物车的子订单是单个,可以单个支付,券包的子订单不能单个支付
// public static boolean childOrderIsSingle(Integer type) {
// if (type.intValue() == SINGLE.getCode().intValue() || type.intValue() == ONE_NUMBER_ORDER_BATCH.getCode().intValue()


+ 0
- 49
mallinkService/src/main/java/com/iformall/pay/WxPay.java Wyświetl plik

@@ -47,11 +47,6 @@ 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";
// 查询代金券信息
@@ -255,50 +250,6 @@ public class WxPay {
return WxPay.doPostSSL(GETTRANSFERINFO_URL, params, certPath, certPassword);
}
/**
* 商家转账到零钱 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter4_3_1.shtml
* 注意:1. 需要登录到特约商户号自己的商户后台,产品中心---APPID账号管理----我关联的appId账号,把C端小程序关联
* 2. 需要设置白名单IP
* 3.微信不能开通运营账户,如果运营账户开通,则资金会从运营账户里面扣取,不会从基本账户扣取
* @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<WxCashOutPV3Item> 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));
}

/**
* 商户模式下 扫码模式一之生成二维码
*


+ 70
- 0
mallinkService/src/main/java/com/iformall/pay/WxPayV3.java Wyświetl plik

@@ -0,0 +1,70 @@
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.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.github.binarywang.wxpay.v3.util.RsaCryptoUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class WxPayV3 {
protected static Logger log = LoggerFactory.getLogger(WxPayV3.class);

//商家转账到零钱
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 WxPayV3() {
}

/**
* 商家转账到零钱 https://pay.weixin.qq.com/wiki/doc/apiv3/open/pay/chapter4_3_1.shtml
* 注意:1. 需要登录到特约商户号自己的商户后台,产品中心---APPID账号管理----我关联的appId账号,把C端小程序关联
* 2. 需要设置白名单IP
* 3.微信不能开通运营账户,如果运营账户开通,则资金会从运营账户里面扣取,不会从基本账户扣取
* @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<WxCashOutPV3Item> 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));
}
}

+ 3
- 2
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v2/WxCashOutAdapterService.java Wyświetl plik

@@ -39,6 +39,7 @@ import com.iformall.pay.WxCashOutPV3;
import com.iformall.pay.WxCashOutPV3Item;
import com.iformall.pay.WxCashOutQueryP;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayV3;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxRefundOrderP;
import com.iformall.pay.WxRefundOrderSP;
@@ -221,7 +222,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{
}
String response = null;
try {
response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut));
response = WxPayV3.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut));
} catch (Exception e) {
log.error("零钱支付异常: " + e.getMessage(),e);
return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常:"+e.getMessage(), null);
@@ -292,7 +293,7 @@ public class WxCashOutAdapterService implements CashOutAdapterService{
}
String response = null;
try {
response = WxPay.merchantTransferInfo(String.valueOf(cashOut.getId()), payService);
response = WxPayV3.merchantTransferInfo(String.valueOf(cashOut.getId()), payService);
} catch (Exception e) {
log.error("零钱支付查询异常: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage());


+ 3
- 2
mallinkService/src/main/java/com/iformall/service/pay/service/cashout/wx/v3/WxCashOutV3AdapterService.java Wyświetl plik

@@ -39,6 +39,7 @@ import com.iformall.pay.WxCashOutPV3;
import com.iformall.pay.WxCashOutPV3Item;
import com.iformall.pay.WxCashOutQueryP;
import com.iformall.pay.WxPay;
import com.iformall.pay.WxPayV3;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxRefundOrderP;
import com.iformall.pay.WxRefundOrderSP;
@@ -221,7 +222,7 @@ public class WxCashOutV3AdapterService implements CashOutAdapterService{
}
String response = null;
try {
response = WxPay.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut));
response = WxPayV3.merchantTranferChange(payService,generateWxCashOutPV3(payAccount, appInfo, cashOut));
} catch (Exception e) {
log.error("零钱支付异常: " + e.getMessage(),e);
return new CashOutAdapterResult(false, EnumCashOutStatus.FAIL.getCode(), "微信零钱支付接口调用异常:"+e.getMessage(), null);
@@ -292,7 +293,7 @@ public class WxCashOutV3AdapterService implements CashOutAdapterService{
}
String response = null;
try {
response = WxPay.merchantTransferInfo(String.valueOf(cashOut.getId()), payService);
response = WxPayV3.merchantTransferInfo(String.valueOf(cashOut.getId()), payService);
} catch (Exception e) {
log.error("零钱支付查询异常: " + e.getMessage(),e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "微信零钱支付查询接口异常:"+e.getMessage());


+ 13
- 38
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java Wyświetl plik

@@ -14,6 +14,7 @@ import com.alibaba.fastjson.JSONObject;
import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.enums.EnumComposeOrder;
import com.iformall.enums.EnumOrderStatus;
import com.iformall.enums.EnumPayMode;
import com.iformall.enums.EnumPayShare;
@@ -40,24 +41,6 @@ import lombok.extern.slf4j.Slf4j;
public class WxMiniAppPayV3AdapterService implements CDrivingPayService{

JSONObject errorMap = JSON.parseObject("{" +
"\"NOAUTH\":{\"detail\":\"商户无此接口权限\",\"reason\":\"商户未开通此接口权限\",\"resolution\":\"请商户前往申请此接口权限\"}," +
"\"NOTENOUGH\":{\"detail\":\"余额不足\",\"reason\":\"用户帐号余额不足\",\"resolution\":\"用户帐号余额不足,请用户充值或更换支付卡后再支付\"}," +
"\"ORDERPAID\":{\"detail\":\"商户订单已支付\",\"reason\":\"商户订单已支付,无需重复操作\",\"resolution\":\"商户订单已支付,无需更多操作\"}," +
"\"ORDERCLOSED\":{\"detail\":\"订单已关闭\",\"reason\":\"当前订单已关闭,无法支付\",\"resolution\":\"当前订单已关闭,请重新下单\"}," +
"\"SYSTEMERROR\":{\"detail\":\"系统错误\t\",\"reason\":\"系统超时\",\"resolution\":\"系统异常,请用相同参数重新调用\"}," +
"\"APPID_NOT_EXIST\":{\"detail\":\"APPID不存在\",\"reason\":\"参数中缺少APPID\",\"resolution\":\"请检查APPID是否正确\"}," +
"\"MCHID_NOT_EXIST\":{\"detail\":\"MCHID不存在\",\"reason\":\"参数中缺少MCHID\",\"resolution\":\"请检查MCHID是否正确\"}," +
"\"APPID_MCHID_NOT_MATCH\":{\"detail\":\"appid和mch_id不匹配\",\"reason\":\"appid和mch_id不匹配\",\"resolution\":\"请确认appid和mch_id是否匹配\"}," +
"\"LACK_PARAMS\":{\"detail\":\"缺少参数\t\",\"reason\":\"缺少必要的请求参数\",\"resolution\":\"请检查参数是否齐全\"}," +
"\"OUT_TRADE_NO_USED\":{\"detail\":\"商户订单号重复\",\"reason\":\"同一笔交易不能多次提交\",\"resolution\":\"请核实商户订单号是否重复提交\"}," +
"\"SIGNERROR\":{\"detail\":\"签名错误\",\"reason\":\"参数签名结果不正确\",\"resolution\":\"请检查签名参数和方法是否都符合签名算法要求\"}," +
"\"XML_FORMAT_ERROR\":{\"detail\":\"XML格式错误\t\",\"reason\":\"XML格式错误\",\"resolution\":\"请检查XML参数格式是否正确\"}," +
"\"REQUIRE_POST_METHOD\":{\"detail\":\"请使用post方法\",\"reason\":\"未使用post传递参数\",\"resolution\":\"请检查请求参数是否通过post方法提交\"}," +
"\"POST_DATA_EMPTY\":{\"detail\":\"post数据为空\",\"reason\":\"post数据不能为空\",\"resolution\":\"请检查post数据是否为空\"}," +
"\"NOT_UTF8\":{\"detail\":\"编码格式错误\",\"reason\":\"未使用指定编码格式\",\"resolution\":\"请使用UTF-8编码格式\"}}");
private WxPayOrderP generateWxPayOrderP(WxPayAccount payAccount,WxComposeOrder composeOrder,String productName, WxPayOrder record,String openId,String appId,Date currentDate) throws Exception {
// 统一下单 普通商户模式
String noncestr = Utility.generate32UUID();
@@ -112,14 +95,6 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{
log.info("back to UI: " + returnMap.toString());
} else {
String errMsg = "";
JSONObject errObj = errorMap.getJSONObject(result_code);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("return_msg");
record.setFailReason(errMsg);
}
record.setUpdateTime(new Date());
par.setSuccess(false);
@@ -193,14 +168,6 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{
log.info("back to UI: " + returnMap.toString());
} else {
String errMsg = "";
JSONObject errObj = errorMap.getJSONObject(result_code);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("return_msg");
record.setFailReason(errMsg);
}
record.setUpdateTime(new Date());
par.setSuccess(false);
par.setMsg(errMsg);
@@ -210,7 +177,8 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{
}
/**
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter7_8_2.shtml
* 电商收付通
* https://pay.weixin.qq.com/wiki/doc/apiv3_partner/open/pay/chapter3_3_0.shtml
*/
@Override
public PayAdapterResult pay(WxPayAccount payAccount, WxPayOrder record,WxComposeOrder composeOrder,String productName,EnumPayShare isShare,WxAppinfo appInfo,Date currentDate, PayExtraParam params) throws Exception {
@@ -221,8 +189,15 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{
if (StringUtils.isBlank(openId) ) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"openId为空");
}
//普通商户模式
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前商户号非服务商模式,不能使用该产品.");
}
/*
* 普通支付/小程序支付
* 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());
@@ -230,7 +205,7 @@ public class WxMiniAppPayV3AdapterService implements CDrivingPayService{
return getOrderPResult(returnMap,record,payAccount,wxPayOrderP.getNonce_str());
} 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());


Ładowanie…
Anuluj
Zapisz