Java生鲜电商平台-生鲜售后系统的退款架构设计与代码分享

说明:任何一个电商行业都涉及到退货与退款的问题,但是生鲜电商行业还设有一个显著的特点,那就是换货。在人性面前,各种各样的退货,退款,换货的售后问题,层出不穷,那么应该如何架构与设计呢?请看下文.

由于涉及到的东西比较多,目前只讲退款的架构设计与代码分享.

退款,是一个易造成负体验的业务产品。原因是商户对于退款的要求务必退款成功、高效、快,而且又得很好地支撑业务,否则就容易招来吐槽。

退款,一个看似简单,但充满复杂性的产品。

要想做好退款系统,我们必须深入的了解业务发展趋势,将客户诉求与现状业务结合起来;同时还需站在服务客户的角度,尽可能让客户降低操作,这样才有希望将退款系统打造好。

因此,笔者根据在Java生鲜电商平台独自负责退款系统的经验,让大家避免踩坑,向大家分享如何从0-1打造厉害的退款系统。

本文将从需求背景、需求分析,以及产品设计三个层面来阐述退款系统。

一、需求背景

在我接手退款系统之前,公司的退款系统是这样的:

1. 只支持订单全额退款;不支持部分退款;
2. 退款不退回交易手续费;
3. 退款请求的成功率超级低,不超过50%;
4. 上游通道不给力,内部系统也不给力,经常网络波动就退款失败,或者当日交易不足就退款失败,只能打回给商家,让其二次发起。

在以前允许直连模式的情况下,通道会有以下情况:

1)不提供退款接口;但有通道提供的商户后台;
2)提供退款接口,当日交易金额小于退款金额,则通道退款失败;有些细分到具体某个支付产品(如微信公众号)的当日交易金额小于退款金额,就退款失败;
网络原因波动,则通道没接收,则退款失败;
3)若风险订单,通道有时会先行扣款,再通知我们,因此我们需要让客户发起,但不经过上游渠道;
4)通道对账单与订单状态不一致,例如对账单成功,但是接口返回失败;

5. 给商户的退款接口不支持返回失败原因;
6. 经常性的遭到客户投诉退款效率问题;
7. 每次退款订单不支持系统自动审核,均需要人工审核。

所以当时接手这样的退款系统,内心是有点小崩溃的,感觉旧退款系统真是一无所能。

举几个栗子

1) 作为电商平台,购买两双鞋,对其中一双鞋不满意进行退款,然后我们不支持;
2) 客户做秒杀拼团活动,一做拼团,退款的并发不支持;不能退回支付手续费,平台含泪亏钱;
3)正常的全额退款订单,明明在支付公司申请成功,但是莫名之间将退款订单打回来,原因是

支付公司与上游通道不稳定。作为客户的认知是无法理解的,“明明退款申请成功,却为何退款失败回来呢??Are you kidding me?”

尽管知道是个坑,但还得义无反顾,因为作为产品经理,岗位职责就是得解决问题;而且越能体现产品经理的价值就是解决棘手的问题,就是对异常问题的深入思考。

产品经理的核心,不在于原型画的有多好,不在于需求文档写的多清晰,而在于对异常问题的深入思考。

因此,在我接到这个需求之后,多次经过需求分析,以及需求调研。最终发现要想做好退款需求,主要是理解好商户、支付公司,以及财务对账的需求。

对于商户,最核心的要保证退款成功率、快速到账,支撑退手续费、部分退款等业务情况;
对于支付公司,主要是满足商户需求,以及提高退款的灵活性,能够支持业务的异常性;对财务对账,通道退款手续费与通道保持一致。

二、需求分析

做好需求分析,需要我们换位思考客户对一个需求的实际诉求;需求分析,也是一个理清思路的过程。
本文从商户、支付公司、财务三个对象中分别梳理他们对退款的需求。

1. 商户对退款的诉求

商户对于退款的需求,主要体现在能够支撑商户的业务需求,例如部分退款、多次退款、接口全面性等等,那么针对以下几种进行单独分析。

1)提供多种手续费模式

① 需支持不退回手续费;目的是保证公司现有利益,尽量对外不退手续费;
② 需支持退回手续费。目的是提供优质商户的客户体验。

