代驾同城服务系统,分账与保险对接方案
代驾同城服务资金链路复杂,订单资金需要拆分平台服务费、司机收入、渠道佣金,同时出行意外险需要和订单生命周期联动,下单/接单触发投保、行程结束同步保单状态。分账和保险对接模块要保证资金流水可审计、分账规则可配置、投保异步可靠,隔离支付主流程,避免第三方接口异常阻塞订单。本文基于SpringBoot讲解分账模型、异步投保对接、对账与异常补偿方案。
后端技术栈:SpringBoot + MyBatis-Plus + Redis + RabbitMQ,分账、保险独立为finance-service。Redis缓存分账模板、保险产品配置;MQ异步处理投保、分账回调;支付渠道、保险服务商API通过统一客户端封装;资金流水、保单记录独立建表,和订单业务表解耦。
整体业务流程:用户支付订单全款后,支付回调通知财务模块;系统读取当前订单绑定的分账模板,生成分账明细,调用支付分账接口;同时消费订单接单事件,调用保险服务商接口发起投保,绑定订单、司机、乘客信息;保险回调更新保单状态;分账完成后生成分账流水;订单取消、行程提前终止时,触发退保或者保费按规则扣除;每日定时任务执行资金对账、保单对账,标记差异数据交由人工处理。
下面是分账明细生成、保险投保请求核心Java示例代码:
@Service public class OrderFinanceService { @Autowired private SplitRuleMapper splitRuleMapper; private SplitRecordMapper splitRecordMapper; private InsuranceRecordMapper insuranceRecordMapper; private PaySplitClient paySplitClient; private InsuranceApiClient insuranceApiClient; @Autowired private RabbitTemplate rabbitTemplate; /** * 生成分账明细并发起分账 */ @Transactional(rollbackFor = Exception.class) public ResultDTO<Void> createSplitAndExecute(Long orderId, BigDecimal totalAmount) { // 查询分账规则模板 SplitRule rule = splitRuleMapper.selectById(1L); SplitRecord splitRecord = new SplitRecord(); splitRecord.setOrderId(orderId); splitRecord.setTotalAmount(totalAmount); // 平台服务费 BigDecimal platformFee = totalAmount.multiply(rule.getPlatformRate()); // 渠道佣金 BigDecimal channelFee = totalAmount.multiply(rule.getChannelRate()); // 司机实收金额 BigDecimal driverIncome = totalAmount.subtract(platformFee).subtract(channelFee); splitRecord.setPlatformFee(platformFee); splitRecord.setChannelFee(channelFee); splitRecord.setDriverIncome(driverIncome); splitRecord.setSplitStatus(0); splitRecord.setCreateTime(LocalDateTime.now()); splitRecordMapper.insert(splitRecord); // 异步发起分账,避免同步阻塞 SplitDTO splitDTO = new SplitDTO(); splitDTO.setOrderId(orderId); splitDTO.setSplitNo(splitRecord.getId().toString()); splitDTO.setPlatformFee(platformFee); splitDTO.setChannelFee(channelFee); splitDTO.setDriverIncome(driverIncome); rabbitTemplate.convertAndSend("finance.split.exchange", "split.execute", splitDTO); return ResultDTO.success(); } /** * 发起代驾意外险投保 */ public ResultDTO<Void> applyInsurance(InsuranceDTO dto) { InsuranceRecord insuranceRecord = new InsuranceRecord(); insuranceRecord.setOrderId(dto.getOrderId()); insuranceRecord.setUserId(dto.getUserId()); insuranceRecord.setDriverId(dto.getDriverId()); insuranceRecord.setProductCode(dto.getProductCode()); insuranceRecord.setInsStatus(0); insuranceRecordMapper.insert(insuranceRecord); InsuranceApiReq req = new InsuranceApiReq(); req.setPolicyNo(insuranceRecord.getId().toString()); req.setUserName(dto.getUserName()); req.setIdCard(dto.getIdCard()); req.setStartTime(dto.getTripStartTime()); req.setEndTime(dto.getTripEndTime()); // 异步调用保险接口 rabbitTemplate.convertAndSend("insurance.apply.exchange", "insurance.send", req); return ResultDTO.success(); } }分账模板与资金模型设计,后台支持配置多套分账模板,区分普通订单、渠道推广订单、合作服务商订单。分账项包含平台技术服务费、渠道推广佣金、司机代驾服务费、保险代收保费。比例支持按比例或者固定金额配置,模板绑定服务类型,下单时自动匹配。所有资金明细提前落库,以预分账记录为准,不直接依赖第三方渠道返回结果。分账状态分为待分账、分账成功、分账失败、已退款回滚,失败订单支持人工重试分账。
分账安全与资金回滚机制,订单退款场景是分账核心难点。如果已经分账完成,需要调用分账回退接口,收回已经结算的资金;分账未执行则直接取消分账任务。每一次分账、回退都生成独立流水号,流水号和渠道分账单号一一映射。分账操作必须带上幂等号,防止重复分账造成资金多发。幂等号由订单ID+操作类型+时间戳组成,第三方渠道侧做幂等校验。
保险对接时序设计,代驾意外险不能过早投保,也不能遗漏。主流时序:司机接单成功之后触发投保,保障接驾+代驾全程;保障起止时间绑定行程预估时间,行程超时自动顺延。保险分为乘客险和司机险,可以单独配置是否开启。保险接口全部异步调用,投保失败不会阻断订单履约流程,后台定时任务重试投保;保单回调更新保单状态,保单号回写到保险记录表,用户订单详情页展示保单信息。
退保与批改逻辑,订单中途取消、司机改派,需要区分处理保险。未生效保单直接发起退保;已经生效短时间行程,按保险服务商规则判断是否支持退保;不支持退保的,保费正常结算。司机改派后,旧保单标记失效,系统重新为新司机发起投保,生成新保单记录。所有退保记录和原保单关联,留存退保回执。
异步回调与幂等处理,支付分账回调、保险回调接口都要做好幂等,以外部回执单号作为唯一判断依据。回调到达后,先校验签名,再更新本地状态;重复回调直接返回成功,不重复执行业务逻辑。回调失败、回执丢失的数据,对账任务会比对渠道对账单和本地流水,标记差异单。
对账补偿体系,每日凌晨启动对账任务,分为资金对账和保单对账。资金对账拉取支付渠道分账明细,和本地split_record比对,核对金额、状态;保单对账拉取保险服务商的每日保单清单,核对投保、退保、失效状态。差异数据进入异常工单,财务或者保险运营人工核查,支持手动触发重试、手动标记处理结果。
权限和审计设计,资金分账流水、保单信息属于敏感数据。司机只能查看自己的收入明细,看不到平台抽成和渠道佣金;用户只能查看自己的保单;财务管理员拥有完整分账流水、对账记录查看权限;保险运营查看保单台账。所有修改分账比例、人工重试分账、手动退保操作,记录操作人、操作时间、变更前后数据,形成审计日志。
上下游模块联动,支付模块支付成功事件触发预分账;司机接单事件触发投保;订单跟踪模块行程结束、取消事件触发退保或者分账回退;分账流水同步到财务台账模块,用于财务统计;保单信息在订单详情透出,安全追踪模块在安全事件里关联保单号,出现安全事故时快速调取保单材料。
异常场景处理,保险服务商接口超时、网络抖动,本地状态保持待投保,由定时任务多次重试,设置最大重试次数,超限后告警人工介入;支付渠道分账限流,同样走重试队列;订单退款时,如果部分分账项不支持回退,系统标记挂账,人工线下处理;身份证信息校验失败,投保直接失败,不影响代驾订单,给用户提示无保险保障。
分账与保险对接方案的核心,是把资金结算和保险履约做成独立的财务中台能力,和代驾调度、订单跟踪解耦。依靠预记录、异步调用、幂等、每日对账补偿,解决第三方接口不稳定、退款回滚复杂的痛点,保证资金合规、保险链路完整,降低平台资金风险和事故纠纷风险。