Просмотр исходного кода

fix pay v3

release_toaliyun_real
lin 3 лет назад
Родитель
Сommit
c7f6f17f15
9 измененных файлов: 179 добавлений и 359 удалений
  1. +11
    -10
      mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java
  2. +12
    -2
      mallinkService/src/main/java/com/iformall/pay/WxPayV3.java
  3. +3
    -3
      mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java
  4. +4
    -4
      mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java
  5. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java
  6. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java
  7. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java
  8. +145
    -336
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java
  9. +1
    -1
      mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java

+ 11
- 10
mallinkCallback/src/main/java/com/iformall/controller/callback/WxPayController.java Просмотреть файл

@@ -197,13 +197,14 @@ public class WxPayController extends BaseController {
xml = IOUtils.toString(request.getInputStream(), Charset.forName("UTF-8"));
logger.info(xml);
paramMap = WxPayment.xmlToMap(xml);
paramMap.put("tenantId", tenantId);
String jsonMsg = JSON.toJSONString(paramMap);

FmInsideNotifyRefundSuccessMsg refundSuccessMsg = new FmInsideNotifyRefundSuccessMsg();
refundSuccessMsg.setMsgType(EnumMsgRecordType.INSIDE_NOTIFY_REFUND_SUCCESS.getCode());
refundSuccessMsg.setDelayTimeLevel(3);
refundSuccessMsg.setPayWay(EnumPayWay.PAY_WAY_WECHAT.getCode());
refundSuccessMsg.setPayVersion(EnumPayVersion.WX_PAY_V2.getCode());
refundSuccessMsg.setPayVersion(EnumPayVersion.WX_PAY_V3.getCode());
refundSuccessMsg.setJsonMsg(jsonMsg);

// response = wxRefundOrderService.notify(paramMap, EnumPayWay.PAY_WAY_WEAPP);
@@ -214,21 +215,21 @@ public class WxPayController extends BaseController {
} catch (BizMessageException e) {
logger.error("refund wxpay, notify error, req: " + xml + ", e:" + e.getLocalizedMessage());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", e.getMessage());
return XmlUtil.getRequestXml(resultMap);
resultMap.put("code", "FAIL");
resultMap.put("message", e.getMessage());
return JSON.toJSONString(resultMap);
} catch (MallinkException e) {
logger.error("refund wxpay, notify error, req: " + xml + ", e:" +e.getLocalizedMessage());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", e.getMessage());
return XmlUtil.getRequestXml(resultMap);
resultMap.put("code", "FAIL");
resultMap.put("message", e.getMessage());
return JSON.toJSONString(resultMap);
} catch (Exception e) {
logger.error("refund wxpay, order create error, req: " + xml + ", e: " + e.getMessage());
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", e.getMessage());
return XmlUtil.getRequestXml(resultMap);
resultMap.put("code", "FAIL");
resultMap.put("message", e.getMessage());
return JSON.toJSONString(resultMap);
}
}



+ 12
- 2
mallinkService/src/main/java/com/iformall/pay/WxPayV3.java Просмотреть файл

