作者:肖哲彬
部门:营销中心
引言
生活中商家经常会遇到这样的问题:订单退款后优惠券没有被回收、退款过程中商家对营销资产没有直观的感知、黑产党尝试薅商家资产羊毛等,给商家造成了不好的体验。为了解决商家的上述难题,我们构建了营销逆向域,负责各种营销资产的逆向操作业务,包括资产的冻结、解冻、回收等能力。
一、业务形态
在一次实际营销场景中,商家设置了一种满10元送优惠券的活动,而后消费者下了一笔20元的订单得到了一张优惠券,然后申请了订单全额退款,商家希望能回收优惠券;而另一位消费也花了20元,只申请5元的部分退款,商家表示订单达到了门槛,不打算回收券。这是最基础的一个业务场景,营销逆向域就是处理该券的逆向操作,我们关心触发逆向的条件和对应的营销资产种类。
1.1 营销资产种类
营销资产是指订单满足某些营销活动的门槛后由营销系统发放给消费者的虚拟资产或权益。常见的营销资产有优惠券、优惠码、积分、储值金等;虚拟权益有砍价,助力,抽奖等(消费者在消费后可以获得一定的资格参与其他互动类的活动),各种营销资产的存在有利于促进消费者回购,帮助商家稳定客源,在电商系统中扮演者重要角色。
按虚拟资产的价值属性区分,可分为金本位资产和普通资产。店铺储值就是典型的金本位资产,还有现金红包、京豆等,这类资产的特点是与资金直接挂钩,均可直接用来无门槛消费。而普通资产如优惠券、积分等,本身不与资金直接相关,其营销价值大于资产价值。对于金本位资产的逆向操作会更加严肃一些,普通资产的风险控制更多得由商家去操作。按资产价值区分如下图:
1.2 触发的条件
在买家申请退款时,需要冻结营销资产;买家撤销退款或各种关单场景,需要解冻资产;商家同意退款,退款完成需要回收资产;买家修改退款单时需要看申请金额的变化,来决定冻结还是解冻资产。门槛需要与正向发放的门槛需要保持一致,即不足发放门槛时,需要处理资产。关于冻结解冻回收状态机如下图所示:
在理解触发条件和营销资产后,我们可以构建我们的系统。在整个交易链路中,营销逆向系统在中台的位置处于逆向链路下游,在用户下单行为完成后并且发生退款才会可能涉及,系统特点是流量不高但对计算精准性有很高要求,中台的位置如下图所示:
由产品同学配置好活动的逆向规则,在实际退款执行时按配置的规则执行。下单链路会提供活动的快照信息,包括优惠门槛、发放资产等。营销逆向域依赖于有赞规则引擎,负责底层组件的调用,最终通过发放中心异步操作资产,一次退款的主要业务流程如下图所示:
二、模型构建
为了保持领域层(domain)整洁,只依赖内部的common包,依赖层(dependency)和基础设施层(infrastructure)通过依赖倒置的方式依赖于领域层,屏蔽了外围的接口实现。上游应用层(application)以拓展点的形式接入交易系统,处理请求和外部查询。参考DDD的规范,我们有如下包结构:
2.1 领域设计
领域模型需要保证高内聚低耦合,有对应的行为支撑模型的属性,以下列举主要的几个模型:
实体(Entity):
- 商品(goods):包括订单中的商品、活动参与商品和退款商品,具有商品各种计算能力,如判断商品的剩余金额,商品之间各种逻辑关系等。
- 资产(equity):各类虚拟资产的统一抽象,一般来自正向的快照信息,提供资产操作的行为和各种统计视图。
- 门槛(conditionTable):抽象活动的发放规则条件,由正向的snapshot解析而来。提供通用化的参数转化行为。
值对象(ValueObject):
- 订单(order):上游交易告知的订单信息,包括订单商品,金额等信息。
- 退款单(refundOrder):同样由交易产生,包括了申请退款的商品,申请的退款金额,件数以及可退金额等信息。
聚合根(Aggregate):
- 活动聚合(refundActivity):对门槛、商品和资产实体做一个整体的聚合,抽象成一个退款活动,对外做统一操作,边界清晰。
服务(Service):
- 在领取层统一提供refundService服务,提供三种能力:计算抵扣金额,资产逆向操作以及订单资产信息查询。
上下文(Context):
- RefundContext:逆向域的上下文信息,包括订单退款单等,在有赞规则引擎中提供上下文服务。
2.2 正逆向领域映射
在开发过程中我们面临这样的问题:正向域产生的优惠快照(snapshot)在逆向域无法被识别,原因是不同领域之间底层数据不互通,使得逆向域解析正向模型时变得十分困难。我们采用模型关系映射的方式,解决不同领域间模型和参数的转化问题。以满X条件模型为例,正向模型有两个参数amountAt和amount分别对应满多少元(件)和实际多少元(件),还有两个optionBind绑定条件:amountPrice和amountNum分别表示满多少元和满多少件,这是一个高度抽象灵活的模型,不同参数绑定表示了不同业务含义,但带来了很多问题,比如满多少元和满多少件的业务校验逻辑不同,在流程中除了要关心模型本身是什么更要关心模型绑定的参数,破坏了内聚的原则;再如在用户仅退款退款场景中,是没有件数信息的,存在特殊的产品逻辑。所以在逆向域构建过程中,我们采用含义清晰的积木。实际映射配置如下:
代码语言:javascript复制 <identification name="ump.refund.setting.amount.num.resource">
<params>
<param key="amountNum">
<mapping domain="UMP" meta_id="ump.pbb.condition.amountOver" bind="amountNum"/>
</param>
</params>
</identification>
identification
标签定义了受体模型, params
定义了这个模型下的参数列表, key
定义模型下的参数名, mapping
定义了参数值的来源,从哪个领域( domain
)的哪个模型( meta_id
)中取哪个绑定( bind
)或者参数( value
)。
通过定义模型映射关系,我们可以直接把A领域的模型转换成B领域的模型(包含参数),省去了业务自己去解析积木,转换参数,再构建的过程,提高开发效率。
三、思考
存在正逆向的门槛条件不同业务需求,比如虽然下单满足指定金额送优惠券,但只要发生退款即回收券,这种情况下逆向的门槛条件高于正向,又或者订单金额全退才回收优惠券等,未来逆向域考虑提供通用的退款模板,只需配置“AtOnce”或者“All”这样的普通条件就可实现条件判断。此外,逆向域作用范围可以再拓展,涉及退款退虚拟资产的业务都可以接入,例如充值储值卡送优惠券,用户退储值账户,也可以接入营销逆向域。最后,金本位资产的逆向流程接入也十分重要。
在逆向域诞生之前,营销活动通过监听退款消息来做逻辑,杂糅在系统各个组件中,非常不利于管理和维护。新系统打散了活动的概念,抽象出各种规则,使退款不再依赖于具体业务,而依赖于各种配置的规则。
结语
本文介绍了营销逆向域的业务形态,以及逆向域的领域实践,解决了资产的逆向回收问题,支持多种退款场景,支持不同业务规则,实现了逆向流程配置化。总体来说,相比于下单域,逆向属于比较稳定的领域,易于收拢业务、方便制定规则、能力可以复用。但在领域设计上还可以更加抽象,未来将更多地与中台其他系统联动,接入更多需求。