这里的退款手续费计算是一个难点,因为一笔具体的支付金额对外收费存在三种情况
1)按比例收费;
2)按单笔固定金额收费;
3)按固定金额+比例收费。
那么应该如何处理手续费呢?如何才能保障双方利益呢?尽可能的将手续费退完,并且同时有便于商家理解?其实有两种简单的实现方式:① 按比例退回手续费,即退款手续费=退款金额*支付金额*支付手续费;② 按支付费率退回手续费,即退款手续费=退款金额*支付费率。若固定金额收手续费,则每退一次,退回一次固定金额费率。

经过权衡,我们选择了按比例退回手续费模式,更加简单易懂。

2)支持任意金额退款

① 支持订单全额退款;
② 支持部分退款。

举例:在网上买两双鞋,然后对其中不满意只退其中一双,而不想两双都退。

3)支持多次退款

① 支持一次退款;
② 支持多次退款。

场景:消费者在网上一次性购买十件衣服,由于是陆续到货,收到货物之后不满意,则进行退款,那么这里就会出现多次的部分退款。

4)提供全面的退款接口

① 接口的全面性:单笔退款接口、批量退款接口、以及接口里面的请求、应答、异步通知、查询接口等等均需满足;

② 错误码的全面性:对于商户对接而言,假如出现退款失败,则需要将具体失败原因返回,方便进行排查问题,以及联系消费者。

由于一家支付机构会接入多家上游渠道,而且每家渠道均不一样,甚至错误码存在问题。因此不能直接将通道错误码返回给商家,必须做到错误码的过滤,建立一套错误码转译机制,提高用户体验。

5)支持退款到账快

由于商户也是为消费者而服务的,对于消费者,一旦申请退款,则系统资金立马到账;如果资金迟迟不到账,而会降低消费者对商家的好感,从而也会降低商家对支付公司的好感。因此基本一旦发起退款,希望分钟级到账处理。

首先分析退款的路径,商户发起退款后,处于待支付公司审核,支付公司审核之后进入其上游银联审核,那么作为支付公司所能做的就是降低退款订单在支付公司的滞留时间,简单系统自动判断订单无风险就自动审核通过。

2. 支付公司对退款的诉求

作为支付公司本身,在基本满足商户对于退款诉求之外,还有更高的指标要求;主要表现在要尽可能的提高退款成功率、保证退款安全性、保证退款的灵活性,以及易用性。

接下来从产品视角的来分析应该如何满足这些需求。

1)尽可能保证退款成功率

① 更新退款处理:一般通道直接返回退款失败的订单,不用直接告诉商户重新发起,目的是降低对于商户的体验干扰。而是支付公司将内部的退款流水号更新,二次请求上游通道,这样对于上游通道而言,这是一笔新的退款;退款成功之后,再更新告知商户退款的成功结果。

说明:商户请求支付公司的单号,一般是商户订单号,支付公司会相应生成退款流水号进行标记,同时将退款流水号作为请求上游单号请求银行,银行会返回银行流水号。我们只需将请求银行的退款流水号进行更新即可,这样区分退款应答层和请求层,更加层次分明。

② 打款退款处理:通道无退款接口,或者多次响应失败;特别是对于快捷支付的产品,可以选择退款调用代付打款接口,通过接口打款给原消费者卡号中,这样间接实现退款,保证退款成功率;做到尽一切可能提高体验。

③ 退回消费者余额:若消费者开立了钱包账户,则提供退回消费者钱包余额的功能,这样将极大提高退款效率。

④ 建立反查机制:在系统内部建立定时反查机制。针对处理中的订单进行查询退款状态,一旦反查结果成功,则更新退款状态,避免通道没有退款接口,或者异步应答出现问题的情况。

2)尽可能保证退款安全性

① 根据通道情况配置是否系统自动审核。由于通道渠道的质量千差万别的,对于良好运行的上游渠道,则可以配置自动审核,则会降低退款订单的停留时间;对于质量差的不稳定的渠道,则人工审核。如果出现系统故障时,出现交易堵塞引发批量退款时,也可以紧急关闭自动审核功能,保证安全性;

② 通道先行扣款,则人工审核。对于有些风险订单,通道实行先行扣款机制(尽管不合理),为了对账的一致性,我们需要商户重新发起,但是需拦截请求通道,因此可以针对这些订单对应的上游渠道进行人工审核,直接作退款成功处理。

