Commit d2f97121 by 咸鱼

feat:订单支持部分退款

parent 27ed02bf
package com.freemud.sdk.api.assortment.order.request.order;
import com.freemud.application.sdk.api.ordercenter.request.create.OrderTaskReq;
import io.swagger.annotations.ApiModelProperty;
import lombok.Builder;
import lombok.Data;
import org.hibernate.validator.constraints.Range;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
@Data
public class V2CancelOrderRequest {
@ApiModelProperty(value = "商户号", required = true)
@NotNull
private String partnerId;
@ApiModelProperty(value = "操作人")
private String operator;
@ApiModelProperty(value = "订单编号,与thirdOrderCode二选一,如果orderCode为null则使用thirdOrderCode查询订单")
private String orderCode;
@ApiModelProperty(value = "第三方订单编码,与orderCode二选一,三平台订单号,例如百度、饿了么、美团")
private String thirdOrderCode;
@NotNull(message = "下单渠道不能为空")
@Range(min = 1, max = 127)
private Byte orderClient;
@ApiModelProperty(value = "退的配送费,单位:分")
private BigDecimal deliveryAmount;
@ApiModelProperty(value = "售后原因")
private String afterSalesReason;
@ApiModelProperty(value = "取消原因", hidden = true)
private String cancelReason;
@ApiModelProperty(value = "申请说明")
private String reqRemark = "";
@ApiModelProperty(value = "从创建售后单开始计时,超时完成的时间(单位:分钟),超时后通知。若不需要通知,则不填写。")
private Integer timeout;
@ApiModelProperty(value = "订单定时任务")
private OrderTaskReq orderTask;
/**
* 操作来源客户端
*/
@ApiModelProperty(value = "操作来源客户端 1:POS插件 2:小助手 3:开放平台 4:自动任务 5:用户端 6:系统 7:万象 8:太一")
private Byte operationClient;
/**
* 售后退款状态
*/
@ApiModelProperty(value = "售后退款状态 0:未定义(存量数据) 1:未退款 2:退款中 3:退款失败 4:已退款")
private Byte refundState;
/**
* 退款失败原因
*/
@ApiModelProperty(value = "退款失败原因")
private String refundFailReason;
@ApiModelProperty(value = "售后单类型", required = true)
@NotNull
private Byte afterSalesType;
@ApiModelProperty(value = "是否退配送费,默认值:是")
@Builder.Default
private boolean isRefundDeliveryAmount = true ;
@ApiModelProperty(value = "申请金额,单位分,如果是全部退款,并且传递null,则自动填入 订单用户需支付金额", required = true)
private BigDecimal reqAmount;
@ApiModelProperty(value = "若为null,默认只做【创建】,售后单状态为【待处理】\n" +
"若为2,默认做【创建】+【审核通过】,售后单状态为【退货中】\n" +
"若为5,默认做【创建】+【同意并退货完成】,售后单状态【已退货】\n" +
"若为4,默认做【创建】+【同意并退款完成】,售后单状态为【完成】")
private Byte createEvent;
@ApiModelProperty(value = "扩展字段")
private String extInfo = "{}";
@ApiModelProperty(value = "订单是否需要挂起,默认挂起")
private boolean suspended = true;
}
......@@ -15,7 +15,7 @@ import org.apache.commons.lang.StringUtils;
*/
public class CancelOrderRequestAdapter {
public static CancelOrderRequest convert(OrderInfoReqs order, String refundId, AfterSalesType afterSalesType, String reason, Boolean refundDeliveryFee, Byte refundMode) {
public static CancelOrderRequest convert(OrderInfoReqs order, String refundId, AfterSalesType afterSalesType, String reason, String remark, Boolean refundDeliveryFee, Byte refundMode) {
CancelOrderRequest req = new CancelOrderRequest();
req.setOrderId(order.getOrderCode());
req.setPartnerId(order.getPartnerId());
......@@ -36,7 +36,7 @@ public class CancelOrderRequestAdapter {
}
// 这里给默认值,外面调用者 自己的根据业务判断退款 状态
req.setRefundState(AfterSalesRefunStateEnum.STATE_1.getIndex());
req.setReqRemark(reason);
req.setReqRemark(remark);
req.setRefundDeliveryAmount(refundDeliveryFee);
// 商城订单 增加拓展信息
CancelOrderRequest.AfterSalesOrderExtInfoReq ext = new CancelOrderRequest.AfterSalesOrderExtInfoReq();
......
package cn.freemud.adapter;
import com.alibaba.fastjson.JSON;
import com.freemud.application.sdk.api.ordercenter.enums.AfterSalesType;
import com.freemud.application.sdk.api.ordercenter.response.orderInfo.OrderInfoReqs;
import com.freemud.sdk.api.assortment.order.enums.AfterSalesRefunStateEnum;
import com.freemud.sdk.api.assortment.order.enums.OperationClientEnum;
import com.freemud.sdk.api.assortment.order.request.order.CancelOrderRequest;
import com.freemud.sdk.api.assortment.order.request.order.V2CancelOrderRequest;
import org.apache.commons.lang.StringUtils;
import java.math.BigDecimal;
public class V2CancelOrderRequestAdapter {
public static V2CancelOrderRequest convert(OrderInfoReqs order, Long refundAmount, AfterSalesType afterSalesType, String reason, String remark, Boolean refundDeliveryFee, Byte refundMode) {
V2CancelOrderRequest req = new V2CancelOrderRequest();
req.setPartnerId(order.getPartnerId());
req.setOperator(order.getUserName());
if (AfterSalesType.SYSTEM_CANCEL.getIndex().equals(afterSalesType.getIndex())) {
req.setOperator("admin");
req.setOperationClient(OperationClientEnum.STATE_6.getIndex().byteValue());
}
req.setOrderCode(order.getOrderCode());
req.setReqAmount(new BigDecimal(refundAmount));
req.setOrderClient(order.getOrderClient().byteValue());
req.setOperationClient(OperationClientEnum.STATE_5.getIndex().byteValue());
if (StringUtils.isNotBlank(reason) && reason.length() > 50) {
reason = reason.substring(0, 50);
}
req.setAfterSalesReason(reason);
req.setCancelReason(reason);
req.setReqRemark(remark);
req.setAfterSalesType(afterSalesType.getIndex().byteValue());
// 这里给默认值,外面调用者 自己的根据业务判断退款 状态
req.setRefundState(AfterSalesRefunStateEnum.STATE_1.getIndex().byteValue());
req.setRefundDeliveryAmount(refundDeliveryFee);
// 商城订单 增加拓展信息
CancelOrderRequest.AfterSalesOrderExtInfoReq ext = new CancelOrderRequest.AfterSalesOrderExtInfoReq();
ext.setRefundMode(refundMode);
req.setExtInfo(JSON.toJSONString(ext));
return req;
}
}
......@@ -248,7 +248,7 @@ public class OrderController {
// 微商城因为没有退款原因选项 所以将用户退款说明用户作为退款原因
String reason = StringUtils.isBlank(reqVo.getReason())
? reqVo.getRemarks() : reqVo.getReason();
refundService.refundOrder(reqVo.getPartnerId(), reqVo.getOid(), reason, reqVo.getRefundMode());
refundService.refundOrder(reqVo.getPartnerId(), reqVo.getOid(), reqVo.getRefundAmount(), reason, reqVo.getRemarks(), reqVo.getRefundMode());
return ResponseUtil.success();
}
......
......@@ -43,6 +43,11 @@ public class OrderRefundVo {
private String partnerId;
/**
* 退款金额
*/
private Long refundAmount;
/**
* 微商城退款方式
*
* @see RefundModeEnum#getIndex()
......
......@@ -15,6 +15,7 @@ import cn.freemud.entities.dto.pay.QueryInvoiceByCodesRequest;
import cn.freemud.entities.vo.QueryInvoiceReq;
import cn.freemud.entities.vo.QueryRefundFailuresListReq;
import cn.freemud.entities.vo.RefundFailuresSuccessfulReq;
import com.freemud.sdk.api.assortment.order.request.order.V2CancelOrderRequest;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.http.MediaType;
import org.springframework.web.bind.annotation.PostMapping;
......@@ -90,4 +91,8 @@ public interface OrderServiceClient {
@PostMapping(value = "/order/config/queryByKeys")
BaseResponse<List<QueryByKeysResp>> queryByKeys(@RequestBody QueryByKeysReq req);
@LogIgnoreFeign(logMessage="createInvoice")
@PostMapping("/order/v2/cancelPortion")
BaseResponse<Void> refundOrder(@RequestBody V2CancelOrderRequest v2CancelOrderRequest);
}
......@@ -90,19 +90,20 @@ public class PaymentHandle {
public PayRefundResponse getCommonPayRefundResponse(OrderManagerRequest request, OrderBeanV1 orderBean) {
PayRefundResponse refundResponse;
try {
BigDecimal refundAmount = getRefundAmount(orderBean.getCompanyId(), new BigDecimal(orderBean.getAmount()), orderBean.getOid());
if (null != orderBean.getOrderPayItem() && orderBean.getOrderPayItem().size() > 0) {
// payment/application/refund
refundResponse = this.multiRefund(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), getRefundAmount(orderBean));
refundResponse = this.multiRefund(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), refundAmount);
} else {
OrderExtendedReq extended = orderBean.getOrderExtended();
if (StringUtils.isNotBlank(extended.getAgentPayerId()) && !Objects.equals(extended.getAgentPayerId(), orderBean.getUserId())) {
OrderExtInfoDto ext = JSON.parseObject(orderBean.getExtInfo(), OrderExtInfoDto.class);
//代付人信息不为空 并且和订单创建人不一样,表示代付单 payment/application/agentRefund
refundResponse = this.agentPayRefund(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), getRefundAmount(orderBean), ext.getPayTransId());
refundResponse = this.agentPayRefund(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), refundAmount, ext.getPayTransId());
} else {
//正常订单现金退款 paymentcenter/refund
PayRefundRequestDto req = paymentSdkAdapter.getOrderRefundRequest(orderBean.getCompanyId(), orderBean.getShopId(),
orderBean.getOid(), getRefundAmount(orderBean), orderBean.getPayVoucher(), orderBean.getExtInfo(), request.getReason());
orderBean.getOid(), refundAmount, orderBean.getPayVoucher(), orderBean.getExtInfo(), request.getReason());
// 抖音订单,退款时需要传递商品信息
if (OrderClientType.TIKTOKPAY.getIndex().toString().equals(orderBean.getOrderClient())) {
Map<String, String> extParam = new HashMap<>();
......@@ -142,19 +143,20 @@ public class PaymentHandle {
public PayRefundResponse getCommonPayRefundResponse(OrderInfoReqs order, String reason) {
PayRefundResponse refundResponse;
try {
BigDecimal refundAmount = getRefundAmount(order.getPartnerId(), order.getActualPayAmount(), order.getOrderCode());
if (CollectionUtils.isNotEmpty(order.getOrderPayItemCreateReqList())) {
// payment/application/refund
refundResponse = this.multiRefund(order.getPartnerId(), order.getStoreId(), order.getOrderCode(), order.getActualPayAmount());
refundResponse = this.multiRefund(order.getPartnerId(), order.getStoreId(), order.getOrderCode(), refundAmount);
} else {
OrderExtendedReq extended = order.getOrderExtended();
if (StringUtils.isNotBlank(extended.getAgentPayerId()) && !Objects.equals(extended.getAgentPayerId(), order.getUserId())) {
OrderExtInfoDto ext = JSON.parseObject(order.getExtInfo(), OrderExtInfoDto.class);
//代付人信息不为空 并且和订单创建人不一样,表示代付单 payment/application/agentRefund
refundResponse = this.agentPayRefund(order.getPartnerId(), order.getStoreId(), order.getOrderCode(), order.getActualPayAmount(), ext.getPayTransId());
refundResponse = this.agentPayRefund(order.getPartnerId(), order.getStoreId(), order.getOrderCode(), refundAmount, ext.getPayTransId());
} else {
//正常订单现金退款 paymentcenter/refund
PayRefundRequestDto req = paymentSdkAdapter.getOrderRefundRequest(order.getPartnerId(), order.getStoreId(),
order.getOrderCode(), order.getActualPayAmount(), order.getPayRequestNo(), order.getExtInfo(), reason);
order.getOrderCode(), refundAmount, order.getPayRequestNo(), order.getExtInfo(), reason);
// 抖音订单,退款时需要传递商品信息
if (OrderClientType.TIKTOKPAY.getIndex().equals(order.getOrderClient())) {
Map<String, String> extParam = new HashMap<>();
......@@ -355,8 +357,9 @@ public class PaymentHandle {
public PayRefundResponse refund(String reason, OrderBeanV1 orderBean) {
PayRefundStatus refundStatus = PayRefundStatus.SUCCESS;
BigDecimal refundAmount = getRefundAmount(orderBean.getCompanyId(), new BigDecimal(orderBean.getAmount()), orderBean.getOid());
PayRefundRequestDto orderRefundRequest = paymentSdkAdapter
.getOrderRefundRequest(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), getRefundAmount(orderBean), orderBean.getPayVoucher(), orderBean.getExtInfo(), reason);
.getOrderRefundRequest(orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getOid(), refundAmount, orderBean.getPayVoucher(), orderBean.getExtInfo(), reason);
if (ObjectUtils.equals(orderBean.getAmount(), 0L)) {
return handlePayRefundResponse(refundStatus, orderRefundRequest.getRefundId());
}
......@@ -413,12 +416,13 @@ public class PaymentHandle {
/**
* 获取退款金额
*
* @param data
* @return
* @param partnerId 商户号
* @param refundAmount 总金额
* @param orderId 订单号
* @return 退款金额
*/
private BigDecimal getRefundAmount(OrderBeanV1 data) {
BigDecimal refundAmount = new BigDecimal(data.getAmount());
OrderBaseResp<List<AfterSalesOrderResp>> listBaseResponse = orderSdkService.queryAfterSaleByOrderCode(data.getCompanyId(), data.getOid());
private BigDecimal getRefundAmount(String partnerId, BigDecimal refundAmount, String orderId) {
OrderBaseResp<List<AfterSalesOrderResp>> listBaseResponse = orderSdkService.queryAfterSaleByOrderCode(partnerId, orderId);
if (CollectionUtils.isNotEmpty(listBaseResponse.getResult())) {
refundAmount = new BigDecimal(listBaseResponse.getResult().get(0).getActualAmount());
}
......
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