Commit b48392ab authored by shiyu's avatar shiyu

退款接口

parent 0d2bee3a
...@@ -37,6 +37,11 @@ public class WxPayProperties { ...@@ -37,6 +37,11 @@ public class WxPayProperties {
*/ */
private String payNotifyUrl; private String payNotifyUrl;
/**
* 支付退款通知地址
*/
private String refundNotifyUrl;
/** /**
* 私钥地址 * 私钥地址
*/ */
...@@ -124,4 +129,8 @@ public class WxPayProperties { ...@@ -124,4 +129,8 @@ public class WxPayProperties {
public void setPrivateKeyPath(String privateKeyPath) { public void setPrivateKeyPath(String privateKeyPath) {
this.privateKeyPath = privateKeyPath; this.privateKeyPath = privateKeyPath;
} }
public String getRefundNotifyUrl() {
return refundNotifyUrl;
}
} }
...@@ -19,6 +19,7 @@ import com.wechat.pay.java.service.refund.model.CreateRequest; ...@@ -19,6 +19,7 @@ import com.wechat.pay.java.service.refund.model.CreateRequest;
import com.wechat.pay.java.service.refund.model.Refund; import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.Status; import com.wechat.pay.java.service.refund.model.Status;
import com.wwdz.ch.core.consts.ResultCode; import com.wwdz.ch.core.consts.ResultCode;
import com.wwdz.ch.core.entity.wxPay.DistributionOrderRefundRequestDto;
import com.wwdz.ch.core.type.Result; import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.PriceUtil; import com.wwdz.ch.core.util.PriceUtil;
import com.wwdz.ch.core.util.UUID; import com.wwdz.ch.core.util.UUID;
...@@ -267,4 +268,43 @@ public class WxPayServiceApi { ...@@ -267,4 +268,43 @@ public class WxPayServiceApi {
return Result.failed(); return Result.failed();
} }
/**
* 微信支付申请退款
* @param dto
* @return
*/
public Result orderRefund(DistributionOrderRefundRequestDto dto){
try {
//构建退款service
RefundService service = new RefundService.Builder().config(rsaAutoCertificateConfig).build();
//构建退款请求
CreateRequest request = new CreateRequest();
//构建订单金额信息
AmountReq amountReq = new AmountReq();
//退款金额,单位为分
amountReq.setRefund(dto.getRefundPrice());
//原订单金额,单位为分
amountReq.setTotal(dto.getAmount());
//货币类型(默认人民币)
amountReq.setCurrency("CNY");
//退款回调地址
request.setNotifyUrl(wxPayProperties.getRefundNotifyUrl());
//商户系统单号
request.setOutTradeNo(dto.getDistributionOrderId());
request.setAmount(amountReq);
//商户退款单号
request.setOutRefundNo(dto.getRefundId());
//退款通知回调地址
request.setNotifyUrl(null);
Refund refundResponse = service.create(request);
logger.info("微信申请退款接口返回:{}", JsonUtils.from(refundResponse));
return Result.success(refundResponse);
}catch (Exception e){
logger.error("微信退款接口错误error : {}", e);
}
return Result.failed();
}
} }
...@@ -10,6 +10,7 @@ public class DistributionEnum { ...@@ -10,6 +10,7 @@ public class DistributionEnum {
PRE_SEND(10, "待发货"), PRE_SEND(10, "待发货"),
PRE_SIGNED(20, "待收货"), PRE_SIGNED(20, "待收货"),
AFTER_SALE(30, "售后中"), AFTER_SALE(30, "售后中"),
REFUNDING(80, "退款受理中"),
FINISH(100, "已完成"), FINISH(100, "已完成"),
CANCEL(101, "已取消"), CANCEL(101, "已取消"),
...@@ -44,4 +45,41 @@ public class DistributionEnum { ...@@ -44,4 +45,41 @@ public class DistributionEnum {
} }
/**
* 分销订单状态
*/
public enum RefundOrderStateEnum {
PROCESSING(10, "处理中"),
SUCCESS(100, "退款成功"),
FAILED(101, "退款失败"),
;
private int code;
private String des;
RefundOrderStateEnum(int code, String des) {
this.code = code;
this.des = des;
}
public static String getNameByCode(int code) {
for (DistributionEnum.RefundOrderStateEnum refundOrderStateEnum : DistributionEnum.RefundOrderStateEnum.values()) {
if (code == refundOrderStateEnum.getCode()) {
return refundOrderStateEnum.getDes();
}
}
return null;
}
public int getCode() {
return code;
}
public String getDes() {
return des;
}
}
} }
package com.wwdz.ch.core.entity.wxPay;
import com.xxdxxs.entity.Entity;
import lombok.Data;
@Data
public class DistributionOrderRefundRequestDto implements Entity {
/**
* 分销订单号
*/
private String distributionOrderId;
/**
* 系统退款单号
*/
private String refundId;
/**
* 订单金额
*/
private Long amount;
/**
* 分销订单状态
*/
private Integer state;
/**
* 微信支付订单号
*/
private String paymentId;
/**
* 预支付单号
*/
private String prepayId;
/**
* 要退款的金额
*/
private Long refundPrice;
/**
* 退款接口请求秘钥
*/
private String secret;
}
...@@ -47,6 +47,7 @@ dts: ...@@ -47,6 +47,7 @@ dts:
merchantSerialNumber: 41168B86EDCC260B11D2B0DDE8684DF148FB16F2 merchantSerialNumber: 41168B86EDCC260B11D2B0DDE8684DF148FB16F2
apiV3Key: 7e9504fd8a5c458ab7466b8aaae462a9 apiV3Key: 7e9504fd8a5c458ab7466b8aaae462a9
payNotifyUrl: https://cjxc-applet-dev.wanwudezhi.com/wxPayCallback/getPayNotify payNotifyUrl: https://cjxc-applet-dev.wanwudezhi.com/wxPayCallback/getPayNotify
refundNotifyUrl: https://cjxc-applet-dev.wanwudezhi.com/wxPayCallback/getRefundNotify
privateKeyPath: apiclient_key.pem privateKeyPath: apiclient_key.pem
p12KeyPath: apiclient_cert.p12 p12KeyPath: apiclient_cert.p12
tradeType: JSAPI tradeType: JSAPI
......
...@@ -38,6 +38,7 @@ dts: ...@@ -38,6 +38,7 @@ dts:
merchantSerialNumber: 41168B86EDCC260B11D2B0DDE8684DF148FB16F2 merchantSerialNumber: 41168B86EDCC260B11D2B0DDE8684DF148FB16F2
apiV3Key: 7e9504fd8a5c458ab7466b8aaae462a9 apiV3Key: 7e9504fd8a5c458ab7466b8aaae462a9
payNotifyUrl: https://cjxc-applet.wanwudezhi.com/wxPayCallback/getPayNotify payNotifyUrl: https://cjxc-applet.wanwudezhi.com/wxPayCallback/getPayNotify
refundNotifyUrl: https://cjxc-applet.wanwudezhi.com/wxPayCallback/getRefundNotify
privateKeyPath: apiclient_key.pem privateKeyPath: apiclient_key.pem
p12KeyPath: apiclient_cert.p12 p12KeyPath: apiclient_cert.p12
tradeType: JSAPI tradeType: JSAPI
......
package com.wwdz.ch.db.dao.distribution;
import com.wwdz.ch.db.domain.distribution.RefundOrder;
public interface RefundOrderDao {
/**
* 插入新记录
*
* @param refundOrder
* @return
*/
int insert(RefundOrder refundOrder);
/**
* 更新记录
*
* @param refundOrder
* @return
*/
int update(RefundOrder refundOrder);
}
...@@ -127,4 +127,9 @@ public class DistributionOrderRequestDto extends BaseRequestDto implements Entit ...@@ -127,4 +127,9 @@ public class DistributionOrderRequestDto extends BaseRequestDto implements Entit
* 要退款的金额 * 要退款的金额
*/ */
private String refundPrice; private String refundPrice;
/**
* 退款接口请求秘钥
*/
private String secret;
} }
package com.wwdz.ch.db.impl.distribution;
import com.wwdz.ch.db.dao.distribution.RefundOrderDao;
import com.wwdz.ch.db.domain.distribution.RefundOrder;
import com.wwdz.ch.db.domain.distribution.RefundOrderExample;
import com.wwdz.ch.db.mapper.distribution.RefundOrderMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
@Repository
public class RefundOrderDaoImpl implements RefundOrderDao {
@Autowired
RefundOrderMapper refundOrderMapper;
@Override
public int insert(RefundOrder refundOrder) {
return refundOrderMapper.insert(refundOrder);
}
@Override
public int update(RefundOrder refundOrder) {
RefundOrderExample example = new RefundOrderExample();
RefundOrderExample.Criteria criteria = example.createCriteria();
criteria.andRefundIdEqualTo(refundOrder.getRefundId());
return refundOrderMapper.updateByExampleSelective(refundOrder, example);
}
}
package com.wwdz.ch.db.mapper.distribution;
import com.wwdz.ch.db.domain.distribution.RefundOrder;
import com.wwdz.ch.db.domain.distribution.RefundOrderExample;
import java.util.List;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
@Mapper
public interface RefundOrderMapper {
long countByExample(RefundOrderExample example);
int deleteByExample(RefundOrderExample example);
int deleteByPrimaryKey(Integer id);
int insert(RefundOrder record);
int insertSelective(RefundOrder record);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table refund_order
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
RefundOrder selectOneByExample(RefundOrderExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table refund_order
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
RefundOrder selectOneByExampleSelective(@Param("example") RefundOrderExample example, @Param("selective") RefundOrder.Column ... selective);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table refund_order
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
List<RefundOrder> selectByExampleSelective(@Param("example") RefundOrderExample example, @Param("selective") RefundOrder.Column ... selective);
List<RefundOrder> selectByExample(RefundOrderExample example);
/**
* This method was generated by MyBatis Generator.
* This method corresponds to the database table refund_order
*
* @mbg.generated
* @project https://github.com/itfsw/mybatis-generator-plugin
*/
RefundOrder selectByPrimaryKeySelective(@Param("id") Integer id, @Param("selective") RefundOrder.Column ... selective);
RefundOrder selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") RefundOrder record, @Param("example") RefundOrderExample example);
int updateByExample(@Param("record") RefundOrder record, @Param("example") RefundOrderExample example);
int updateByPrimaryKeySelective(RefundOrder record);
int updateByPrimaryKey(RefundOrder record);
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ import com.wechat.pay.java.core.RSAAutoCertificateConfig; ...@@ -4,6 +4,7 @@ import com.wechat.pay.java.core.RSAAutoCertificateConfig;
import com.wechat.pay.java.core.notification.NotificationParser; import com.wechat.pay.java.core.notification.NotificationParser;
import com.wechat.pay.java.core.notification.RequestParam; import com.wechat.pay.java.core.notification.RequestParam;
import com.wechat.pay.java.service.payments.model.Transaction; import com.wechat.pay.java.service.payments.model.Transaction;
import com.wechat.pay.java.service.refund.model.RefundNotification;
import com.wwdz.ch.core.api.OfficialAccountApi; import com.wwdz.ch.core.api.OfficialAccountApi;
import com.wwdz.ch.core.api.wxpay.WxPayServiceApi; import com.wwdz.ch.core.api.wxpay.WxPayServiceApi;
import com.wwdz.ch.core.consts.DistributionEnum; import com.wwdz.ch.core.consts.DistributionEnum;
...@@ -11,14 +12,8 @@ import com.wwdz.ch.core.type.Result; ...@@ -11,14 +12,8 @@ import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.PriceUtil; import com.wwdz.ch.core.util.PriceUtil;
import com.wwdz.ch.core.util.RedisUtils; import com.wwdz.ch.core.util.RedisUtils;
import com.wwdz.ch.core.util.TimeUtil; import com.wwdz.ch.core.util.TimeUtil;
import com.wwdz.ch.db.dao.distribution.DistributionOrderDao; import com.wwdz.ch.db.dao.distribution.*;
import com.wwdz.ch.db.dao.distribution.DistributorBindDao; import com.wwdz.ch.db.domain.distribution.*;
import com.wwdz.ch.db.dao.distribution.DistributorProfitDao;
import com.wwdz.ch.db.dao.distribution.SupplierItemDao;
import com.wwdz.ch.db.domain.distribution.DistributionOrder;
import com.wwdz.ch.db.domain.distribution.DistributorBind;
import com.wwdz.ch.db.domain.distribution.DistributorProfit;
import com.wwdz.ch.db.domain.distribution.SupplierItem;
import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto; import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
import com.wwdz.ch.wx.entity.PayNoticeMsg; import com.wwdz.ch.wx.entity.PayNoticeMsg;
import com.wwdz.ch.wx.service.distribution.SendMsgService; import com.wwdz.ch.wx.service.distribution.SendMsgService;
...@@ -32,7 +27,7 @@ import org.springframework.transaction.annotation.Transactional; ...@@ -32,7 +27,7 @@ import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport; import org.springframework.transaction.interceptor.TransactionAspectSupport;
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import org.springframework.web.bind.annotation.RestController;
import com.wechat.pay.java.service.refund.model.Status;
import javax.servlet.ServletInputStream; import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletRequest;
import java.io.BufferedReader; import java.io.BufferedReader;
...@@ -81,8 +76,11 @@ public class WxPayCallbackController { ...@@ -81,8 +76,11 @@ public class WxPayCallbackController {
@Autowired @Autowired
DistributorBindDao distributorBindDao; DistributorBindDao distributorBindDao;
@Autowired
RefundOrderDao refundOrderDao;
@RequestMapping(value ="/getPayNotify") @RequestMapping(value ="/getPayNotify")
public synchronized String payNotify(HttpServletRequest request) throws IOException { public String payNotify(HttpServletRequest request) throws IOException {
logger.info("------------------ 收到微信支付回调通知 ------------------"); logger.info("------------------ 收到微信支付回调通知 ------------------");
// 请求头Wechatpay-Signature // 请求头Wechatpay-Signature
String signature = request.getHeader("Wechatpay-Signature"); String signature = request.getHeader("Wechatpay-Signature");
...@@ -246,7 +244,7 @@ public class WxPayCallbackController { ...@@ -246,7 +244,7 @@ public class WxPayCallbackController {
sb.append(line); sb.append(line);
} }
} catch (IOException e) { } catch (IOException e) {
throw new IOException("读取返回支付接口数据流出现异常!"); throw new IOException("读取微信回调接口数据流出现异常!");
} finally { } finally {
if (reader != null) { if (reader != null) {
reader.close(); reader.close();
...@@ -259,4 +257,94 @@ public class WxPayCallbackController { ...@@ -259,4 +257,94 @@ public class WxPayCallbackController {
} }
@RequestMapping(value ="/getRefundNotify")
@Transactional
public String refundNotify(HttpServletRequest request) throws IOException {
logger.info("------------------ 收到微信支付退款回调通知 ------------------");
// 请求头Wechatpay-Signature
String signature = request.getHeader("Wechatpay-Signature");
// 请求头Wechatpay-nonce
String nonce = request.getHeader("Wechatpay-Nonce");
// 请求头Wechatpay-Timestamp
String timestamp = request.getHeader("Wechatpay-Timestamp");
// 微信支付证书序列号
String serial = request.getHeader("Wechatpay-Serial");
// 签名方式
String signType = request.getHeader("Wechatpay-Signature-Type");
// 初始化 NotificationParser
NotificationParser parser = new NotificationParser(rsaAutoCertificateConfig);
// 构造 RequestParam
RequestParam requestParam = new RequestParam.Builder()
.serialNumber(serial)
.nonce(nonce)
.signature(signature)
.timestamp(timestamp)
.signType(signType)
.body(getRequestBody(request))
.build();
Map<String, String> returnMap = new HashMap<>();
returnMap.put("code", "FAIL");
returnMap.put("message", "失败");
RefundNotification refundNotification;
try {
refundNotification = parser.parse(requestParam, RefundNotification.class);
logger.info("验签成功!-退款回调结果:{}", refundNotification.toString());
} catch (Exception e) {
logger.error("退款回调验签失败:{}", e);
return JsonUtils.from(returnMap);
}
//商户订单号,分销订单号
String distributionOrderId = refundNotification.getOutTradeNo();
//商户退款单号
String refundId = refundNotification.getOutRefundNo();
try {
if (redisUtils.hasKey(refundId)) {
logger.info(">>>>>>>>>>> 分销单号【{}】, 退款单号【{}】, 退款回调正在被其它服务处理,当前不能操作 <<<<<<<<<<<<", distributionOrderId, refundId);
return JsonUtils.from(returnMap);
}
redisUtils.set(refundId, refundId);
//退款成功
if (refundNotification.getRefundStatus().equals(Status.SUCCESS)){
//查询系统中订单现在的状态,避免重复更新
DistributionOrder distributionOrder = distributionOrderDao.findById(distributionOrderId);
//只有在订单状态为退款处理中,才进行退款成功的状态修改
if (distributionOrder.getState() == DistributionEnum.DistributionOrderStateEnum.REFUNDING.getCode()) {
//订单改为已取消的状态
distributionOrderDao.updateState(distributionOrderId, DistributionEnum.DistributionOrderStateEnum.CANCEL.getCode());
String successTime = refundNotification.getSuccessTime();
//退款单状态改为成功
RefundOrder refundOrder = new RefundOrder();
refundOrder.setRefundId(refundId);
refundOrder.setWxRefundId(refundNotification.getRefundId());
refundOrder.setUpdateTime(new Date());
refundOrder.setSuccessTime(TimeUtil.wxTimeConvertToDate(successTime));
refundOrder.setUserReceivedAccount(refundNotification.getUserReceivedAccount());
refundOrder.setState(DistributionEnum.RefundOrderStateEnum.SUCCESS.getCode());
refundOrderDao.update(refundOrder);
//分销商利润记录改为无效
distributorProfitDao.updateValidState(distributionOrderId, false);
logger.info(">>>>>>>> 分销单号:{}, 退款单号:{},退款处理成功, 退款时间为: {}<<<<<<<<<", distributionOrderId, refundId, TimeUtil.wxTimeConvertToDate(successTime));
returnMap.put("code", "SUCCESS");
returnMap.put("message", "成功");
return JsonUtils.from(returnMap);
}
} else {
//退款单状态改为失败
RefundOrder refundOrder = new RefundOrder();
refundOrder.setRefundId(refundId);
refundOrder.setUpdateTime(new Date());
refundOrder.setState(DistributionEnum.RefundOrderStateEnum.FAILED.getCode());
refundOrderDao.update(refundOrder);
}
} catch (Exception e) {
logger.error("退款回调处理失败 : {}", e);
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
} finally {
redisUtils.delete(refundId);
}
return JsonUtils.from(returnMap);
}
} }
...@@ -43,7 +43,7 @@ public class WebMvcConfiguration implements WebMvcConfigurer { ...@@ -43,7 +43,7 @@ public class WebMvcConfiguration implements WebMvcConfigurer {
"/imCallback/**", "/wx/category/**", "/imCallback/**", "/wx/category/**",
"/wx/consignSale/**", "/wx/item/**", "/wx/consignSale/**", "/wx/item/**",
"/wx/returnOrder/**", "/wx/distributionOrder/confirmSigned", "/wx/distributionOrder/delivery", "/wx/distributionOrder/cancel", "/wx/returnOrder/**", "/wx/distributionOrder/confirmSigned", "/wx/distributionOrder/delivery", "/wx/distributionOrder/cancel",
"/wx/supplierItem/findItemsOfCurrentDistributor" "/wx/supplierItem/findItemsOfCurrentDistributor", "/wx/distributionOrder/refund"
// , "/wx/supplierItem/**", "/wx/shareRecord/**", "/wx/distributionOrder/**", "/wx/selfPage/**" // , "/wx/supplierItem/**", "/wx/shareRecord/**", "/wx/distributionOrder/**", "/wx/selfPage/**"
/* "/wx/officialAccount/**", /* "/wx/officialAccount/**",
"/wx/item/**", "/wx/item/**",
......
package com.wwdz.ch.wx.impl.distribution; package com.wwdz.ch.wx.impl.distribution;
import com.github.pagehelper.PageInfo; import com.github.pagehelper.PageInfo;
import com.wechat.pay.java.service.refund.model.Refund;
import com.wechat.pay.java.service.refund.model.Status;
import com.wwdz.ch.core.api.wxpay.WxPayServiceApi; import com.wwdz.ch.core.api.wxpay.WxPayServiceApi;
import com.wwdz.ch.core.consts.DistributionEnum; import com.wwdz.ch.core.consts.DistributionEnum;
import com.wwdz.ch.core.consts.LogisticsEnum; import com.wwdz.ch.core.consts.LogisticsEnum;
import com.wwdz.ch.core.entity.wxPay.DistributionOrderRefundRequestDto;
import com.wwdz.ch.core.type.PageSearchResult; import com.wwdz.ch.core.type.PageSearchResult;
import com.wwdz.ch.core.type.Result; import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.*; import com.wwdz.ch.core.util.*;
import com.wwdz.ch.db.dao.distribution.DistributionOrderDao; import com.wwdz.ch.core.util.UUID;
import com.wwdz.ch.db.dao.distribution.DistributorProfitDao; import com.wwdz.ch.db.dao.distribution.*;
import com.wwdz.ch.db.dao.distribution.DistributorShareRecordDao; import com.wwdz.ch.db.domain.distribution.*;
import com.wwdz.ch.db.dao.distribution.SupplierItemDao;
import com.wwdz.ch.db.domain.distribution.DistributionOrder;
import com.wwdz.ch.db.domain.distribution.DistributorProfit;
import com.wwdz.ch.db.domain.distribution.DistributorShareRecord;
import com.wwdz.ch.db.domain.distribution.SupplierItem;
import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto; import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
import com.wwdz.ch.db.dto.request.distribution.SupplierItemRequestDto; import com.wwdz.ch.db.dto.request.distribution.SupplierItemRequestDto;
import com.wwdz.ch.wx.entity.DeliveryNoticeMsg; import com.wwdz.ch.wx.entity.DeliveryNoticeMsg;
...@@ -45,6 +43,8 @@ public class DistributionOrderServiceImpl implements DistributionOrderService { ...@@ -45,6 +43,8 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
private final static String DISTRIBUTION_ORDER_PREFIX = "DA"; private final static String DISTRIBUTION_ORDER_PREFIX = "DA";
private final static String SECRET = "117eb48AX0864490fbe4d1ef081B9cc25";
@Autowired @Autowired
DistributionOrderDao distributionOrderDao; DistributionOrderDao distributionOrderDao;
...@@ -69,6 +69,9 @@ public class DistributionOrderServiceImpl implements DistributionOrderService { ...@@ -69,6 +69,9 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
@Autowired @Autowired
SendMsgService sendMsgService; SendMsgService sendMsgService;
@Autowired
RefundOrderDao refundOrderDao;
@Transactional @Transactional
@Override @Override
public Result createDistributionOrder(DistributionOrderRequestDto dto) { public Result createDistributionOrder(DistributionOrderRequestDto dto) {
...@@ -487,4 +490,52 @@ public class DistributionOrderServiceImpl implements DistributionOrderService { ...@@ -487,4 +490,52 @@ public class DistributionOrderServiceImpl implements DistributionOrderService {
} }
}); });
} }
@Override
public Result refund(DistributionOrderRequestDto dto) {
try {
String refundId = UUID.randomUUID().toString(true);
//判断订单状态
String distributionOrderId = dto.getDistributionOrderId();
DistributionOrder distributionOrder = distributionOrderDao.findById(distributionOrderId);
if (distributionOrder.getState() != DistributionEnum.DistributionOrderStateEnum.PRE_SEND.getCode()) {
return Result.failed("订单状态不是待发货,不能退款");
}
if (!SECRET.equals(dto.getSecret())) {
return Result.failed("密钥不正确");
}
DistributionOrderRefundRequestDto refundRequestDto = new DistributionOrderRefundRequestDto();
refundRequestDto.setDistributionOrderId(distributionOrderId);
refundRequestDto.setRefundPrice(distributionOrder.getAmount());
refundRequestDto.setAmount(distributionOrder.getAmount());
refundRequestDto.setRefundId(refundId);
Result result = wxPayServiceApi.orderRefund(refundRequestDto);
if (!result.getSuccess()) {
return Result.failed("调用微信支付退款接口错误");
}
Refund refundResponse = (Refund) result.getData();
if (refundResponse.getStatus().equals(Status.SUCCESS)) {
Date now = new Date();
//创建退款单
RefundOrder refundOrder = new RefundOrder();
refundOrder.setRefundId(refundId);
refundOrder.setRefundAmount(distributionOrder.getAmount());
refundOrder.setAmount(distributionOrder.getAmount());
refundOrder.setDistributionOrderId(distributionOrderId);
refundOrder.setDistributorId(distributionOrder.getSellerId());
refundOrder.setCreateTime(now);
refundOrder.setUpdateTime(now);
refundOrder.setState(DistributionEnum.RefundOrderStateEnum.PROCESSING.getCode());
refundOrderDao.insert(refundOrder);
//退款受理成功,订单的状态改为退款受理中
distributionOrderDao.updateState(distributionOrderId, DistributionEnum.DistributionOrderStateEnum.REFUNDING.getCode());
logger.info(">>>>>>>> 分销单号:{}, 退款单号:{}, 退款申请成功,创建退款单 <<<<<<<<<", distributionOrderId, refundId);
return Result.success(refundId);
}
} catch (Exception e) {
logger.error("退款申请失败 error : {}", e);
}
return Result.failed();
}
} }
...@@ -61,6 +61,13 @@ public interface DistributionOrderService { ...@@ -61,6 +61,13 @@ public interface DistributionOrderService {
*/ */
Result findOrderDetailOfUser(DistributionOrderRequestDto dto); Result findOrderDetailOfUser(DistributionOrderRequestDto dto);
/**
* 订单退款
* @param dto
* @return
*/
Result refund(DistributionOrderRequestDto dto);
......
...@@ -176,4 +176,19 @@ public class DistributionOrderController { ...@@ -176,4 +176,19 @@ public class DistributionOrderController {
return distributionOrderService.findOrderDetailOfUser(dto); return distributionOrderService.findOrderDetailOfUser(dto);
} }
@ApiOperation(value = "订单退款")
@PostMapping("/refund")
public Result refund(@RequestBody DistributionOrderRequestDto dto) {
logger.info("订单退款,请求参数:{}", JSON.toJSONString(dto));
Validator validator = new Validator(FormHandler.ofEntity(dto));
validator.set("secret", "秘钥").must().string()
.set("distributionOrderId", "分销订单号").must().string()
.end();
if (!validator.isValid()) {
return Result.failed(validator.getErrorInfo());
}
return distributionOrderService.refund(dto);
}
} }
...@@ -5,6 +5,7 @@ import com.wwdz.ch.core.api.OfficialAccountApi; ...@@ -5,6 +5,7 @@ import com.wwdz.ch.core.api.OfficialAccountApi;
import com.wwdz.ch.core.api.wxpay.WxPayServiceApi; import com.wwdz.ch.core.api.wxpay.WxPayServiceApi;
import com.wwdz.ch.core.type.Result; import com.wwdz.ch.core.type.Result;
import com.wwdz.ch.core.util.PriceUtil; import com.wwdz.ch.core.util.PriceUtil;
import com.wwdz.ch.core.util.UUID;
import com.wwdz.ch.db.dao.distribution.DistributionOrderDao; import com.wwdz.ch.db.dao.distribution.DistributionOrderDao;
import com.wwdz.ch.db.domain.distribution.DistributionOrder; import com.wwdz.ch.db.domain.distribution.DistributionOrder;
import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto; import com.wwdz.ch.db.dto.request.distribution.DistributionOrderRequestDto;
...@@ -43,17 +44,21 @@ public class WxPayServiceTest { ...@@ -43,17 +44,21 @@ public class WxPayServiceTest {
@Test @Test
public void refund() { public void refund() {
List<String> list = Arrays.asList("DA2402241542377839584"); List<String> list = Arrays.asList("DA2402241539558250270");
list.forEach(orderId ->{ list.forEach(orderId ->{
DistributionOrderRequestDto dto = new DistributionOrderRequestDto(); DistributionOrderRequestDto dto = new DistributionOrderRequestDto();
dto.setDistributionOrderId(orderId); dto.setDistributionOrderId(orderId);
dto.setAmount("28.8"); dto.setAmount("12.8");
dto.setRefundPrice("28.8"); dto.setRefundPrice("12.8");
Result result = wxPayServiceApi.refund(dto); Result result = wxPayServiceApi.refund(dto);
logger.info("申请微信支付退款:{}", result); logger.info("申请微信支付退款:{}", result);
}); });
} }
public static void main(String[] args) {
System.out.println(UUID.fastUUID().toString(true));
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment