Java生鲜电商平台-生鲜电商中售后退款流程整理与架构实现(小程序/APP)

Java生鲜电商平台-生鲜电商中售后退款流程整理与架构实现(小程序/APP)

 

说明:任何一个生鲜电商系统,无论是小程序还是APP都无法避免的会出现退货,退款等售后问题,那么根据我这边的经验,本文分享下,在做售后的系统设计的

过程中,我们以为如何进行设计,如何进行退款,如何进行审批与操作呢?

 

目录

1. 售后系统的流程设计。

2. 售后系统的数据库设计。

3. 售后系统的代码实现。

4. 售后系统的运营统计。

5. 售后系统的复盘.

 

1. 售后系统的流程设计。

  说明:售后系统的流程设计指的是如何进行售后系统的步骤设计,理论上是存在以下几个步骤的,我先简单的画个图。工具用Visio

         

          Java生鲜电商平台-生鲜电商中售后退款流程整理与架构实现(小程序/APP)_第1张图片

 

 

                我们根据上面画的流程图,我们分析下有以下几个步骤

               1. 用户通过某一个订单中的具体商品进行申请售后,比如说:买的土豆烂了一半。

               2. 客服人员根据用户的申请进行审批,审批存在审批通过与审批不通过的情况,通过则打款,不通过则退回,可再次申请。

               3. 审批通过后,系统记录申请打款的记录表,然后自动打款。出现异常,则走异常监控,人工干预。

              4. 最后根据日或者周为单位进行整个系统的运营复盘,这样才更加的高效与减少售后问题,这里有个疑问,为什么不用避免售后问题呢?而要采用减少呢?

                   根据我这6年来的生鲜电商的经验,这个售后问题无法避免与消除,不管是精细化做得多么的好的企业,都一定存在这个情况,只是比率比较小而已.

 

2. 售后系统的数据库设计。

               

      说明:根据整个业务的流程与整理,我们发现需要有以下几张表来记录。(Mysql数据库为例)

                1. 售后记录基础信息表。(aftersales)

                2. 售后审批日志表 。(aftersales_approve)

                3.售后问题分类信息表  (aftersales_classify)

                4. 售后问题分类明细表  (aftersales_classify_item)

                5.  售后退款金额记录表  (aftersales_refund)

 

3. 售后系统的代码实现。

 

              说明:根据整个业务场景,我们发现,用户在生鲜电商小程序或者APP上提交售后申请。客服人员进行售后的审批。系统自动打款,运营复盘。

 

               这里面有些基础的东西,都是CRUD,我就不贴代码了,我贴一些核心的代码

 

                1. 系统自动打款

                     说明:系统去扫描售后退款金额记录表,把需要打款的信息进行提交给微信,用的是定时器来操作。

                     

@Scheduled(cron = "0 */5 * * * ?")
    public void aftersalesRefundExecute()
    {
        log.info("[AftersalesRefundJob][aftersalesRefundExecute]系统开启任务检查:需要打款的售后列表");

        List  list= this.aftersalesRefundService.getAftersalesRefundList();

        if(CollectionUtils.isEmpty(list))
        {
            log.info("未查询到需要打款的售后列表");
            return;
        }

        for (AftersalesRefund refund:list)
        {

            //获取订单
            String orderSn=aftersalesRefundService.getOrderSnByAftersalesRefund(refund.getAftersalesId());

            //获取订单对象
            Order order=this.orderService.getOrderByOrderNumber(orderSn);

            try
            {
                //申请退款
                WxPayRefundRequest refundInfo = WxPayRefundRequest.newBuilder()
                        .outTradeNo(orderSn)
                        //退款订单号
                        .outRefundNo(refund.getRefundOrderNumber())
                        //金额,单位为:分
                        .totalFee(order.getActualPrice().multiply(BigDecimal.valueOf(100)).intValue())
                        //退款金额,单位为:分
                        .refundFee(refund.getRefundAmount().multiply(BigDecimal.valueOf(100)).intValue())
                        .notifyUrl("https://wx-api.xxx.com/refund/refundNotify")
                        .build();
                WxPayRefundResult wxPayRefundResult;
                try
                {
                    wxPayRefundResult = wxPayService.refund(refundInfo);
                    //判断退款信息是否正确
                    if (REFUND_SUCCESS.equals(wxPayRefundResult.getReturnCode()) && REFUND_SUCCESS.equals(wxPayRefundResult.getResultCode()))
                    {
                        log.info("正在退款中....");
                    }else
                    {
                        log.info("退款失败,请联系管理员...");
                    }
                } catch (WxPayException e) {

                    //组织对象
                    refund.setRefundStatus(3);
                    refund.setRefundRemarks(e.getXmlString());
                    //更新错误信息
                    this.aftersalesRefundService.updateAftersalesRefundException(refund);
                    log.error("微信退款接口错误信息= {}", e);
                }
              Thread.sleep(1500);
            }catch (Exception ex)
            {
                log.error("[AftersalesRefundJob][aftersalesRefundExecute] exception",ex);
            }
        }
    }

                     2. 系统自动打款成功后,微信会服务端进行回调来通知。

 

                          说明:微信服务端回调,我们一般需要做什么几个步骤呢?(注意,在同一个事务里面完成,如果失败,就直接让微信返回FAIL)

                                  1. 验证签名

                                  2. 更新申请记录表状态

                                  3.  增加售后日志记录

                                  4.  更新售后主表状态

