Commit 9029c5e9 by shuhu.hou@freemud.cn

Merge branch 'feature/20200117_核销券失败退款兼容'

parents 3df7f9f6 28f4d5e1
...@@ -2,6 +2,7 @@ package cn.freemud.service; ...@@ -2,6 +2,7 @@ package cn.freemud.service;
import cn.freemud.base.entity.BaseResponse; import cn.freemud.base.entity.BaseResponse;
import cn.freemud.entities.dto.CouponCodeVerificationProductDto; import cn.freemud.entities.dto.CouponCodeVerificationProductDto;
import cn.freemud.entities.dto.QueryOrdersResponseDto;
import cn.freemud.entities.vo.ActivityClassifyCouponBean; import cn.freemud.entities.vo.ActivityClassifyCouponBean;
import cn.freemud.enums.ActivityChannelEnum; import cn.freemud.enums.ActivityChannelEnum;
...@@ -20,4 +21,10 @@ public interface CouponActivityService { ...@@ -20,4 +21,10 @@ public interface CouponActivityService {
*/ */
BaseResponse verificationCoupon(ActivityChannelEnum activityChannelEnum, String couponCode, String oid, String partnerId, BaseResponse verificationCoupon(ActivityChannelEnum activityChannelEnum, String couponCode, String oid, String partnerId,
String storeId, String userId, List<CouponCodeVerificationProductDto> products, Integer discountPrice); String storeId, String userId, List<CouponCodeVerificationProductDto> products, Integer discountPrice);
/**
* 核销优惠券
* @param orderBean
*/
BaseResponse verificationCoupon(QueryOrdersResponseDto.DataBean.OrderBean orderBean);
} }
...@@ -2,6 +2,7 @@ package cn.freemud.service.impl; ...@@ -2,6 +2,7 @@ package cn.freemud.service.impl;
import cn.freemud.adapter.CouponAdapter; import cn.freemud.adapter.CouponAdapter;
import cn.freemud.base.entity.BaseResponse; import cn.freemud.base.entity.BaseResponse;
import cn.freemud.constant.ResponseCodeConstant;
import cn.freemud.entities.dto.*; import cn.freemud.entities.dto.*;
import cn.freemud.entities.vo.ActivityClassifyCouponBean; import cn.freemud.entities.vo.ActivityClassifyCouponBean;
import cn.freemud.entities.vo.ActivityCouponBean; import cn.freemud.entities.vo.ActivityCouponBean;
...@@ -10,8 +11,17 @@ import cn.freemud.service.CouponActivityService; ...@@ -10,8 +11,17 @@ import cn.freemud.service.CouponActivityService;
import cn.freemud.service.thirdparty.CouponClient; import cn.freemud.service.thirdparty.CouponClient;
import cn.freemud.service.thirdparty.CouponOfflineClient; import cn.freemud.service.thirdparty.CouponOfflineClient;
import cn.freemud.utils.LogUtil; import cn.freemud.utils.LogUtil;
import cn.freemud.utils.PropertyConvertUtil;
import cn.freemud.utils.ResponseUtil; import cn.freemud.utils.ResponseUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.freemud.application.sdk.api.log.ApiLog;
import com.freemud.application.sdk.api.log.ErrorLog;
import com.freemud.application.sdk.api.log.ThirdPartyLog;
import com.freemud.application.sdk.api.service.EmailAlertService;
import com.google.common.base.Throwables;
import com.google.gson.Gson; import com.google.gson.Gson;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils; import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
...@@ -30,12 +40,15 @@ public class CouponActivityServiceImpl implements CouponActivityService { ...@@ -30,12 +40,15 @@ public class CouponActivityServiceImpl implements CouponActivityService {
private CouponAdapter couponAdapter; private CouponAdapter couponAdapter;
@Autowired @Autowired
private CouponOfflineClient couponOfflineClient; private CouponOfflineClient couponOfflineClient;
@Autowired
private EmailAlertService emailAlertService;
private static Gson gson = new Gson(); private static Gson gson = new Gson();
@Override @Override
public BaseResponse verificationCoupon(ActivityChannelEnum activityChannelEnum, String couponCode, String oid, String partnerId, public BaseResponse verificationCoupon(ActivityChannelEnum activityChannelEnum, String couponCode, String oid, String partnerId,
String storeId, String userId, List<CouponCodeVerificationProductDto> products,Integer discountPrice) { String storeId, String userId, List<CouponCodeVerificationProductDto> products, Integer discountPrice) {
if (StringUtils.isNotBlank(couponCode)) { if (StringUtils.isNotBlank(couponCode)) {
CouponCodeVerificationDto couponCodeVerificationDto = couponAdapter.convert2CouponCodeVerificationDto(activityChannelEnum, couponCode, oid, partnerId, storeId, userId, products,discountPrice); CouponCodeVerificationDto couponCodeVerificationDto = couponAdapter.convert2CouponCodeVerificationDto(activityChannelEnum, couponCode, oid, partnerId, storeId, userId, products, discountPrice);
try { try {
//3.券核销 //3.券核销
CouponCodeResponseDto couponCodeResponseDto = couponOfflineClient.verification(couponCodeVerificationDto); CouponCodeResponseDto couponCodeResponseDto = couponOfflineClient.verification(couponCodeVerificationDto);
...@@ -51,4 +64,68 @@ public class CouponActivityServiceImpl implements CouponActivityService { ...@@ -51,4 +64,68 @@ public class CouponActivityServiceImpl implements CouponActivityService {
} }
return ResponseUtil.success(); return ResponseUtil.success();
} }
/**
* 核销优惠券
*
* @param orderBean
*/
@Override
public BaseResponse verificationCoupon(QueryOrdersResponseDto.DataBean.OrderBean orderBean) {
List<QueryOrdersResponseDto.DataBean.OrderBean.AccountBean> accountList = orderBean.getAccountList();
if (CollectionUtils.isEmpty(accountList) || CollectionUtils.isEmpty(orderBean.getProductList())) {
return ResponseUtil.success();
}
for (QueryOrdersResponseDto.DataBean.OrderBean.AccountBean accountBean : accountList) {
List<CouponCodeVerificationProductDto> products = new ArrayList<>();
//商品券核销核销参数
if (OrderAccountType.PRODUCT_COUPON.getCode().equals(accountBean.getType())) {
for (int i = 0; i < orderBean.getProductList().size(); i++) {
QueryOrdersResponseDto.DataBean.OrderBean.ProductBean productBean = orderBean.getProductList().get(i);
String pid = StringUtils.isNotBlank(productBean.getSpecification()) ? productBean.getSpecification() : productBean.getProductId();
if (!org.springframework.util.CollectionUtils.isEmpty(orderBean.getProductList().get(i).getDiscountList())) {
List<QueryOrdersResponseDto.DataBean.OrderBean.ProductBean.ProductDiscount> discounts = orderBean.getProductList().get(i).getDiscountList().stream().
filter(productDiscount -> productDiscount.getDiscountId().equals(accountBean.getAccountId())).collect(Collectors.toList());
for (QueryOrdersResponseDto.DataBean.OrderBean.ProductBean.ProductDiscount productDiscount : discounts) {
if (productDiscount.getDiscountType() == null || productDiscount.getDiscountType() == 0) {
continue;
}
CouponCodeVerificationProductDto couponCodeVerificationProductDto = new CouponCodeVerificationProductDto();
couponCodeVerificationProductDto.setPID(pid);
couponCodeVerificationProductDto.setConsume_num(productDiscount.getDiscountQty());
couponCodeVerificationProductDto.setSeq(i + 1);
products.add(couponCodeVerificationProductDto);
}
}
}
}
Integer orderType = orderBean.getType();
ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeEnumConvert2ActivityChannel(orderType);
if (activityChannelEnum == null) {
activityChannelEnum = ActivityChannelEnum.pickup;
}
if (OrderAccountType.COUPON.getCode().equals(accountBean.getType())
|| OrderAccountType.PRODUCT_COUPON.getCode().equals(accountBean.getType())
|| OrderAccountType.DISCOUNT_COUPON.getCode().equals(accountBean.getType())) {
CouponCodeVerificationDto couponCodeVerificationDto = couponAdapter.convert2CouponCodeVerificationDto(activityChannelEnum, accountBean.getAccountId(), orderBean.getOid(), orderBean.getCompanyId(), orderBean.getShopId(), orderBean.getUserId(), products, accountBean.getPrice().intValue());
try {
//3.券核销
CouponCodeResponseDto couponCodeResponseDto = couponOfflineClient.verification(couponCodeVerificationDto);
ThirdPartyLog.infoConvertJson(System.currentTimeMillis(), System.currentTimeMillis(), "/api", couponCodeVerificationDto, couponCodeResponseDto);
if (!Objects.equals(couponCodeResponseDto.getStatusCode(), ResponseResult.SUCCESS.getCode())) {
emailAlertService.sendEmailAlert("核销券码失败", String.format("request:%s \r\nresponse:%s", JSONObject.toJSONString(couponCodeVerificationDto), JSONObject.toJSONString(couponCodeResponseDto)));
return ResponseUtil.error(ResponseResult.COUPON_VERIFICATION_FAIL);
}
} catch (Exception ex) {
emailAlertService.sendEmailAlert("核销券码异常", String.format("request:%s \r\nexception:%s", JSONObject.toJSONString(couponCodeVerificationDto), Throwables.getStackTraceAsString(ex)));
ErrorLog.printErrorLog("verification_error", "/api", couponCodeVerificationDto, ex);
return ResponseUtil.error(ResponseResult.COUPON_VERIFICATION_FAIL);
}
}
}
return ResponseUtil.success();
}
} }
...@@ -97,6 +97,7 @@ import com.freemud.sdk.api.assortment.order.request.order.*; ...@@ -97,6 +97,7 @@ import com.freemud.sdk.api.assortment.order.request.order.*;
import com.freemud.sdk.api.assortment.order.response.order.*; import com.freemud.sdk.api.assortment.order.response.order.*;
import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse; import com.freemud.sdk.api.assortment.order.response.payment.OrderPayResponse;
import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService; import com.freemud.sdk.api.assortment.order.service.OrderCenterSdkService;
import com.freemud.sdk.api.assortment.order.util.LockUtils;
import com.freemud.sdk.api.assortment.orderdistributor.entity.dto.PaymentMqMessageDto; import com.freemud.sdk.api.assortment.orderdistributor.entity.dto.PaymentMqMessageDto;
import com.freemud.sdk.api.assortment.orderdistributor.service.PaymentQueueService; import com.freemud.sdk.api.assortment.orderdistributor.service.PaymentQueueService;
import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest; import com.freemud.sdk.api.assortment.payment.request.UnifiedOrderRequest;
...@@ -127,6 +128,8 @@ public class OrderServiceImpl implements Orderservice { ...@@ -127,6 +128,8 @@ public class OrderServiceImpl implements Orderservice {
private final Integer RESPONSE_SUCCESS_CODE = 100; private final Integer RESPONSE_SUCCESS_CODE = 100;
private final String PAY_SUCCESS_KEY="pay_success_key:";
private static Gson gson = new Gson(); private static Gson gson = new Gson();
@Value("${saas.reverseNotifyiDcUrl}") @Value("${saas.reverseNotifyiDcUrl}")
...@@ -322,6 +325,11 @@ public class OrderServiceImpl implements Orderservice { ...@@ -322,6 +325,11 @@ public class OrderServiceImpl implements Orderservice {
@Override @Override
public String paySuccessCallback(PaysuccessNoticeMessage message) { public String paySuccessCallback(PaysuccessNoticeMessage message) {
//添加分布式锁,如果没有取得锁直接返回失败;整个方法执行完毕后会删掉该锁
if(!LockUtils.lockAfter(redisCache.getRedisTemplate(),PAY_SUCCESS_KEY+message.getTrans_id())){
return newSendPayFaileMessage();
}
ConfirmOrderDto confirmOrderDto = orderAdapter.convent2ConfirmOrderDto(message); ConfirmOrderDto confirmOrderDto = orderAdapter.convent2ConfirmOrderDto(message);
//首先判断当前订单号是否为围餐,围餐则需要截取掉订单最后一位数字 //首先判断当前订单号是否为围餐,围餐则需要截取掉订单最后一位数字
String orderId = redisCache.getValue(RedisCacheEnum.ORDER_CACHE_WEICAN_TRANSID_INFO.getCode() + confirmOrderDto.getOrderId()); String orderId = redisCache.getValue(RedisCacheEnum.ORDER_CACHE_WEICAN_TRANSID_INFO.getCode() + confirmOrderDto.getOrderId());
...@@ -360,11 +368,15 @@ public class OrderServiceImpl implements Orderservice { ...@@ -360,11 +368,15 @@ public class OrderServiceImpl implements Orderservice {
ruleId = orderExtInfoDto.getRuleId(); ruleId = orderExtInfoDto.getRuleId();
} }
} }
// 如果订单状态不是未支付,返回信息 // 如果订单状态不是未支付,返回信息
if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()) || !OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) { if (!PayStatus.NOT_PAY.getCode().equals(orderBean.getPayStatus()) || !OrderStatus.WAIT_PAY.getCode().equals(orderBean.getStatus())) {
return sendPaySuccessNoticeMessage(); return sendPaySuccessNoticeMessage();
} }
//核销优惠券,若核销失败直接退款
if (!ResponseResult.SUCCESS.getCode().equals(couponActivityService.verificationCoupon(orderBean).getCode())){
orderRefund(orderBean, "核销券异常退款", openid, oid);
return newSendPayFaileMessage();
}
// 订单失败后 发消息重试 待实现 // 订单失败后 发消息重试 待实现
String takeCode; String takeCode;
String daySeq; String daySeq;
...@@ -397,52 +409,7 @@ public class OrderServiceImpl implements Orderservice { ...@@ -397,52 +409,7 @@ public class OrderServiceImpl implements Orderservice {
takeCode = payAccessResponse.getData().getTakeCode(); takeCode = payAccessResponse.getData().getTakeCode();
daySeq = payAccessResponse.getData().getDaySeq(); daySeq = payAccessResponse.getData().getDaySeq();
//核销优惠券
List<OrderBean.AccountBean> accountList = orderBean.getAccountList();
if (CollectionUtils.isNotEmpty(accountList) && CollectionUtils.isNotEmpty(orderBean.getProductList())) {
for (OrderBean.AccountBean accountBean : accountList) {
List<CouponCodeVerificationProductDto> products = new ArrayList<>();
//商品券核销核销参数
if (OrderAccountType.PRODUCT_COUPON.getCode().equals(accountBean.getType())) {
for (int i = 0; i < orderBean.getProductList().size(); i++) {
OrderBean.ProductBean productBean = orderBean.getProductList().get(i);
String pid = StringUtils.isNotBlank(productBean.getSpecification()) ? productBean.getSpecification() : productBean.getProductId();
if (!org.springframework.util.CollectionUtils.isEmpty(orderBean.getProductList().get(i).getDiscountList())) {
List<OrderBean.ProductBean.ProductDiscount> discounts = orderBean.getProductList().get(i).getDiscountList().stream().
filter(productDiscount -> productDiscount.getDiscountId().equals(accountBean.getAccountId())).collect(Collectors.toList());
for (OrderBean.ProductBean.ProductDiscount productDiscount : discounts) {
if (productDiscount.getDiscountType() == null || productDiscount.getDiscountType() == 0) {
continue;
}
CouponCodeVerificationProductDto couponCodeVerificationProductDto = new CouponCodeVerificationProductDto();
couponCodeVerificationProductDto.setPID(pid);
couponCodeVerificationProductDto.setConsume_num(productDiscount.getDiscountQty());
couponCodeVerificationProductDto.setSeq(i + 1);
products.add(couponCodeVerificationProductDto);
}
}
}
}
Integer orderType = orderBean.getType();
ActivityChannelEnum activityChannelEnum = PropertyConvertUtil.orderTypeEnumConvert2ActivityChannel(orderType);
if (activityChannelEnum == null) {
activityChannelEnum = ActivityChannelEnum.pickup;
}
if (OrderAccountType.COUPON.getCode().equals(accountBean.getType())
|| OrderAccountType.PRODUCT_COUPON.getCode().equals(accountBean.getType())
|| OrderAccountType.DISCOUNT_COUPON.getCode().equals(accountBean.getType())) {
BaseResponse response = couponActivityService.verificationCoupon(activityChannelEnum, accountBean.getAccountId(),
orderBean.getOid(), partnerId, storeId, userId, products, accountBean.getPrice().intValue());
// 如果核销失败,退款
if (!ResponseCodeConstant.RESPONSE_SUCCESS_STR.equals(response.getCode())) {
orderRefund(orderBean, "订单异常退款", openid, oid);
return gson.toJson(message);
}
}
}
}
//TODO 清空购物车 //TODO 清空购物车
NewShoppingCartClearDto newShoppingCartClearDto = new NewShoppingCartClearDto(); NewShoppingCartClearDto newShoppingCartClearDto = new NewShoppingCartClearDto();
newShoppingCartClearDto.setPartnerId(partnerId); newShoppingCartClearDto.setPartnerId(partnerId);
...@@ -504,6 +471,8 @@ public class OrderServiceImpl implements Orderservice { ...@@ -504,6 +471,8 @@ public class OrderServiceImpl implements Orderservice {
} }
//支付回掉成功标记 //支付回掉成功标记
redisCache.save(RedisKeyConstant.KGD_PAYMENT_CALLBACK_FMID + message.getOut_trade_no(), message.getOut_trade_no(), 10L, TimeUnit.MINUTES); redisCache.save(RedisKeyConstant.KGD_PAYMENT_CALLBACK_FMID + message.getOut_trade_no(), message.getOut_trade_no(), 10L, TimeUnit.MINUTES);
//删除分布式锁
redisCache.delete("saas:lockAfter:"+PAY_SUCCESS_KEY+message.getTrans_id());
return sendPaySuccessNoticeMessage(); return sendPaySuccessNoticeMessage();
} }
......
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