@@ -56,7 +56,10 @@ public class WxPayV3 {
//小程序下单-分账-查询
private static final String SHARE_QUERY_URL = "https://api.mch.weixin.qq.com/v3/profitsharing/orders/%s";
//小程序下单-普通支付-退款
private static final String PAY_COMMON_REFUND = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
private static final String PAY_COMMON_REFUND_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds";
//小程序下单-普通支付-退款查询
private static final String PAY_COMMON_REFUND_QUERY_URL = "https://api.mch.weixin.qq.com/v3/refund/domestic/refunds/%s";
private WxPayV3() {
@@ -197,8 +200,15 @@ public class WxPayV3 {
* @throws WxPayException
*/
public static String payCommonRefund(WxPayService payService,V3PayRefundReq req) throws WxPayException {
return payService.postV3WithWechatpaySerial(PAY_COMMON_REFUND, JSON.toJSONString(req));
return payService.postV3WithWechatpaySerial(PAY_COMMON_REFUND_URL, JSON.toJSONString(req));
}
/**
* 普通支付-退款查询 https://pay.weixin.qq.com/wiki/doc/apiv3_partner/apis/chapter4_5_10.shtml
* @throws WxPayException
*/
public static String payCommonRefundQuery(WxPayService payService,String outRefundNo) throws WxPayException {
return payService.postV3WithWechatpaySerial(String.format(PAY_COMMON_REFUND_QUERY_URL, outRefundNo), null);
}
}

+ 3
- 3
mallinkService/src/main/java/com/iformall/service/impl/WxRefundOrderServiceImpl.java Просмотреть файл

@@ -350,7 +350,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService {
throw new MallinkException(ErrorCode.DB_FAIL);
}
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType);
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder,updWxOrder.getId(), payType);
if (refundResult.isSuccess()) {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateById(record);
@@ -554,7 +554,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService {
if (null == payAccount) {
throw new MallinkException(ErrorCode.PAY_ORDER_QUERY_ERROR.getCode(), "payAccount为空[payId:"+appInfo.getPayId()+"]");
}
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, payType);
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, wxOrder.getId(),payType);
if (refundResult.isSuccess()) {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateById(record);
@@ -776,7 +776,7 @@ public class WxRefundOrderServiceImpl implements WxRefundOrderService {
logger.error("退款订单已存在, 无法再提交退款申请");
throw new MallinkException(ErrorCode.REFUND_ORDER_EXIST.getCode(), "退款订单已存在, 无法再提交退款申请");
}
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder, null);
RefundAdapterResult refundResult = payServiceFactory.getRefundPayAdapterService(payOrder.getPayVendor(),payAccount.getPayVersion()).refund(payAccount, appInfo, record, payOrder,orderId, null);
if (refundResult.isSuccess()) {
record.setRefundOrderStatus(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
wxRefundOrderMapper.updateById(record);


+ 4
- 4
mallinkService/src/main/java/com/iformall/service/pay/service/pay/wx/v3/miniApp/appPay/WxMiniAppPayV3AdapterService.java Просмотреть файл

@@ -83,7 +83,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法");
}
req.setDescription(appInfo.getName()+"-"+productName);
req.setOut_trade_no(String.valueOf(composeOrder.getMainOrderId()));
req.setOut_trade_no(record.getPayOrderNo());
req.setNotify_url(payAccount.getPayNotifyV3Url());
V3PaySettleReq settle = new V3PaySettleReq();
@@ -128,7 +128,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl
V3CombinePayCommonMiniAppReq req = new V3CombinePayCommonMiniAppReq();
req.setCombine_appid(appInfo.getAppId());
req.setCombine_mchid(payAccount.getMchId());
req.setCombine_out_trade_no(String.valueOf(composeOrder.getMainOrderId()));
req.setCombine_out_trade_no(record.getPayOrderNo());
if (payAccount.getMchType() != EnumPayMchType.TOTAL.getCode() && payAccount.getMchType() != EnumPayMchType.DIRECT.getCode()) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法");
}
@@ -238,7 +238,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl
if (!oldRecord.isMulity()) {
req.setSp_mchid(payAccount.getMchId());
req.setSub_mchid(oldRecord.getSingleChildOrderShare().getMerchantUid());
req.setOut_trade_no(String.valueOf(oldRecord.getId()));
req.setOut_trade_no(oldRecord.getPayOrderNo());
String response = WxPayV3.payCommonQuery(payService, req);
if (StringUtils.isBlank(response)){
log.error("pay common v3 query response is null."+JSON.toJSONString(req));
@@ -275,7 +275,7 @@ public class WxMiniAppPayV3AdapterService extends BaseWxPayV3AdapterService impl
SFTPayQueryReq req = new SFTPayQueryReq();
req.setSp_mchid(payAccount.getMchId());
req.setSub_mchid(record.getSingleChildOrderShare().getMerchantUid());
req.setOut_trade_no(String.valueOf(record.getId()));
req.setOut_trade_no(record.getPayOrderNo());
WxPayV3SFT.payCommonClose(payService, req);
return new PayAdapterResult(true, "close success", req, null);
}else {


+ 1
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java Просмотреть файл

@@ -22,7 +22,7 @@ public interface RefundPayAdapterService {
* @param payType
* @return
*/
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType);
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType);
/**
* API查询退款


+ 1
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java Просмотреть файл

@@ -47,7 +47,7 @@ public class TtRefundAdapterService implements RefundPayAdapterService{
WxOrderService wxOrderService;
@Override
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {

try {
TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount);


+ 1
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java Просмотреть файл

@@ -343,7 +343,7 @@ public class WxRefundAdapterService implements RefundPayAdapterService{
}
@Override
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {
if (StringUtils.isBlank(payAccount.getApiKey())) {
log.error("支付密钥为空");
throw new MallinkException(ErrorCode.API_KEY_NOT_FOUND.getCode(), "支付密钥为空,请联系商城管理员");


+ 145
- 336
mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java Просмотреть файл

@@ -1,5 +1,6 @@
package com.iformall.service.pay.service.refund.wx.v3;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
@@ -7,6 +8,7 @@ import java.util.TreeMap;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSON;
@@ -16,6 +18,7 @@ import com.iformall.common.ErrorCode;
import com.iformall.common.Result;
import com.iformall.common.ResultData;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxOrder;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
@@ -34,9 +37,14 @@ import com.iformall.pay.WxPayV3;
import com.iformall.pay.WxPayment;
import com.iformall.pay.WxRefundOrderP;
import com.iformall.pay.WxRefundOrderSP;
import com.iformall.service.WxOrderService;
import com.iformall.service.WxPayAccountService;
import com.iformall.service.order.entity.WxComposeChildOrderShare;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
import com.iformall.service.pay.service.refund.entity.RefundNotifyAdapterResult;
import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundAmountReq;
import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundGoodsReq;
import com.iformall.service.pay.service.refund.wx.v3.entity.V3PayRefundReq;
import com.iformall.utils.BeanUtils;
import com.iformall.utils.CipherUtil;
@@ -54,206 +62,100 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{
@Autowired
MaUtil maUtil;
private RefundAdapterResult getReusltFromp(String response,WxRefundOrder record,WxPayOrder payOrder) throws MallinkException{
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
record.setRefundVendor(payOrder.getPayVendor());
if ("SUCCESS".equals(result_no)) {
log.info("微信退款订单申请成功: " + returnMap.toString());
try {
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap);
} catch (Exception e) {
log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}
} else {
String errDesc = returnMap.get("err_code_des");
if (errDesc.equalsIgnoreCase("订单已全额退款")) {
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款订单申请成功",returnMap);
}
log.error("微信退款订单申请失败: " + response);
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("return_msg");
record.setFailReason(errMsg);
}
if (errDesc.equalsIgnoreCase("超期订单不允许退款")) {
// 更新券状态
throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW);
}
return new RefundAdapterResult(false, EnumRefundStatus.REFUND_REQ_FAIL.getCode(), errMsg, returnMap);
}
}
private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) {
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String result_no = returnMap.get("result_code");
String refund_id = returnMap.get("refund_id");
// 设置 微信退款订单号
record.setRefundId(refund_id);
record.setRefundVendor(payOrder.getPayVendor());
if ("SUCCESS".equals(result_no)) {
log.info("微信退款订单申请成功: " + returnMap.toString());
try {
return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap);
} catch (Exception e) {
log.error("微信退款订单更新入库出错: " + e.getMessage() + ", record: " + record.toString());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "订单状态更新失败");
}
} else {
// 特殊处理
String errDesc = returnMap.get("err_code_des");
if (errDesc.equalsIgnoreCase("订单已全额退款")) {
return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单申请成功", returnMap);
}
log.error("微信退款订单申请失败: " + response);
String errMsg = "";
JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
if (errObj != null) {
errMsg = errObj.toJSONString();
record.setFailReason(errMsg);
} else {
errMsg = returnMap.get("err_code_des");
record.setFailReason(errMsg);
}
if (errDesc.equalsIgnoreCase("超期订单不允许退款")) {
// 更新券状态
throw new MallinkException(ErrorCode.REFUND_NOT_ALLOW);
}
return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),errMsg,returnMap);
}
}
private V3PayRefundReq getReq(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
@Lazy
@Autowired
WxOrderService wxOrderService;
@Lazy
@Autowired
WxPayAccountService wxPayAccountService;
private V3PayRefundReq getReq(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {
V3PayRefundReq req = new V3PayRefundReq();
if (payAccount.getMchType() == EnumPayMchType.DIRECT.getCode()) {
req.setSub_mchid(getMerchantUid(record,composeOrder.getSingleOrder()));
WxComposeChildOrderShare share = payOrder.getChildOrderShare(orderId);
req.setSub_mchid(share.getMerchantUid());
//总分
}else if (payAccount.getMchType() == EnumPayMchType.TOTAL.getCode()) {
req.setSub_mchid(payAccount.getSubMchId());
}else {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(),"当前支付模式非法");
}
req.setSub_mchid(sub_mchid);
req.setOut_trade_no(payOrder.getPayOrderNo());
req.setOut_refund_no(String.valueOf(record.getId()));
req.setReason(payType.getMessage());
req.setNotify_url(payAccount.getRefundNotifyV3Url());
V3PayRefundAmountReq amount = new V3PayRefundAmountReq();
amount.setRefund(record.getRefundFee());
amount.setTotal(record.getTotalFee());
req.setAmount(amount);
List<V3PayRefundGoodsReq> goods = new ArrayList<V3PayRefundGoodsReq>();
WxOrder order = wxOrderService.getById(orderId, payAccount.getTenantId());
V3PayRefundGoodsReq gr = new V3PayRefundGoodsReq();
gr.setGoods_name("商品"+order.getProductId());
gr.setMerchant_goods_id(order.getProductId().toString());
gr.setRefund_amount(record.getRefundFee());
gr.setRefund_quantity(order.getCouponNumber());
goods.add(gr);
req.setGoods_detail(goods);
return req;
}
private RefundAdapterResult getResultFromSp(String response,WxRefundOrder record,WxPayOrder payOrder) {
JSONObject result = JSON.parseObject(response);
// 设置 微信退款订单号
record.setRefundId(result.getString("refund_id"));
record.setRefundVendor(payOrder.getPayVendor());
return new RefundAdapterResult(true, EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(), "退款订单成功", result);
}
@Override
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,EnumPayType payType) {
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {
// 向微信提交退款申请
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
} else {
// 服务商模式
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
String response = null;
try {
response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder, payType));
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
log.info("微信退款订单:" + wxRefundOrderSP.toString() + ", response: " + response.toString());
return getResultFromSp(response, record, payOrder);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "当前只支持服务商模式");
}
// 服务商模式
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
String response = null;
try {
//合单和普通一样
if (!payOrder.isMulity()) {
response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder,orderId, payType));
}else {
response = WxPayV3.payCommonRefund(payService, getReq(payAccount, appInfo, record, payOrder,orderId, payType));
}
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
return getResultFromSp(response, record, payOrder);
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
Map<String, String> paramMap = WxPayment.buildWeappRefundQueryMap(
appInfo.getAppId(), payAccount.getMchId(),
record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()),
record.getRefundId(), payAccount.getApiKey());
String response = WxPay.orderRefundQuery(paramMap);
log.info("微信退款订单:" + record.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String return_code = returnMap.get("return_code");
if("SUCCESS".equals(return_code)){
String result_code = returnMap.get("result_code");
if("SUCCESS".equals(result_code)){
String refund_status_0 = returnMap.get("refund_status_0");
if("SUCCESS".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap);
}else if("REFUNDCLOSE".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap);
}else if("PROCESSING".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap);
}else if("CHANGE".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),
"退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",returnMap);
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态");
}
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des"));
}
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg"));
}

// String result_no = returnMap.get("result_code");
// if ("SUCCESS".equals(result_no)) {
// String refund_id = returnMap.get("refund_id");
// return new RefundAdapterResult(true,0,"退款",returnMap);
// } else {
// String errMsg = "";
// JSONObject errObj = errorRefundReqMap.getJSONObject(result_no);
// if (errObj != null) {
// errMsg = errObj.toJSONString();
// } else {
// errMsg = returnMap.get("return_msg");
// }
// return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap);
// }
} else {
Map<String, String> paramMap = WxPayment.buildSWeappRefundQueryMap(
appInfo.getParentAppId(), appInfo.getAppId(), payAccount.getMchId(), payAccount.getSubMchId(),
record.getTransactionId(), record.getPayOrderNo(), String.valueOf(record.getId()), record.getRefundId(), payAccount.getApiKey());
String response = WxPay.orderRefundQuery(paramMap);
log.info("微信退款订单:" + record.toString() + ", response: " + response.toString());
Map<String, String> returnMap = WxPayment.xmlToMap(response);
String return_code = returnMap.get("return_code");
if("SUCCESS".equals(return_code)){
String result_code = returnMap.get("result_code");
if("SUCCESS".equals(result_code)){
String refund_status_0 = returnMap.get("refund_status_0");
if("SUCCESS".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",returnMap);
}else if("REFUNDCLOSE".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",returnMap);
}else if("PROCESSING".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",returnMap);
}else if("CHANGE".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款异常",returnMap);
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态");
}
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("err_code_des"));
}
// 服务商模式
WxPayService payService = maUtil.getWxPayService(appInfo, payAccount);
String response = null;
try {
response = WxPayV3.payCommonRefundQuery(payService, String.valueOf(record.getId()));
JSONObject result = JSON.parseObject(response);
String refund_status_0 = result.getString("status");
if("SUCCESS".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_SUCCESS.getCode(),"退款成功",result);
}else if("CLOSED".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",result);
}else if("PROCESSING".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",result);
}else if("ABNORMAL".equals(refund_status_0)){
return new RefundAdapterResult(true,EnumRefundStatus.REFUND_FAIL.getCode(),
"退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",result);
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 "+returnMap.get("return_msg"));
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态");
}
// String result_no = returnMap.get("result_code");
// if ("SUCCESS".equals(result_no)) {
// String refund_id = returnMap.get("refund_id");
// return new RefundAdapterResult(true,0,"退款",returnMap);
// } else {
// String errMsg = "";
// JSONObject errObj = errorRefundQueryMap.getJSONObject(result_no);
// if (errObj != null) {
// errMsg = errObj.toJSONString();
// } else {
// errMsg = returnMap.get("return_msg");
// }
// return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),errMsg,returnMap);
// }
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
}

@@ -269,171 +171,78 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{
private RefundNotifyAdapterResult notifyErrorResult(String msg) {
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "FAIL");
resultMap.put("return_msg", msg);
return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,XmlUtil.getRequestXml(resultMap));
resultMap.put("code", "FAIL");
resultMap.put("message", msg);
return new RefundNotifyAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),msg,JSON.toJSONString(resultMap));
}
private RefundNotifyAdapterResult notifySuccessResult(String transactionId,String refundId,WxRefundOrder refundOrder) {
SortedMap resultMap = new TreeMap();
resultMap.put("return_code", "SUCCESS");
resultMap.put("return_msg", "OK");
return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,XmlUtil.getRequestXml(resultMap));
resultMap.put("code", "SUCCESS");
resultMap.put("message", "OK");
return new RefundNotifyAdapterResult(transactionId, refundId,refundOrder,JSON.toJSONString(resultMap));
}
@Override
public RefundNotifyAdapterResult notify(Map<String, String> paramMap, EnumPayWay payWay) {
// how to get wechatAppId, wechatMchId, partnerKey
String appId = paramMap.get("appid");
String subAppId = paramMap.get("sub_appid");
String mchId = paramMap.get("mch_id");
String subMchId = paramMap.get("sub_mch_id");
if (StringUtils.isBlank(subAppId) && StringUtils.isBlank(subMchId)) {
// 普通商户号
WxAppinfo appinfo = wxAppinfoMapper.findByAppId(appId);
if (appinfo == null) {
log.error("未找到appid信息:" + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
log.error("未找到mch_id信息:" + mchId);
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
if (!mchId.equalsIgnoreCase(payAccount.getMchId())) {
log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId());
throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) {
if (!"SUCCESS".equals(paramMap.get("return_code"))) {
log.warn("notify refund, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单状态码非SUCCESS");
}

// 解密req_info
String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey);
Map<String, String> reqMap = WxPayment.xmlToMap(req_info);

String payOrderNo = reqMap.get("out_trade_no");
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId());
if (payOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单总金额不一致");
}
String refundIdStr = reqMap.get("out_refund_no");
Long refundOrderId = Long.valueOf(refundIdStr);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);
if (refundOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单总金额不一致");
}
// 验证退款金额
if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) {
log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款总金额不一致");
}
// 处理支付成功
//handleRefundSuccess(refundOrder, reqMap.get("transaction_id"), reqMap.get("refund_id"));
log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder);
}
} catch (RuntimeException e) {
log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
} catch (Exception e) {
log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
}
} else {
// 服务号回调
WxAppinfo appinfo = wxAppinfoMapper.findByAppId(subAppId);
if (appinfo == null) {
log.error("未找到appid信息:" + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
WxPayAccount payAccount = wxPayAccountMapper.selectById(appinfo.getPayId());
if (payAccount == null) {
log.error("未找到mch_id信息:" + mchId);
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
if (!mchId.equalsIgnoreCase(payAccount.getMchId())) {
log.error("mch_id不对应:" + mchId + ",account:" + payAccount.getMchId());
throw new MallinkException(ErrorCode.MCH_INFO_NOT_EQUAL);
}
String partnerKey = payAccount.getApiKey();
try {
if (payWay.getType() == EnumPayWay.EnumPayWayType.WX_MINIPAY) {
if (!"SUCCESS".equals(paramMap.get("return_code"))) {
log.warn("notify order, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单状态码非SUCCESS");
}

// 解密req_info
String req_info = CipherUtil.decryptReqInfo(paramMap.get("req_info"), partnerKey);
log.info(req_info);
Map<String, String> reqMap = WxPayment.xmlToMap(req_info);

String payOrderNo = reqMap.get("out_trade_no");
if (payOrderNo == null) {
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), null);
}
Long payOrderId = Long.valueOf(payOrderNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,payAccount.getTenantId());
if (payOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(payOrder.getPayAmount().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单总金额不一致");
}
String refundIdStr = reqMap.get("out_refund_no");
Long refundOrderId = Long.valueOf(refundIdStr);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);
if (refundOrder == null) {
log.warn("notify refund, wxpay check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款订单不存在");
}
// 验证支付金额
if (!reqMap.get("total_fee").equals(refundOrder.getTotalFee().toString())) {
log.warn("notify refund, wxpay check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单总金额不一致");
}
// 验证退款金额
if (!reqMap.get("refund_fee").equals(refundOrder.getRefundFee().toString())) {
log.warn("notify refund, wxpay check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款总金额不一致");
}

log.info("notify refund, wxpay checksign success, paramMap:{}, paramMap: " + reqMap.toString() + ", payWay:" + payWay.toString());
return notifySuccessResult(reqMap.get("transaction_id"), reqMap.get("refund_id"), refundOrder);
}
} catch (RuntimeException e) {
log.warn("notify refund, wepay checksign error, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
} catch (Exception e) {
log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
}
String tenantId = paramMap.get("tenantId");
String resource = paramMap.get("resource");
JSONObject reObj = JSON.parseObject(resource);
WxPayService wxPayService = wxPayAccountService.getWxPayService(tenantId);
try {
String decryptContent = WxPayV3.decrypt(wxPayService, reObj.getString("ciphertext"), reObj.getString("nonce"), reObj.getString("associated_data"));
JSONObject decryptObj = JSON.parseObject(decryptContent);
String spMchId = decryptObj.getString("sp_mchid");
String subMchId = decryptObj.getString("sub_mchid");
String transactionId = decryptObj.getString("transaction_id");
String outTradeNo = decryptObj.getString("out_trade_no");
String refundId = decryptObj.getString("refund_id");
String outRefundNo = decryptObj.getString("out_refund_no");
String refundStatus = decryptObj.getString("refund_status");
String successTime = decryptObj.getString("success_time");
String userReceivedAccount = decryptObj.getString("user_received_account");
JSONObject rObj = decryptObj.getJSONObject("amount");
int total = rObj.getIntValue("total");
int refund = rObj.getIntValue("refund");
int payerTotal = rObj.getIntValue("payer_total");
int payerRefund = rObj.getIntValue("payer_refund");

Long payOrderId = Long.valueOf(outTradeNo);
WxPayOrder payOrder = wxPayOrderMapper.selectById(payOrderId,tenantId);
if (payOrder == null) {
log.warn("notify refund, wxpay v3 check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单不存在");
}
// 验证支付金额
if (payerTotal != payOrder.getPayAmount().intValue()) {
log.warn("notify refund, wxpay v3 check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("支付订单总金额不一致");
}
Long refundOrderId = Long.valueOf(outRefundNo);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);
if (refundOrder == null) {
log.warn("notify refund, wxpay v3 check pay order not exists, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款订单不存在");
}
// 验证支付金额
if (payerTotal != refundOrder.getTotalFee().intValue()) {
log.warn("notify refund, wxpay v3 check total_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单总金额不一致");
}
// 验证退款金额
if (payerRefund != refundOrder.getRefundFee().intValue()) {
log.warn("notify refund, wxpay v3 check refund_fee is invalid, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("退款总金额不一致");
}
return notifySuccessResult(transactionId, refundId, refundOrder);
} catch (RuntimeException e) {
log.warn("notify refund paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
} catch (Exception e) {
log.warn("notify refund, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString() + ", e:" + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getMessage());
}

return notifyErrorResult("FAILED");
}

}

+ 1
- 1
mallinkService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/entity/V3PayRefundReq.java Просмотреть файл

@@ -8,7 +8,7 @@ import lombok.Data;
public class V3PayRefundReq {

private String sub_mchid;//微信支付分配的子商户号,即分账的出资商户号。
private String out_trade_no;//微信支付订单号
private String out_trade_no;//原支付交易对应的商户订单号
private String out_refund_no;//商户退款单号
private String reason;//退款原因
private String notify_url;//退款结果回调url


Загрузка…
Отмена
Сохранить