电商项目-统一下单
在介绍这篇文章之前我们先了解一下
Q1.什么是统一下单
大家如果做过微信、支付宝支付的话,那一定用过统一下单这个接口。
这里我们以微信支付为例
微信支付文档:https://pay.weixin.qq.com/wiki/doc/api/index.html
在trade_type参数中我们有很多中选择,不同的参数代表我们不同的场景,不同的场景校验的参数以及链路是不同的,比如在小程序、微信内置支付需要传递OpenId
Q2.统一下单解决了什么
提供了一个清晰对外的接口,根据传入不同的参数来决定不同的链路方向以及返回不同的结果
电商应用场景
在电商项目中,我们也会有统一下单的场景,比如我们有普通商品、新用户专享活动商品、会员用户专享活动商品、而活动商品是基于普通商品转换过来的(可能这里说的比较抽象,给大家上一幅简易的图来解释)
t_spu、t_sku表是所有商品的基础信息以及价格(简称为普通商品)
t_activity_prod表是活动商品信息,引入基础表的spu_id、sku_id
。但活动商品的价格(price)、库存(stock)则需要独立添加,因为在电商项目中,活动商品的价格比普通商品更低,并且库存还有限制
不同订单不同走向
普通商品和活动商品订单流程也是不同的,这里以支付回调后的清算为例子(参考下图)
普通商品清算后需要核销使用的优惠券和积分
活动商品清算则需要核销新人或新会员的专享机会(假设只能购买一次)
代码中如何实现
在电商项目中一个支付成功订单的生成分为三步
【确认订单】、【提交订单并支付】、【订单支付回调】
废话不多说,我们直接开搞!前方高能!!!!!前方高能!!!!!前方高能!!!!!
/**
* 统一订单支付服务 2020年12月30日 13点49分
*
* @author bandari
*/
public interface OrderServiceFactory {
/**
* 统一确认订单
*
* @param configOrderBo 统一确认订单入参
* @return 统一确认订单出参
*/
UnifiedConfigOrderVo unifiedConfigOrder(UnifiedConfigOrderBo configOrderBo);
/**
* 统一提交订单
*
* @param submitOrderBo 统一提交订单入参
* @return 统一提交订单出参
*/
UnifiedSubmitOrderVo unifiedSubmitOrder(ConfigOrderDTO configOrderDTO);
/**
* 统一订单支付成功后的事件处理
*
* @param paySuccessOrderBo 支付成功订单入参
* @return 支付成功订单出参
*/
UnifiedPaySuccessOrderVo unifiedPaySuccessOrder(UnifiedPaySuccessOrderBo paySuccessOrderBo);
/**
* 统一订单退款成功后的事件处理
*
* @param refundSuccessOrderBo 退款成功订单入参
* @return 退款成功订单出参
*/
UnifiedRefundSuccessOrderVo unifiedRefundSuccessOrder(
UnifiedRefundSuccessOrderBo refundSuccessOrderBo);
普通订单、新人专享订单、新会员订单重写这个接口
/**
* 普通订单服务
* 注意这里的orderServiceFactory1
* @author bandari
*/
@Slf4j
@Service("orderServiceFactory1")
public class OrdinaryOrderServiceFactoryImpl implements OrderServiceFactory {
@Override
public UnifiedConfigOrderVo unifiedConfigOrder(UnifiedConfigOrderBo configOrderBo) {
log.info("");
log.info("普通商品进行确认订单操作:{}", JSONUtil.toJsonStr(configOrderBo));
log.info("校验普通商品是否存在、库存是否充足等");
//这里用ThreadLocal 代替Redis
ConfigOrderDTO dto = new ConfigOrderDTO();
BeanUtils.copyProperties(configOrderBo, dto);
Map<String, ConfigOrderDTO> configOrderDTOMap = new HashMap<>(