3)尽可能保证退款的灵活性

    ① 增加强制退款成功操作:如果和通道对账发现,订单在对账单显示成功,但是系统中仍为未成功的状态,因此需要将这些订单强制更正为退款成功。

 ② 增加强制退款失败操作:由于前面聊到通道退款失败,我们将不直接置为失败,而是更新处理,那么假设消费者卡号注销呢?则只能强制置为失败。

③ 降低耦合性:由于退款系统属于支付收单的逆向流程,很容易与收单进行强耦合在一起,因此有必要将收单的关键字段同步到退款系统,无需频繁调用收单数据。降低耦合性有助于为后续的子商户退款、分账退款作铺垫。因此一旦涉及分账退款,其退款逻辑的复杂性远远高于基础退款。

④ 建立异常订单机制。 主要有如下情况:一旦发起重复订单支付,可以系统自动触发调用退款的模式进行处理;有风控系统主动触发退款的模式进行处理;有支付金额小于订单手续费的入账异常,自动触发发起退款。

4)尽可能保证退款的易用性

① 接口返回失败原因,由于支付公司上游会有很多通道,各家的错误码不一致,甚至现有的银联网联不一致,也不规范,作为普通商家很难看懂。因此需要建立一层错误码转译机制,目的是建立支付公司内部统一错误码机制,实现标准化,同时将上游通道难以理解的错误码简化为简单易懂的错误码。

② 失败订单自动化处理,前期可以根据通道的返回的错误码,进行人工二次处理,后期则可以根据通道具体的错误码进行自动化处理,目的是在保证退款成功率的同时又降低人工操作成本。

举个例子:通道错误码返回:“该卡为作废卡,订单状态:01”,则说明卡号本身为废卡,因此无论怎么处理都将失败,可以自动化置为失败;又例如返回:“你的操作过于频繁,请稍后再试”,这可以系统自动化的更新退款流水号重新处理。

3. 财务对于退款的诉求

财务的日常工作之一,是进行通道对账,目的是将上游通道的订单计费情况,与内部系统保持一致。由于支付公司的上游-银联/网联,在通道退款接口不会返回退款手续费的值,因此需要支付公司自行计算退款手续费,以保持与通道一致性。

1)保证退款手续费无误

上游的订单计费,对于支付公司来讲就是支出的成本,因此每个渠道入网,都会有个成本规则配置(这个规则要有很强的灵活性来支撑不同收费模式),需要根据通道情况,增加“是否退回手续费,以及手续费规则”。这样的目的是保证双方规则的统一性,降低对账的障碍。

具体如下图所示:

 
 

三. 产品设计

在进行产品设计的时候,我们需要确立产品设计的原因,以退款系统为例:

首先,要进行解耦,各模块之间可以采取必要的相互调用原则,不影响其他功能模块的设计;
    其次,退款的账户扣款要明确账户扣款的路径;
    第三,要明确退款的各模块的定义、标准,例如状态流,审核流、退款方式、退款来源;
    最后,要梳理出各板块的业务逻辑,并通过产品架构串联起来。
    根据产品设计原则,同时基于以上的需求分析的情况,本文只挑选三个重要板块进行产品设计分析:

1)如何确立退款业务流;
2)退款手续费的计算准确;
3)更新退款的业务逻辑。

1. 退款业务流

一个好的退款状态流能够很好的体现退款订单所进行的步骤。而且,退款又是一个非常有严谨的业务,有时又特别需要审核环节,因此为了将退款流程更加清晰,将流程分为退款状态流和审核流。

1)退款状态流

 
 

2)退款审核流

这里审核状态之所以不加入银行审核状态,是因为完全没有必要,作为下游机构无需知道其审核机构,只需知道处理状态即可。

 
 

3)退款状态的变动流程

 
 

2. 退款手续费计算逻辑

由于允许多次退款,因此需要标记一笔退款订单的剩余可退的金额,以及剩余可退手续费,避免商户钻空子导致公司亏钱,因此逻辑必须严谨。

计算公式,
剩余可退金额=订单金额-累计已退款金额;如果是初次退款,则剩余可退金额=订单金额‘’
剩余可退手续费=支付手续费-累计已退手续费。

