xhxu před 1 rokem
rodič
revize
585bba8f43
15 změnil soubory, kde provedl 808 přidání a 40 odebrání
  1. +84
    -0
      suimangService/src/main/java/com/iformall/domain/po/ProductOrderRefund.java
  2. +39
    -0
      suimangService/src/main/java/com/iformall/enums/EnumRefundOrderStatus.java
  3. +15
    -0
      suimangService/src/main/java/com/iformall/mapper/ProductOrderRefundMapper.java
  4. +31
    -0
      suimangService/src/main/java/com/iformall/service/ProductOrderRefundService.java
  5. +5
    -2
      suimangService/src/main/java/com/iformall/service/impl/ProductOrderPayServiceImpl.java
  6. +122
    -0
      suimangService/src/main/java/com/iformall/service/impl/ProductOrderRefundServiceImpl.java
  7. +24
    -0
      suimangService/src/main/java/com/iformall/service/pay/PayServiceFactory.java
  8. +5
    -4
      suimangService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java
  9. +199
    -0
      suimangService/src/main/java/com/iformall/service/pay/service/refund/ali/AliRefundAdapterService.java
  10. +43
    -13
      suimangService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java
  11. +8
    -0
      suimangService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundAdapterResult.java
  12. +13
    -6
      suimangService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java
  13. +73
    -14
      suimangService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java
  14. +1
    -1
      suimangService/src/main/resources/mapper/ProductOrderPayMapper.xml
  15. +146
    -0
      suimangService/src/main/resources/mapper/ProductOrderRefundMapper.xml

+ 84
- 0
suimangService/src/main/java/com/iformall/domain/po/ProductOrderRefund.java Zobrazit soubor

@@ -0,0 +1,84 @@
package com.iformall.domain.po;

import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableName;
import com.iformall.domain.po.base.TenantEntity;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

import java.math.BigDecimal;
import java.util.Date;

@TableName(value = "product_order_refund")
@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
public class ProductOrderRefund extends TenantEntity {

protected Long id;

@io.swagger.annotations.ApiModelProperty(value="系统订单号",name="orderId")
private Long orderId;
@io.swagger.annotations.ApiModelProperty(value="系统订单号",name="orderNumber")
private String orderNumber;

@io.swagger.annotations.ApiModelProperty(value="EnumProject",name="projectType")
private Integer projectType;
@io.swagger.annotations.ApiModelProperty(value = "EnumProductOrderPayVendor", name = "payVendor")
private Integer payVendor;

@io.swagger.annotations.ApiModelProperty(value="用户id",name="userId")
private Long userId;

@io.swagger.annotations.ApiModelProperty(value="支付id",name="payId")
private Long payId;

@io.swagger.annotations.ApiModelProperty(value="第三方订单号",name="transactionId")
private String transactionId;

@io.swagger.annotations.ApiModelProperty(value="订单金额(分)",name="payAmount")
private Integer payAmount;

@io.swagger.annotations.ApiModelProperty(value="退款金额(分)",name="refundAmount")
private Integer refundAmount;

@io.swagger.annotations.ApiModelProperty(value="EnumRefundOrderStatus",name="refundOrderStatus")
private Integer refundOrderStatus;

@io.swagger.annotations.ApiModelProperty(value="失败原因",name="failReason")
private String failReason;

@io.swagger.annotations.ApiModelProperty(value="",name="refundId")
private String refundId;

@io.swagger.annotations.ApiModelProperty(value="退款原因",name="refundReason")
private String refundReason;

@io.swagger.annotations.ApiModelProperty(value="退款补充原因",name="refundDescription")
private String refundDescription;

@io.swagger.annotations.ApiModelProperty(value="创建时间",name="createDate")
private Date createDate;
@io.swagger.annotations.ApiModelProperty(value="更新时间",name="updateDate")
private Date updateDate;

@TableField(exist = false)
private String payAmountStr;
public String getPayAmountStr() {
return payAmount != null ? new BigDecimal(payAmount).divide(new BigDecimal(100)).toPlainString() : payAmountStr;
}

@TableField(exist = false)
private String refundAmountStr;
public String getRefundAmountStr() {
return refundAmount != null ? new BigDecimal(refundAmount).divide(new BigDecimal(100)).toPlainString() : refundAmountStr;
}

@TableField(exist = false)
private Date startDate;

@TableField(exist = false)
private Date endDate;

}

+ 39
- 0
suimangService/src/main/java/com/iformall/enums/EnumRefundOrderStatus.java Zobrazit soubor

@@ -0,0 +1,39 @@
package com.iformall.enums;

