同城外卖小程序风控方案:重复下单、异常订单识别模块开发
一、小程序外卖风控面临的业务问题
同城外卖小程序的下单链路短、用户点击频繁,网络抖动、重复点击、支付回调重试都容易产生重复下单,造成重复扣款、多生成订单、商家出餐混乱。同时还存在恶意刷单、虚假下单、跨设备批量下单、地址位置异常等风险订单。中小同城平台一般不适合重型实时风控集群,需要一套轻量化、可配置、低运维成本的风控模块,区分正常用户误操作和恶意异常订单,兼顾用户体验和平台资金安全。
二、风控模块整体架构设计
整体采用前置校验+规则识别+后置复核三层架构,嵌入下单主流程:
- 前置层:幂等校验、限流、防重提交,拦截重复下单请求;
- 规则引擎层:多维度特征判断,命中风险规则后标记风险等级,分为直接拦截、人工审核、正常放行三类;
- 后置复核层:订单入库后异步扫描,定时任务补扫漏判异常单,记录风控日志、风险台账。
数据存储选用Redis做临时风控计数、幂等锁;MySQL持久化风控规则、风控日志、风险订单记录;小程序端采集设备指纹、定位信息,作为风控特征传入后端。
三、重复下单防重实现(幂等+分布式锁)
防重复下单核心依靠幂等Token,小程序进入确认下单页时后端下发唯一幂等键,用户提交订单时携带该key。后端优先在Redis校验,再配合数据库唯一索引兜底,避免网络重试、前端重复点击产生重复订单。
@Service
public class OrderIdempotentService {
@Resource
private RedisTemplate<String, Object> redisTemplate;
private static final String IDEM_KEY_PREFIX = "order:idem:";
private static final long EXPIRE_SECONDS = 300;
public boolean checkIdempotent(String idempotentKey) {
String redisKey = IDEM_KEY_PREFIX + idempotentKey;
Boolean success = redisTemplate.opsForValue().setIfAbsent(redisKey, "1", EXPIRE_SECONDS, TimeUnit.SECONDS);
if (Boolean.TRUE.equals(success)) {
return true;
}
return false;
}
}
下单接口入口先调用该方法校验,校验失败直接返回“请勿重复提交订单”;同时订单表增加幂等字段唯一索引,作为最后一层兜底防护,防止Redis缓存异常导致的重复写入。
四、异常订单识别维度与规则配置
异常订单识别采用可配置规则,后台支持动态开关阈值,不需要修改代码发布。识别特征主要分为四类:
- 用户行为特征:短时间下单频次过高、连续下单后立刻取消、高频退款;
- 设备与网络特征:同一设备多账号下单、同一IP短时间大量下单、设备指纹异常;
- 地理位置特征:下单定位和收货地址距离偏差过大、超出平台配送范围下单;
- 订单业务特征:订单金额异常、优惠券叠加超出规则、同一商家短时间多单自提。
风险等级划分:低风险标记日志放行;中风险进入人工审核队列,订单暂不推送商家;高风险直接拦截下单。
五、风控规则执行与风险标记代码示例
@Service
public class OrderRiskCheckService {
// 简单频次风控:同一用户1分钟最多3次下单
public RiskResult checkUserFrequency(Long userId) {
String freqKey = "order:risk:freq:" + userId;
Long count = redisTemplate.opsForValue().increment(freqKey, 1);
if (count == 1) {
redisTemplate.expire(freqKey, 60, TimeUnit.SECONDS);
}
if (count > 3) {
return RiskResult.builder().risk(true).riskLevel(2).msg("下单过于频繁,请稍后重试").build();
}
return RiskResult.ok();
}
}
所有风控校验结果统一写入风控日志,记录订单号、用户ID、设备指纹、命中规则、风险等级、处理动作,方便后续对账和问题复盘。
六、风控白名单、黑名单与灰度策略
平台运营后台维护风控黑白名单,商家测试账号、内部运营账号可以加入白名单,跳过部分频次校验;多次恶意下单、刷单账号加入黑名单,直接拦截下单。
规则上线采用灰度策略,新规则先标记日志不拦截,观察一段时间误判率,确认误判在可接受范围,再开启拦截动作,避免误伤正常用户。
七、风控告警与定时补偿扫描机制
实时风控只能拦截下单阶段请求,部分异常在订单生成后才暴露,需要定时任务轮询订单表,扫描已支付、待接单状态订单,二次校验风险特征。
对于命中高风险的已支付订单,系统自动告警推送给运营,支持自动发起退款或人工介入核实;风控看板统计拦截量、审核量、误判量,持续调整阈值。
八、总结
同城外卖小程序的风控模块,核心分为重复下单拦截和多维度异常订单识别两大块,优先使用幂等Token+Redis分布式锁解决重复提交问题,再通过轻量化规则引擎,基于用户、设备、地理位置、订单业务特征识别异常订单。这套方案不需要引入复杂流计算组件,适合中小同城外卖平台,规则可配置、日志可追溯,同时搭配灰度上线、黑白名单机制控制误判。风控不是一次性开发完成,需要持续根据平台订单数据调整阈值,平衡拦截效果和用户体验,降低刷单、重复下单带来的资金和履约风险。