计算逻辑

 
 

举例为证:假设交易金额为100的订单,其支付手续费为0.5元;交易金额为1000元的订单,其支付手续费为4元。

字母含义:试算手续费=A,剩余可退手续费=B,此次实际退款的手续费=C;剩余可退金额=D。
        从中我们可以知道,由于退款存在近似值的情况,会存在一定的误差。
        例如下表中100元的订单,在未完全退款之前,就存在把退款手续费扣完的情况;因此我们要设定剩余可退金额与试算的退款手续费比较,避免亏损。
        但也存在下表中1000元订单的情况,在完全退款之后,其手续费存在退不了的情况,而这种情况对于支付公司并未有过多损失,因此允许这种发生。

 
 

3. 更新订单逻辑

当通道返回退款失败的结果之后,往往并不是这笔订单一定不能再处理的,而是在这次的请求是不能处理失败的。因此,我们需要千方百计尽可能重新处理,但是更新订单并未盲目,否则会造成超额退款的情况。

所以,更新退款需要基于以下判断:

  1) 先反查通道退款状态,如果反查通道的状态实际为“已创建”,即通道未接受,则用原退款流水号重新请求即可;若反查成功,则系统自动更新退款流水号重新请求,直至成功;

2) 不反查直接更新退款,有一种请求属于通道反查失败,一直报错,但是基于通道对账单发现并未处理成功,可以认定为通道本身的问题,因此可以不反查直接更新,由于这个操作具有风险性,故仅部分退款时需谨慎操作。

4. 其他

在产品设计中,需要将退款各种情况考虑全面,因此为了让大家更好的理解设计退款的全貌,我将剩余的产品功能核心部分展示一下,方便理解。

1)商户入网

① 支撑商户的每个支付产品退手续费、不退手续费;
② 支持商户的特殊计费不退手续费,普通计费退手续费。

2)通道入网

① 支持一个通道的不同规则退手续费与不退手续费;
② 允许每个通道的退款手续费算法不一样的配置。

3)对外接口

① 提供单笔退款接口、批量退款接口、查询单笔退款接口、查询所有退款接口;
② 打造退款响应码机制。

4)退款逻辑

① 基于通道情况,可配置自动审核/人工审核;
② 基于退款失败订单,进行更新处理;
③ 打造通道错误码自动化处理机制,降低人工操作;
④ 支持异常订单的退款处理。

5)升级退款能力

① 支持子商户退款;
② 支持打款退款,若无法原路退款,可采取打款退款处理;
③ 支持分账退款。允许订单分账前退款,以及订单分账后退款。

四. 总结

打造好Java生鲜电商平台退款系统,不仅要支撑现有客户对于部分退款、退手续费等功能的需求;而且要升级思维,加强对异常情况的考虑——这样才能够让产品持续屹立不倒,打造出一个厉害的Java生鲜电商平台退款系统。

联系QQ:137071249

QQ群:793305035

