有赞营销逆向域的探索与实践

2020 年 10 月 15 日

有赞营销逆向域的探索与实践

引言

生活中商家经常会遇到这样的问题:订单退款后优惠券没有被回收、退款过程中商家对营销资产没有直观的感知、黑产党尝试薅商家资产羊毛等,给商家造成了不好的体验。为了解决商家的上述难题,我们构建了营销逆向域,负责各种营销资产的逆向操作业务,包括资产的冻结、解冻、回收等能力。

一、业务形态

在一次实际营销场景中,商家设置了一种满 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 分别表示满多少元和满多少件,这是一个高度抽象灵活的模型,不同参数绑定表示了不同业务含义,但带来了很多问题,比如满多少元和满多少件的业务校验逻辑不同,在流程中除了要关心模型本身是什么更要关心模型绑定的参数,破坏了内聚的原则;再如在用户仅退款退款场景中,是没有件数信息的,存在特殊的产品逻辑。所以在逆向域构建过程中,我们采用含义清晰的积木。实际映射配置如下:

复制代码
<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”这样的普通条件就可实现条件判断。此外,逆向域作用范围可以再拓展,涉及退款退虚拟资产的业务都可以接入,例如充值储值卡送优惠券,用户退储值账户,也可以接入营销逆向域。最后,金本位资产的逆向流程接入也十分重要。

在逆向域诞生之前,营销活动通过监听退款消息来做逻辑,杂糅在系统各个组件中,非常不利于管理和维护。新系统打散了活动的概念,抽象出各种规则,使退款不再依赖于具体业务,而依赖于各种配置的规则。

结语

本文介绍了营销逆向域的业务形态,以及逆向域的领域实践,解决了资产的逆向回收问题,支持多种退款场景,支持不同业务规则,实现了逆向流程配置化。总体来说,相比于下单域,逆向属于比较稳定的领域,易于收拢业务、方便制定规则、能力可以复用。但在领域设计上还可以更加抽象,未来将更多地与中台其他系统联动,接入更多需求。

本文转载自公众号有赞 coder(ID:youzan_coder)。

原文链接

有赞营销逆向域的探索与实践

2020 年 10 月 15 日 10:00 461

评论

发布
暂无评论
发现更多内容

Week13 总结

张磊

第13周数据分析

陆不得

架构师训练营——第13周作业

jiangnanage

架构师训练营-week13-学习总结

晓-Michelle

极客大学架构师训练营

PHP配置管理-yaconf

Dnnn

php

关于第四次财富狂潮的思考,区块链如猛虎出笼?

CECBC区块链专委会

比特币 区块链 数字货币

ZIP 也能边下载边解压?优酷流式解压技术揭秘

阿里文娱技术团队

ZIP

PageRank

GalaxyCreater

第13周学习总结

刘卓

synchronized实现原理及代码证明各种锁

Darren

源码 synchronized 轻量级锁 偏向锁 Monitor

GO 语言交叉编译

Dnnn

go

week13 小结

Geek_196d0f

windows10 CUDA环境搭建

yuanhang

tensorfl

Spring 5 中文解析核心篇-集成测试之TestContext(中)

青年IT男

Spring5 JUnit

GO 语言超时实现

Dnnn

go

第13周作业

刘卓

Go语言 sync.Mutex 源码分析

Dnnn

go

Docker Compose 搭建 Redis Cluster 集群环境

哈喽沃德先生

redis Docker Docker-compose redis集群 redis cluster

从零开始搭建完整的电影全栈系统(三)——restfulApi的编写

刘强西

RESTful 电影api

oeasy 教您玩转linux 之 010209 装酷利器 hollywood

o

开始编译第一个typescript实例

程序员学院

typescript 前端 JavaScripte

公有云常用数据分析指标

张磊

MySQL中修改数据表存储引擎的三种方法

Matrix Chan

MySQL 运维 数据表引擎

【在云端 003】 星星之火,可以燎原——云时代的IoT

Bora.Don

云计算 IoT AIOT

java安全编码指南之:Number操作

程序那些事

java安全编码 java安全 安全编码规范

云栖大会边缘计算分论坛倒计时7天,这2点值得期待

巨侠说

边缘计算

PHP Db类强制读主库(master)的设计

Dnnn

php MySQL

GO 语言异常处理

Dnnn

go

遇到银河提现不了网站维护审核怎么办?

丛林里的余光

数据库 网站平台 提现

大数据思考

朱月俊

达达双云双活实践

达达集团运维团队

openresty 微服务治理 多云架构 双活容灾 原生容器

有赞营销逆向域的探索与实践-InfoQ