/**
*
*/
public enum EnumRefundOrderStatus {
REFUND_WAIT(0, "退款中"),
REFUND_REQ_SUCCESS(1, "退款申请成功"),
REFUND_REQ_FAIL(2, "退款申请失败"),
REFUND_REQ_AGREE(3, "同意退款"),
REFUND_SUCCESS(4, "退款成功"),
REFUND_FAIL(5, "退款失败"),
;

public static EnumRefundOrderStatus getEnum(Integer code) {
for (EnumRefundOrderStatus value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumRefundOrderStatus(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 15
- 0
suimangService/src/main/java/com/iformall/mapper/ProductOrderRefundMapper.java Zobrazit soubor

@@ -0,0 +1,15 @@
package com.iformall.mapper;

import com.iformall.common.CommonMapper;
import com.iformall.domain.po.ProductOrderPay;
import com.iformall.domain.po.ProductOrderRefund;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface ProductOrderRefundMapper extends CommonMapper<ProductOrderRefund, Long> {
List<ProductOrderRefund> findList(ProductOrderRefund record);

int orderRefundUpdStatus(ProductOrderRefund record);
}

+ 31
- 0
suimangService/src/main/java/com/iformall/service/ProductOrderRefundService.java Zobrazit soubor

@@ -0,0 +1,31 @@
package com.iformall.service;

import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.ProductOrderPay;
import com.iformall.domain.po.ProductOrderRefund;
import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.enums.EnumProductOrderPayVendor;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;

public interface ProductOrderRefundService {

/**
* 根据实体查询分页列表
*
* @param record
* @param pageIndex
* @param pageSize
* @return
*/
PageInfo<ProductOrderRefund> listAsPage(ProductOrderRefund record, Integer pageIndex, Integer pageSize);

void saveOrUpdate(ProductOrderRefund record);

ProductOrderRefund getById(Long id);

void handleRefund(ProductOrderPay orderPay);

}

+ 5
- 2
suimangService/src/main/java/com/iformall/service/impl/ProductOrderPayServiceImpl.java Zobrazit soubor

@@ -17,6 +17,7 @@ import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.utils.DateUtils;
import com.iformall.utils.RedisLock;
import lombok.extern.slf4j.Slf4j;
@@ -58,6 +59,9 @@ public class ProductOrderPayServiceImpl implements ProductOrderPayService {
@Autowired
WxPayAccountService wxPayAccountService;

@Autowired
ProductOrderRefundService productOrderRefundService;

@Autowired
PayServiceFactory payServiceFactory;

@@ -246,8 +250,7 @@ public class ProductOrderPayServiceImpl implements ProductOrderPayService {

if(EnumPayOrderStatus.ORDER_STATUS_REFUND_WAIT.getCode().equals(productOrderPay.getPayOrderStatus())){
logger.info("当前订单异常支付,退款处理");
//todo 退款

productOrderRefundService.handleRefund(productOrderPay);
return;
}



+ 122
- 0
suimangService/src/main/java/com/iformall/service/impl/ProductOrderRefundServiceImpl.java Zobrazit soubor

@@ -0,0 +1,122 @@
package com.iformall.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.iformall.common.ErrorCode;
import com.iformall.common.IdWorker;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.enums.*;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.*;
import com.iformall.service.*;
import com.iformall.service.pay.PayServiceFactory;
import com.iformall.service.pay.service.pay.PayAdapterService;
import com.iformall.service.pay.service.pay.entity.PayAdapterResult;
import com.iformall.service.pay.service.pay.entity.PayQueryAdapterResult;
import com.iformall.service.pay.service.refund.RefundPayAdapterService;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
import com.iformall.utils.RedisLock;
import lombok.extern.slf4j.Slf4j;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

@Service
@Slf4j
public class ProductOrderRefundServiceImpl implements ProductOrderRefundService {

private final Logger logger = LoggerFactory.getLogger(this.getClass());

@Autowired
ProductOrderRefundMapper productOrderRefundMapper;

@Autowired
ProductOrderPayMapper productOrderPayMapper;

@Autowired
PayServiceFactory payServiceFactory;

@Autowired
WxAppinfoService wxAppinfoService;

@Autowired
WxPayAccountService wxPayAccountService;

@Override
public PageInfo<ProductOrderRefund> listAsPage(ProductOrderRefund record, Integer pageIndex, Integer pageSize) {
return PageHelper.startPage(pageIndex, pageSize).doSelectPageInfo(() -> productOrderRefundMapper.findList(record));
}

@Override
public void saveOrUpdate(ProductOrderRefund record) {
Date now = new Date();
if (record.getId() == null) {
final IdWorker idWorker = IdWorker.get();
record.setId(idWorker.nextId());
record.setCreateDate(now);
record.setUpdateDate(now);
productOrderRefundMapper.insert(record);
} else {
record.setUpdateDate(now);
productOrderRefundMapper.updateById(record);
}
}

@Override
public ProductOrderRefund getById(Long id) {
return productOrderRefundMapper.selectById(id);
}

@Override
public void handleRefund(ProductOrderPay orderPay) {
String refundReason = "重复支付退款";

Date now = new Date();
ProductOrderRefund record = new ProductOrderRefund();
final IdWorker idWorker = IdWorker.get();
record.setId(idWorker.nextId());
record.setOrderId(orderPay.getOrderId());
record.setOrderNumber(orderPay.getOrderNumber());
record.setProjectType(orderPay.getProjectType());
record.setPayVendor(orderPay.getPayVendor());
record.setUserId(orderPay.getUserId());
record.setPayId(orderPay.getId());
record.setTransactionId(orderPay.getTransactionId());
record.setPayAmount(orderPay.getPayAmount());
record.setRefundAmount(orderPay.getPayAmount());
record.setRefundOrderStatus(EnumRefundOrderStatus.REFUND_WAIT.getCode());
record.setRefundReason(refundReason);
record.setCreateDate(now);
record.setUpdateDate(now);
productOrderRefundMapper.insert(record);

RefundPayAdapterService refundPayAdapterService = payServiceFactory.getRefundPayAdapterService(record.getPayVendor());

EnumProductOrderPayVendor payVendorEnum = EnumProductOrderPayVendor.getEnum(record.getPayVendor());
WxAppinfo appinfo = wxAppinfoService.getProjectCAppInfoFromRedis(record.getProjectType(), payVendorEnum.getPlat());
WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appinfo.getPayId());

RefundAdapterResult refund = refundPayAdapterService.refund(appinfo, payAccount, record);
if(refund.isSuccess()){
ProductOrderRefund orderRefundUpd = new ProductOrderRefund();
orderRefundUpd.setId(record.getId());
orderRefundUpd.setRefundId(refund.getRefundId());
orderRefundUpd.setRefundOrderStatus(EnumRefundOrderStatus.REFUND_REQ_SUCCESS.getCode());
productOrderRefundMapper.updateById(orderRefundUpd);

ProductOrderPay orderPayUpd = new ProductOrderPay();
orderPayUpd.setId(orderPay.getId());
orderPayUpd.setPayOrderStatus(EnumPayOrderStatus.ORDER_STATUS_PENDING_REFUND.getCode());
productOrderPayMapper.orderPayUpdStatus(orderPayUpd);
}

}

}

+ 24
- 0
suimangService/src/main/java/com/iformall/service/pay/PayServiceFactory.java Zobrazit soubor

@@ -6,6 +6,7 @@ import com.iformall.enums.EnumAppPlat;
import com.iformall.enums.EnumPayVersion;
import com.iformall.enums.EnumProductOrderPayVendor;
import com.iformall.service.pay.service.pay.wx.v3.nativePay.WxNativePayV3AdapterService;
import com.iformall.service.pay.service.refund.ali.AliRefundAdapterService;
import com.iformall.service.pay.service.refund.douyin.TtRefundAdapterService;
import com.iformall.service.pay.service.refund.wx.v2.WxRefundAdapterService;
import com.iformall.service.pay.service.refund.wx.v3.WxRefundV3AdapterService;
@@ -50,6 +51,7 @@ public class PayServiceFactory {

private Map<String,PayAdapterService> payVendorServiceMap = null;
private Map<String,PayShareAdapterService> payVendorShareMap = null;
private Map<String,RefundPayAdapterService> payVendorRefundMap = null;
private Map<String,PayAdapterService> platQrcodeMap = null;
private Map<String,PayAdapterService> platMsgMap = null;
@@ -92,6 +94,8 @@ public class PayServiceFactory {

@Autowired
TtRefundAdapterService ttRefundService;
@Autowired
AliRefundAdapterService aliRefundService;
@Autowired
WxCashOutQYFKAdapterService wxCashOutService;
@@ -235,6 +239,18 @@ public class PayServiceFactory {
}
return refundMap;
}

private Map<String,RefundPayAdapterService> getPayVendorRefundMap(){
if (null == payVendorRefundMap ) {
payVendorRefundMap = new ConcurrentHashMap<String, RefundPayAdapterService>();
payVendorRefundMap.put(EnumProductOrderPayVendor.PAY_WAY_WECHAT.getCode()+"_", wxRefundV3AdapterService);
payVendorRefundMap.put(EnumProductOrderPayVendor.PAY_WAY_WECHAT_NATIVE.getCode()+"_", wxRefundV3AdapterService);
payVendorRefundMap.put(EnumProductOrderPayVendor.PAY_WAY_ALIPAY.getCode()+"_", aliRefundService);
// payVendorRefundMap.put(EnumProductOrderPayVendor.PAY_WAY_ALIPAY_WAP.getCode()+"_",);
payVendorRefundMap.put(EnumProductOrderPayVendor.PAY_WAY_TT.getCode()+"_",ttRefundService);
}
return payVendorRefundMap;
}
private Map<String,CashOutAdapterService> getCashOutMap() {
if (null == cashoutMap ) {
@@ -334,6 +350,14 @@ public class PayServiceFactory {
}
return refundService;
}

public RefundPayAdapterService getRefundPayAdapterService(Integer payVendor) throws MallinkException{
RefundPayAdapterService refundService = getPayVendorRefundMap().get(payVendor+"_");
if (null == refundService) {
throw new MallinkException(ErrorCode.SYS_SERVER_ERROR.getCode(),"payWay["+payVendor+"] 退款service未找到");
}
return refundService;
}
public CashOutAdapterService getCashOutAdapterService(Integer type,Integer payVersion)throws MallinkException {
CashOutAdapterService cashOutService = getCashOutMap().get(type+"_"+payVersion);


+ 5
- 4
suimangService/src/main/java/com/iformall/service/pay/service/refund/RefundPayAdapterService.java Zobrazit soubor

@@ -2,10 +2,7 @@ package com.iformall.service.pay.service.refund;

import java.util.Map;

import com.iformall.domain.po.WxAppinfo;
import com.iformall.domain.po.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
import com.iformall.domain.po.*;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.service.pay.service.refund.entity.RefundAdapterResult;
@@ -23,6 +20,8 @@ public interface RefundPayAdapterService {
* @return
*/
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType);

public RefundAdapterResult refund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund);
/**
* API查询退款
@@ -32,6 +31,8 @@ public interface RefundPayAdapterService {
* @return
*/
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record);

public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, ProductOrderRefund orderRefund);
/**
* 平台方 异步通知


+ 199
- 0
suimangService/src/main/java/com/iformall/service/pay/service/refund/ali/AliRefundAdapterService.java Zobrazit soubor

@@ -0,0 +1,199 @@
package com.iformall.service.pay.service.refund.ali;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.request.AlipayTradeFastpayRefundQueryRequest;
import com.alipay.api.request.AlipayTradeRefundRequest;
import com.alipay.api.response.AlipayTradeFastpayRefundQueryResponse;
import com.alipay.api.response.AlipayTradeRefundResponse;
import com.iformall.common.ErrorCode;
import com.iformall.domain.po.*;
import com.iformall.douyin.pay.TtPayService;
import com.iformall.douyin.pay.exception.TtPayException;
import com.iformall.douyin.payv2.request.TtPayRefundQueryV2Request;
import com.iformall.douyin.payv2.request.TtPayRefundV2Request;
import com.iformall.douyin.payv2.result.TtPayRefundQueryV2Result;
import com.iformall.douyin.payv2.result.TtPayRefundV2Result;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumRefundOrderStatus;
import com.iformall.enums.EnumRefundStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxPayOrderMapper;
import com.iformall.mapper.WxRefundOrderMapper;
import com.iformall.service.WxAppinfoService;
import com.iformall.service.WxOrderService;
import com.iformall.service.WxPayAccountService;
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.utils.Constant;
import com.iformall.utils.MaUtil;
import com.iformall.utils.XmlUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

@Slf4j
@Service
public class AliRefundAdapterService implements RefundPayAdapterService{

@Autowired
MaUtil maUtil;

/**
* 做为分账的扩展数据
* @param
* @return
*/
protected String getCpExtra(WxRefundOrder record) {
Map<String,String> map = new HashMap<>();
map.put("tenantId",record.getTenantId());
return JSON.toJSONString(map);
}
@Override
public RefundAdapterResult refund(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {
return null;
}

@Override
public RefundAdapterResult refund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
AlipayClient aliPayClient = maUtil.getAliPayClient(appInfo, payAccount);
AlipayTradeRefundRequest request = new AlipayTradeRefundRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", orderRefund.getOrderNumber());
bizContent.put("refund_amount", orderRefund.getRefundAmountStr());
bizContent.put("refund_reason", orderRefund.getRefundDescription());
bizContent.put("out_request_no", orderRefund.getId().toString());

//// 返回参数选项,按需传入
//JSONArray queryOptions = new JSONArray();
//queryOptions.add("refund_detail_item_list");
//bizContent.put("query_options", queryOptions);

request.setBizContent(bizContent.toString());

try {
AlipayTradeRefundResponse response = aliPayClient.execute(request);
if(response.isSuccess()){
if("10000".equals(response.getCode())){
RefundAdapterResult refundAdapterResult = new RefundAdapterResult();
refundAdapterResult.setSuccess(true);
refundAdapterResult.setCode(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
refundAdapterResult.setData(response);
return refundAdapterResult;
}
}
return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),response.getMsg(),response);
} catch (AlipayApiException e) {
log.error("支付宝退款失败{}"+e.getMessage());
e.printStackTrace();
return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),EnumRefundStatus.REFUND_REQ_FAIL.getMessage(),null);
}
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
return null;
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
AlipayClient aliPayClient = maUtil.getAliPayClient(appInfo, payAccount);
AlipayTradeFastpayRefundQueryRequest request = new AlipayTradeFastpayRefundQueryRequest();
JSONObject bizContent = new JSONObject();
bizContent.put("out_trade_no", orderRefund.getOrderNumber());
bizContent.put("out_request_no", orderRefund.getId());

//// 返回参数选项,按需传入
//JSONArray queryOptions = new JSONArray();
//queryOptions.add("refund_detail_item_list");
//bizContent.put("query_options", queryOptions);

request.setBizContent(bizContent.toString());
try {
AlipayTradeFastpayRefundQueryResponse response = aliPayClient.execute(request);
if(response.isSuccess()){
if("REFUND_SUCCESS".equals(response.getRefundStatus())){
return new RefundAdapterResult(true, EnumRefundOrderStatus.REFUND_SUCCESS.getCode(),"退款成功",response);
}
return new RefundAdapterResult(false,EnumRefundOrderStatus.REFUND_FAIL.getCode(),"退款失败",response);
}
} catch (AlipayApiException e) {
e.printStackTrace();
log.error("查询支付宝退款结果失败"+e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),e.getMessage());
}
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}


@Autowired
WxAppinfoService wxAppinfoService;
@Autowired
WxPayAccountService wxPayAccountService;
@Autowired
WxPayOrderMapper wxPayOrderMapper;
@Autowired
WxRefundOrderMapper wxRefundOrderMapper;
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));
}
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));
}
@Override
public RefundNotifyAdapterResult notify(Map<String, String> paramMap, EnumPayWay payWay) {
log.info("TtRefundAdapterService notify{}"+paramMap);
String tenantId = paramMap.get("tenantId");
/**
*
*/
String refundno = paramMap.get("cp_refundno");
Long refundOrderId = Long.valueOf(refundno);
WxRefundOrder refundOrder = wxRefundOrderMapper.selectById(refundOrderId);

String appId = paramMap.get("appid");
WxAppinfo appinfo = wxAppinfoService.getByAppIdFromRedis(appId,tenantId);
if (appinfo == null) {
log.error("未找到appid信息:" + appId);
throw new MallinkException(ErrorCode.APP_ID_NOT_FOUND);
}
WxPayAccount payAccount = wxPayAccountService.getByIdFromRedis(appinfo.getPayId());
if (payAccount == null) {
log.error("未找到mch_id信息:" + appId);
throw new MallinkException(ErrorCode.MCH_INFO_NOT_FOUND);
}
if (!"SUCCESS".equals(paramMap.get("status"))) {
log.error("notify refund, wxpay status not success, paramMap: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifyErrorResult("订单状态码非SUCCESS");
}

// 验证退款金额
if (!paramMap.get("refund_amount").equals(refundOrder.getRefundFee().toString())) {
log.error("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: " + paramMap.toString() + ", payWay:" + payWay.toString());
return notifySuccessResult(refundOrder.getPayOrderNo(), paramMap.get("cp_refundno"), refundOrder);
}

}

+ 43
- 13
suimangService/src/main/java/com/iformall/service/pay/service/refund/douyin/TtRefundAdapterService.java Zobrazit soubor

@@ -16,6 +16,7 @@ import com.iformall.douyin.payv2.result.TtPayRefundQueryV2Result;
import com.iformall.douyin.payv2.result.TtPayRefundV2Result;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumRefundOrderStatus;
import com.iformall.enums.EnumRefundStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxPayAccountMapper;
@@ -121,7 +122,33 @@ public class TtRefundAdapterService implements RefundPayAdapterService{
// }
}

@Override
@Override
public RefundAdapterResult refund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {

CreateRefund createRefund = new CreateRefund();
createRefund.setAppId(appInfo.getAppId());
createRefund.setSalt(payAccount.getApiKey());
createRefund.setOutOrderNo(orderRefund.getOrderNumber());
createRefund.setOutRefundNo(orderRefund.getId().toString());
createRefund.setReason(orderRefund.getRefundReason());
createRefund.setRefundAmount(orderRefund.getRefundAmount());


CreateRefundResult refund = DouYinPayHelper.createRefund(createRefund);
if(refund.isSuccess()){
RefundAdapterResult refundAdapterResult = new RefundAdapterResult();
refundAdapterResult.setSuccess(true);
refundAdapterResult.setCode(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
refundAdapterResult.setRefundId(refund.getRefundNo());
refundAdapterResult.setData(refund);

return refundAdapterResult;
}else{
return new RefundAdapterResult(false,EnumRefundStatus.REFUND_REQ_FAIL.getCode(),refund.getMsg(),refund);
}
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
try {
TtPayService ttPayService = maUtil.getTtPayService(appInfo, payAccount);
@@ -146,20 +173,23 @@ public class TtRefundAdapterService implements RefundPayAdapterService{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常");
}


// QueryRefundResult queryRefundResult = DouYinPayHelper.refundQuery(appInfo.getAppId(), payAccount.getApiKey(), String.valueOf(record.getId()), null);
// if(queryRefundResult != null){
// if("SUCCESS".equals(queryRefundResult.getRefundStatus())){
// return new RefundAdapterResult(true,0,"退款",queryRefundResult);
// }else{
// return new RefundAdapterResult(false,ErrorCode.REFUND_ORDER_ERROR.getCode(),"退款失败",queryRefundResult);
// }
// }else{
// throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
// }
}

@Autowired
@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
QueryRefundResult queryRefundResult = DouYinPayHelper.refundQuery(appInfo.getAppId(), payAccount.getApiKey(), String.valueOf(orderRefund.getId()), null);
if(queryRefundResult != null){
if("SUCCESS".equals(queryRefundResult.getRefundStatus())){
return new RefundAdapterResult(true, EnumRefundOrderStatus.REFUND_SUCCESS.getCode(),"退款成功",queryRefundResult);
}else{
return new RefundAdapterResult(false,EnumRefundOrderStatus.REFUND_FAIL.getCode(),"退款失败",queryRefundResult);
}
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR);
}
}

@Autowired
WxAppinfoService wxAppinfoService;
@Autowired
WxPayAccountService wxPayAccountService;


+ 8
- 0
suimangService/src/main/java/com/iformall/service/pay/service/refund/entity/RefundAdapterResult.java Zobrazit soubor

@@ -8,6 +8,7 @@ public class RefundAdapterResult implements Serializable{
private Integer code;
private String msg;
private Object data;
private String refundId;
public RefundAdapterResult() {
@@ -48,4 +49,11 @@ public class RefundAdapterResult implements Serializable{
this.code = code;
}

public String getRefundId() {
return refundId;
}
public void setRefundId(String refundId) {
this.refundId = refundId;
}

}

+ 13
- 6
suimangService/src/main/java/com/iformall/service/pay/service/refund/wx/v2/WxRefundAdapterService.java Zobrazit soubor

@@ -5,6 +5,7 @@ import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;

import com.iformall.domain.po.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@@ -14,10 +15,6 @@ import com.alibaba.fastjson.JSONObject;
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.WxPayAccount;
import com.iformall.domain.po.WxPayOrder;
import com.iformall.domain.po.WxRefundOrder;
import com.iformall.enums.EnumPayMode;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
@@ -408,7 +405,12 @@ public class WxRefundAdapterService implements RefundPayAdapterService{
}
}

@Override
@Override
public RefundAdapterResult refund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
return null;
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
if (payAccount.getType() == EnumPayMode.MCH.getCode()) {
Map<String, String> paramMap = WxPayment.buildWeappRefundQueryMap(
@@ -503,7 +505,12 @@ public class WxRefundAdapterService implements RefundPayAdapterService{
}
}

@Autowired
@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
return null;
}

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@Autowired
WxPayAccountMapper wxPayAccountMapper;


+ 73
- 14
suimangService/src/main/java/com/iformall/service/pay/service/refund/wx/v3/WxRefundV3AdapterService.java Zobrazit soubor

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

import com.iformall.domain.po.*;
import com.iformall.enums.*;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
@@ -19,16 +21,6 @@ import com.github.binarywang.wxpay.service.WxPayService;
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;
import com.iformall.enums.EnumPayMchType;
import com.iformall.enums.EnumPayMode;
import com.iformall.enums.EnumPayType;
import com.iformall.enums.EnumPayWay;
import com.iformall.enums.EnumRefundStatus;
import com.iformall.exception.MallinkException;
import com.iformall.mapper.WxAppinfoMapper;
import com.iformall.mapper.WxPayAccountMapper;
@@ -59,10 +51,6 @@ import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class WxRefundV3AdapterService implements RefundPayAdapterService{

@Autowired
MaUtil maUtil;
@Lazy
@Autowired
@@ -71,6 +59,10 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{
@Lazy
@Autowired
WxPayAccountService wxPayAccountService;


@Autowired
MaUtil maUtil;
private V3PayRefundReq getReq(WxPayAccount payAccount,WxAppinfo appInfo,WxRefundOrder record,WxPayOrder payOrder,Long orderId,EnumPayType payType) {
V3PayRefundReq req = new V3PayRefundReq();
@@ -160,6 +152,42 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{
return getResultFromSp(response, record, payOrder);
}

@Override
public RefundAdapterResult refund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {

WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo, payAccount);

V3PayRefundReq req = new V3PayRefundReq();
req.setOut_trade_no(orderRefund.getOrderNumber());
req.setOut_refund_no(orderRefund.getId().toString());
req.setReason(orderRefund.getFailReason());

V3PayRefundAmountReq amount = new V3PayRefundAmountReq();
amount.setRefund(orderRefund.getRefundAmount());
amount.setTotal(orderRefund.getPayAmount());
req.setAmount(amount);

String response = null;
try {
try {
response = WxPayV3.payCommonRefund(payService, req);
}catch(WxPayException e) {
log.error("weixin pay v3 refund error. " ,e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getCustomErrorMsg());
}
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
JSONObject resp = JSON.parseObject(response);
RefundAdapterResult result = new RefundAdapterResult();
result.setSuccess(true);
result.setCode(EnumRefundStatus.REFUND_REQ_SUCCESS.getCode());
result.setRefundId(resp.getString("refund_id"));
result.setData(resp);
return result;
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo,WxPayAccount payAccount, WxRefundOrder record) {
// 服务商模式
@@ -192,6 +220,37 @@ public class WxRefundV3AdapterService implements RefundPayAdapterService{
}
}

@Override
public RefundAdapterResult queryRefund(WxAppinfo appInfo, WxPayAccount payAccount, ProductOrderRefund orderRefund) {
WxPayService payService = maUtil.getWxPayServiceBySelfModel(appInfo, payAccount);
String response = null;
try {
try {
response = WxPayV3.payCommonRefundQuery(payService, String.valueOf(orderRefund.getId()));
}catch(WxPayException e) {
log.error("weixin pay v3 query refund error " ,e);
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), e.getCustomErrorMsg());
}
JSONObject result = JSON.parseObject(response);
String refund_status_0 = result.getString("status");
if("SUCCESS".equals(refund_status_0)){
return new RefundAdapterResult(true, EnumRefundOrderStatus.REFUND_SUCCESS.getCode(),"退款成功",result);
}else if("CLOSED".equals(refund_status_0)){
return new RefundAdapterResult(false,EnumRefundOrderStatus.REFUND_FAIL.getCode(),"退款关闭,指商户发起退款失败的情况",result);
}else if("PROCESSING".equals(refund_status_0)){
return new RefundAdapterResult(false,EnumRefundOrderStatus.REFUND_REQ_SUCCESS.getCode(),"退款中",result);
}else if("ABNORMAL".equals(refund_status_0)){
return new RefundAdapterResult(false,EnumRefundOrderStatus.REFUND_FAIL.getCode(),
"退款异常,退款到银行发现用户的卡作废或者冻结了,导致原路退款银行卡失败。",result);
}else{
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(),"查询状态异常 非法状态");
}
} catch (Exception e) {
log.error("退款异常: " + e.getMessage());
throw new MallinkException(ErrorCode.REFUND_ORDER_ERROR.getCode(), "退款异常");
}
}

@Autowired
WxAppinfoMapper wxAppinfoMapper;
@Autowired


+ 1
- 1
suimangService/src/main/resources/mapper/ProductOrderPayMapper.xml Zobrazit soubor

@@ -89,7 +89,7 @@
</if>
<if test=" null != statusS ">
and `order_status` in
and `pay_order_status` in
<foreach collection="statusS" index="index" item="sItem" open="(" separator="," close=")">
#{sItem}
</foreach>


+ 146
- 0
suimangService/src/main/resources/mapper/ProductOrderRefundMapper.xml Zobrazit soubor

@@ -0,0 +1,146 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.iformall.mapper.ProductOrderRefundMapper">
<resultMap id="BaseResultMap" type="com.iformall.domain.po.ProductOrderRefund">
<id column="id" jdbcType="BIGINT" property="id"/>
<result column="tenant_id" jdbcType="VARCHAR" property="tenantId"/>
<result column="parent_tenant_id" jdbcType="VARCHAR" property="parentTenantId" />
<result column="order_id" jdbcType="BIGINT" property="orderId"/>
<result column="order_number" jdbcType="VARCHAR" property="orderNumber"/>
<result column="project_type" jdbcType="TINYINT" property="projectType"/>
<result column="pay_vendor" jdbcType="TINYINT" property="payVendor" />

<result column="user_id" jdbcType="BIGINT" property="userId"/>
<result column="pay_id" jdbcType="BIGINT" property="payId"/>
<result column="transaction_id" jdbcType="VARCHAR" property="transactionId"/>
<result column="pay_amount" jdbcType="INTEGER" property="payAmount"/>

<result column="refund_amount" jdbcType="INTEGER" property="refundAmount"/>
<result column="refund_order_status" jdbcType="INTEGER" property="refundOrderStatus"/>
<result column="fail_reason" jdbcType="VARCHAR" property="failReason"/>
<result column="refund_id" jdbcType="VARCHAR" property="refundId"/>

<result column="refund_reason" jdbcType="VARCHAR" property="refundReason"/>
<result column="refund_description" jdbcType="VARCHAR" property="refundDescription"/>

<result column="create_date" jdbcType="TIMESTAMP" property="createDate"/>
<result column="update_date" jdbcType="TIMESTAMP" property="updateDate"/>

</resultMap>

<sql id="allColumns">
`id`,`tenant_id`,`parent_tenant_id`,`order_id`,`order_number`,`project_type`,`pay_vendor`,
`user_id`,`pay_id`,`transaction_id`,`pay_amount`,
`refund_amount`,`refund_order_status`,`fail_reason`,`refund_id`,`refund_reason`,`refund_description`
`create_date`,`update_date`
</sql>

<sql id="dynamicWhereConditions">
where 1 = 1

<if test=" null != id ">
and `id` = #{id}
</if>

<if test=" null != tenantId and '' != tenantId">
and `tenant_id` = #{tenantId}
</if>
<if test=" null != parentTenantId and '' != parentTenantId">
and `parent_tenant_id` = #{parentTenantId}
</if>

<if test=" null != orderId ">
and `order_id` = #{orderId}
</if>
<if test=" null != orderNumber ">
and `order_number` = #{orderNumber}
</if>
<if test=" null != projectType "> and `project_type` = #{projectType} </if>
<if test=" null != payVendor "> and `pay_vendor` = #{payVendor} </if>

<if test=" null != userId ">
and `user_id` = #{userId}
</if>
<if test=" null != payId ">
and `pay_id` = #{payId}
</if>

<if test=" null != transactionId ">
and `transaction_id` = #{transactionId}
</if>

<if test=" null != refundOrderStatus ">
and `refund_order_status` = #{refundOrderStatus}
</if>
<if test=" null != startDate ">
and `create_date` &gt;= #{startDate}
</if>
<if test=" null != endDate">
and `create_date` &lt;= #{endDate}
</if>
<if test=" null != statusS ">
and `refund_order_status` in
<foreach collection="statusS" index="index" item="sItem" open="(" separator="," close=")">
#{sItem}
</foreach>
</if>

<if test=" null != ids ">
and id in
<foreach collection="ids" index="index" item="idItem" open="(" separator="," close=")">
#{idItem}
</foreach>
</if>
<if test=" null != sortColumns">order by ${sortColumns}</if>
</sql>

<select id="findList" parameterType="com.iformall.domain.po.ProductOrderPay" resultMap="BaseResultMap">
select
<include refid="allColumns"/>
from product_order_pay
<include refid="dynamicWhereConditions"/>
</select>


<update id="orderPayUpdStatus" parameterType="com.iformall.domain.po.ProductOrderPay">
update product_order_pay
set `pay_order_status` = #{payOrderStatus}
,`update_date` = #{updateDate}
<if test=" null != openId">
,`open_id` = #{openId}
</if>
<if test=" null != transactionId">
,`transaction_id` = #{transactionId}
</if>
<if test=" null != payTime">
,`pay_time` = #{payTime}
</if>
<if test=" null != payWay">
,`pay_way` = #{payWay}
</if>
where id = #{id}
and `pay_order_status` != #{payOrderStatus}
<if test=" null != isOrderStatus">
and `pay_order_status` = #{isOrderStatus}
</if>

</update>


<select id="selectByOrder" parameterType="java.util.HashMap" resultMap="BaseResultMap">
select
<include refid="allColumns"/>
from product_order_pay
where `order_id` = #{orderId}
and `pay_vendor` = #{payVendor}
</select>

<update id="orderPayUpdStatus" parameterType="java.util.HashMap">
update product_order_pay
set `pay_order_status` = #{payOrderStatus}
,`update_date` = now()
where `order_id` = #{orderId}
</update>

</mapper>

Načítá se…
Zrušit
Uložit