Java生鲜电商平台-生鲜售后系统的退款架构设计与代码分享的更多相关文章

  1. Java生鲜电商平台-统一格式返回的API架构设计与实战

    Java生鲜电商平台-统一格式返回的API架构设计与实战 说明:随着互联网各岗位精细化分工的普及,出现了很多的系统架构设计,比如常见的前后端分离架构,后端提供接口给前端,前端根据接口的数据进行渲染,大 ...

  2. Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计

    Java生鲜电商平台-生鲜系统中商品订单系统售后系统设计(服务订单履约系统) 说明: 电商之下,我们几乎能从电商平台上买到任何我们日常需要的商品,但是对于很多商品来说,用户购买发货后,只是整个交易流程 ...

  3. Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战

    Java生鲜电商平台-生鲜系统中微服务架构设计与分析实战 说明: Java生鲜系统中微服务的拆分应该如何架构设计与分析呢?以下是我的实战中的设计与经验分析. 目录 1. 微服务简介2. 当前现状3. ...

  4. Java生鲜电商平台-商家支付系统与对账系统架构实战

    Java生鲜电商平台-商家支付系统与对账系统架构实战 说明:关于生鲜电商平台,支付系统是连接消费者.商家(或平台)和金融机构的桥梁,管理支付数据,调用第三方支付平台接口,记录支付信息(对应订单号,支付 ...

  5. Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案

    Java生鲜电商平台-OMS订单系统中并发问题和锁机制的探讨与解决方案 说明:Java开源生鲜电商中OMS订单系统中并发问题和锁机制的探讨与解决方案: 问题由来     假设在一个订单系统中(以火车票 ...

  6. Java生鲜电商平台-会员积分系统的设计与架构

    Java生鲜电商平台-会员积分系统的设计与架构 说明:互联网平台积分体系主要用于激励和回馈用户在平台的消费行为和活动行为,一个良好的积分体系可以很好的提升用户的粘性及活跃度. 一.互联网平台积分体系设 ...

  7. Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战

    Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战 说明:Java生鲜电商平台-小程序或者APP优惠券的设计与源码实战,优惠券是一种常见的促销方式,在规定的周期内购买对应商品类型和额度的商品 ...

  8. Java生鲜电商平台-生鲜电商中商品类目、属性、品牌、单位架构设计与实战

    Java生鲜电商平台-生鲜电商中商品类目.属性.品牌.单位架构设计与实战 说明:Java生鲜电商平台-生鲜电商中商品类目.属性.品牌.单位架构设计与实战经验分享 凡是涉及到购物,必然是建立在商品的基础 ...

  9. Java生鲜电商平台-生鲜供应链(采购管理)

    Java生鲜电商平台-生鲜供应链(采购管理) 在生鲜供应链系统中采购中心这一模块,它是电商公司管理采购的模块,包含供应商管理,采购订单管理,采购商品管理,在该模块中采购订单是采购中心的核心模块.在其他 ...

随机推荐

  1. Emacs 学习之旅

    **Emacs 的使用过程,就像是程序员的生涯一样--路漫漫其修远兮,吾将上下而求索.** ## 万物始于 Emacs 最早知道 _Emacs_ 是从编辑器的圣战开始的,即编辑器之神--Vi,和神的编 ...

  2. Java编程思想——第14章 类型信息(一)

    运行时类型信息使得你可以在程序运行时发现和使用类型信息.Java是如何让我们在运行时识别对象和类的信息得呢? 主要有两种方式:1.传统RTTI,他假定我们在编译期间已经知道了所有类型:2.反射,它允许 ...

  3. window10系统下,彻底删除卸载mysql

    本文介绍,在Windows10系统下,如何彻底删除卸载MySQL...1>停止MySQL服务开始->所有应用->Windows管理工具->服务,将MySQL服务停止.2> ...

  4. Map Reduce 论文阅读

    Map Reduce 是 Google 在 2004 年发表的一篇论文,原文链接 在这 后来 Hadoop 直接内置了这一框架. 读完之后记录一下心得. 主要背景:MapReduce 的出现很具有工程 ...

  5. 掌握git命令的正确使用姿势

    前言 最近在团队内部发起了一个小的python项目(用tkinter实现一个小工具),但是发现大家对git的使用还不太熟悉,不知道怎么同步代码.解决冲突等等.因为我觉得对测试工程师来说,git应该是必 ...

  6. mysql字符集那些事

    1..查看mysql当前使用的字符集. 登录mysql 在mysql 里输入 show variables like 'character_set%' mysql> show variables ...

  7. mysql忘记密码怎么办??

    1.停掉mysql 1.1单实例停止方式 [root@qiuhom ~]# /etc/init.d/mysqld stop Shutting down MySQL. [ OK ] 1.2多实例停止方式 ...

  8. Potato Sacks

    Potato sacks come in different weight capacities (specified in pounds). Potatoes come in different w ...

  9. 使用 Zephir 轻松构建 PHP 扩展

    简介: 通过 PHP 扩展, 我们可以在 php 代码中使用一些特定的方法(大部分的 php 扩展都是用 C 写的). 比如,在 PHP 中需要与 SQLite3 交互,我们可以自己写方法与之进行连接 ...

  10. MySQL数据库的10大经典错误案例

    学习任何一门技术的同时,其实就是自我修炼的过程.沉下心,尝试去拥抱数据的世界! 案例一 Too many connections (连接数过多,导致连接不上数据库,业务无法正常进行) 问题还原: 解决 ...