public Object orderRefundNotify(HttpServletRequest request, HttpServletResponse response) throws Exception {

        //解析xml的结果
        String xmlResult = null;
        try {
            xmlResult = IOUtils.toString(request.getInputStream(), request.getCharacterEncoding());
        } catch (IOException e) {
            log.error("[OrderRefundServiceImpl][orderRefund] [xmlResult]exception",e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        log.info("[OrderRefundServiceImpl][orderRefund] xmlResult 的数据为{}",xmlResult);
        WxPayRefundNotifyResult result = null;
        try
        {
            //解析并验证,返回WxPayRefundNotifyResult对象
            result = wxPayService.parseRefundNotifyResult(xmlResult);
            log.info("微信退款通知xml解析转result结果为{}",result);
        } catch (WxPayException e) {
            log.error("[OrderRefundServiceImpl][orderRefund] [WxPayRefundNotifyResult]exception",e);
            return WxPayNotifyResponse.fail(e.getMessage());
        }

        log.info("处理腾讯支付平台的订单支付");
        log.info("微信退款通知--->result:{}",result);
        log.info("微信退款通知解密信息--->result:{}",result.getReqInfo().toString());

        //获取退款的状态
        String refundStatus=result.getReqInfo().getRefundStatus();

        //比对状态,成功才处理
        if(!WxPayConstants.ResultCode.SUCCESS.equals(refundStatus)){
            log.error(refundStatus);
            throw new WxPayException("微信退款通知状态不为成功!refundStatus:{}"+refundStatus);
        }

        //微信退款单号
        String refundId = result.getReqInfo().getRefundId();

        //商户退款订单号
        String outRefundNo = result.getReqInfo().getOutRefundNo();

        // 分转化成元
        String totalFee = BaseWxPayResult.fenToYuan(result.getReqInfo().getRefundFee());

        //获取售后退款对象
        AftersalesRefund aftersalesRefund=this.aftersalesRefundMapper.getAftersalesRefundByRefundOrderNumber(outRefundNo);

        log.info("aftersalesRefund对象为:{}",aftersalesRefund);

        if (aftersalesRefund == null)
        {
            log.error("AftersalesRefund is not found");
            throw new WxPayException("微信退款售后对象找不到");
        }

        //比对退款金额跟申请金额
        if (!totalFee.equals(aftersalesRefund.getRefundAmount().toString())) {
            return WxPayNotifyResponse.fail(aftersalesRefund.getRefundOrderNumber() + " : 支付金额不符合 totalFee=" + totalFee);
        }

        //比对状态,如果退款状态,0为初始化申请,1为进行中,2为退款成功,3为退款失败'
        //幂等操作,如果是2表示退款已经处理,则不用处理
        if(aftersalesRefund.getRefundStatus().intValue()==2)
        {
            return WxPayNotifyResponse.success("处理成功!");
        }

        ////////////////////////////////3.更新申请记录表状态/////////////////////////////////
        //退款成功
        aftersalesRefund.setRefundStatus(2);
        //微信订单号
        aftersalesRefund.setWeixinOrderNumber(refundId);
        //微信通知时间
        aftersalesRefund.setWeixinNotifyTime(new Date());
        //更新状态
        aftersalesRefundMapper.updateAftersalesRefund(aftersalesRefund);

        /////////////////////////////4. 记录时间轴
        AftersalesApprove aftersalesApprove=new AftersalesApprove();
        aftersalesApprove.setAftersalesId(aftersalesRefund.getAftersalesId());
        //'审批的状态,默认为0,0表示初始化创建,待审核,1为审核未通过,2为审核通过,3,退款中,4,退款成功',
        aftersalesApprove.setApproveStatus(4);
        aftersalesApprove.setApproveContent("退款成功");
        aftersalesApprove.setCreateBy("服务器回调处理");
        aftersalesApprove.setCreateTime(new Date());
        aftersalesApproveMapper.insertAftersalesApprove(aftersalesApprove);

        ///////////////////////////////5.更新售后状态//////////////////////
        Aftersales aftersales=new Aftersales();
        aftersales.setAftersalesId(aftersalesRefund.getAftersalesId());
        //4表示退款成功
        aftersales.setAftersalesStatus(4);
        aftersalesMapper.updateAftersalesMapperAftersalesStatus(aftersales);

        return WxPayNotifyResponse.success("处理成功!");
    }

 

5. 售后系统的复盘.

      说明:为什么有售后系统的复盘呢?原因只有一个,就是通过复盘来获取与统计整个运营系统中发现的问题,进行及时的纠正,最终达到提高客户满意度以及整个公司的成本降低,口碑做好,越做越好的目的.

       在此,文章写完了,当然整个售后过程中是有很多的细节需要注意与检查的,本文只是起到一个抛砖引玉的作用,如果有什么疑问,请在下面进行评论与留言,我会一一答复.

你可能感兴趣的:(Java生鲜电商平台-生鲜电商中售后退款流程整理与架构实现(小程序/APP))