1. 背景
随着电商的普及和发展,各个电商平台竞争逐步进入红海,规则越来越复杂,数据量级越来越大,涉及电商业务的公司也越来越多。
在这样的背景下,涉及电商公司运营部门很多需求得到重视。除此之外,还有一些隐藏在高速发展的电商需求没有得到关注,例如,订单多,涉及到的金额大,公司财务人员的收支对账任务也日益沉重。为此,使用信息系统来实现财务数据的自动对账的需求渐渐被很多公司看到。
2. 概述
下面基于电商特性讲解一下实现财务对账功能
财务对账整体预览:
基于上图,我们需要解决以下几个问题:
1、内部数据包括哪些
2、外部数据如何获取
3、对账引擎要做哪些
4、对账结果如何处理
这些问题,给我们整个对账系统的建设提供的方向,为此,我们分为四个部分给大家分析。
3. 内部数据
内部数据通常是指,公司内部系统中处理过的订单、退单和退款等数据。
3.1. 需求说明
为了不影响系统业务运行,建议定时同步订单系统数据到对账引擎中。
用平台单号将内部系统中的订单、退单和退款,聚合规整到系统账单。
3.2. 数据流转示例
把内部系统中的订单
、退单
、退款单
转换为系统账单
系统内部订单 ( table-1)
订单主表信息 | ||||||
平台订单号 | 系统编号 | 订单数量 | 订单金额 | ··· | 订单时间 | |
PO001 | SO001 | 6 | 150 | ··· | 2022-11-22 16:00:00 | |
订单明细信息 | ||||||
平台订单号 | 系统编号 | sku信息 | sku数量 | sku金额 | ··· | 订单时间 |
PO001 | SO001 | SKU001 | 1 | 50 | ··· | 2022-11-22 16:00:00 |
PO001 | SO001 | SKU002 | 2 | 40 | ··· | 2022-11-22 16:00:00 |
PO001 | SO001 | SKU003 | 3 | 60 | ··· | 2022-11-22 16:00:00 |
系统内部退单 ( table-2)
退单主表信息 | ||||||||
平台退单号 | 平台订单号 | 系统编号 | 退单数量 | 退单金额 | 退货原因 | ··· | 退单时间 | |
PRT001 | PO001 | SRT001 | 2 | 40 | 7天无理由退货 | ··· | 2022-11-24 10:00:00 | |
退单明细信息 | ||||||||
平台退单号 | 平台订单号 | 系统编号 | sku信息 | sku数量 | sku金额 | ··· | 订单时间 | |
PRT001 | PO001 | SRT001 | SKU003 | 2 | 40 | ··· | 2022-11-24 10:00:00 |
系统内部退款 ( table-3)
退款主表信息 | |||||||
平台退款号 | 平台订单号 | 系统编号 | 退款金额 | 退款原因 | ··· | 退款时间 | |
PRF001 | PO001 | SRF001 | 10 | 表面破损补偿 | ··· | 2022-11-25 11:00:00 | |
退款明细信息 | |||||||
平台退款号 | 平台订单号 | 系统编号 | sku信息 | sku金额 | ··· | 订单时间 | |
PRF001 | PO001 | SRF001 | SKU002 | 10 | ··· | 2022-11-25 11:00:00 |
规整后生成一张系统账单 ( table-4),如下:
系统账单主表 | ||||||||
平台订单号 | 正向金额 | 正向数量 | 逆向金额 | 逆向数量 | 转换状态 | ··· | 操作时间 | |
PO001 | 150 | 6 | 50 | 2 | 已转换 | ··· | 2022-11-25 11:00:00 | |
系统账单明细信息 | ||||||||
单据类型 | 平台订单号 | 平台退单/款号 | 系统编号 | sku信息 | sku数量 | sku金额 | ··· | 记录时间 |
订单 | PO001 | -- | SO001 | SKU001 | 1 | 50 | ··· | 2022-11-22 16:00:00 |
订单 | PO001 | -- | SO001 | SKU002 | 2 | 40 | ··· | 2022-11-22 16:00:00 |
订单 | PO001 | -- | SO001 | SKU003 | 3 | 60 | ··· | 2022-11-22 16:00:00 |
退单 | PO001 | PRT001 | SRT001 | SKU003 | 2 | 40 | ··· | 2022-11-24 10:00:00 |
退款 | PO001 | PRF001 | SRF001 | SKU002 | 0 | 10 | ··· | 2022-11-25 11:00:00 |
至此,系统内部的数据已经规整到系统账单表中。
4. 外部数据
外部数据通常是指平台和商家之间的资金流水结算记录,这些数据可以从商家管理后台下载文件,也可以通过资金流水接口获取。
4.1 需求说明
4.1.1 数据获取
我们在获取外部数据时,需要支持接口下载的同时兼容文件导入。
资金流水文件导入后可以上传到oss上保存起来,系统需要解析时读取oss上对应的文件即可,为此我们可以使用 “原始文件记录表
” 记录文件对应的oss路径以及解析状态等。
4.1.2 数据规整
支付宝账单是每一笔流水都有一条数据;抖音账单则是一笔订单对应的金额明细在一条数据的不同字段中体现。
由于各个平台原始账单
(后面提到的原始账单
包括但不限于支付宝原始账单
、 抖音原始账单
、拼多多原始账单
、等表数据)内容不一致,我们需要根据平台单号把不一致的数据规整到一张统一的表中,这样我们就得到了平台账单
。
我们在从各渠道原始账单
转换生成平台账单
数据时,需要确定哪些金额是归属正向,哪些金额归属逆向,为了便于后期扩展,我们可以引入一张平台金额计算配置表
用以标记不同渠道的不同类型数据中的字段取值。
常见电商平台的账单下载,其它的账单可以在对应的开放平台里找:
支付宝账单下载 、 京东账单下载 、 拼多多账单下载 、 抖音电商账单下载
当然还会有很多其它平台不一定有接口,可以通过导入文件的方式进入对账引擎
4.2 数据流转
外部数据流转概况
不同渠道原始账单最终生成平台账单的流转过程
常见的原始账单有以下两种:
- 每笔资金流水对应一条数据(以支付宝原始账单为代表, ( table-5)):
账务流水号 | 业务流水号 | 商户订单号 | 商品名称 | 发生时间 | 对方账号 | 收入金额 | 支出金额 | 账户余额 | 交易渠道 | 业务类型 | 备注 | 业务描述 | 业务账单来源 | 业务基础订单号 | 业务订单号 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1170**141 | 2022110**891 | T200**82 | **商品 | 2022/8/8 20:09:37 | *文(568***@qq.com) | 59 | 0 | ** | 支付宝 | 交易付款 | 0010001|交易收款-交易收款 | 商家中心 | PO001 | M{PO001} | |
1170**142 | 2022110**891 | T200**82 | **商品 | 2022/8/8 20:09:37 | 杭**里妈*软件服务有限公司(lmy***@service.aliyun.com) | 0 | -1.29 | ** | 支付宝 | 交易分账 | 淘宝客佣金代扣款 | 0060011|营销支出-淘宝客佣金 | 联盟商家中心 | PO001 | M{PO001} |
1170**143 | 2022110**891 | T200**82 | **商品 | 2022/8/8 20:09:37 | *付*网络技术有限公司(sys***@alipay.com) | 0 | -0.71 | ** | 支付宝 | 收费 | 花呗支付服务费[2022**5];淘宝交易号[T200P1**4] | 0030038|软件服务费-支付宝服务费 | 蚂蚁商家中心 | PO001 | M{PO001} |
- 每个账单的资金流水在一条数据的不同字段体现(以抖音原始账单为代表 ( table-6)):
动账时间 | 动帐流水号 | 动账方向 | 动账金额 | 动账账户 | 动账摘要 | 计费类型 | 子订单号 | 订单号 | 售后编号 | 下单时间 | 商品ID | 订单类型 | 订单实付应结 | 运费实付 | 实际平台补贴_运费 | 实际平台补贴 | 实际达人补贴 | 实际抖音支付补贴 | 实际抖音月付营销补贴 | 订单退款 | 平台服务费 | 佣金 | 渠道分成 | 招商服务费 | 直播间站外推广费 | 其他分成 | 备注 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
2022/7/26 23:10 | AS2022**019_IN | 入账 | 100 | 微信 | 订单结算 | 鲁班广告 | PO2 | PO002 | 'SS7403**2628 | 2022/6/18 18:26 | '35**583 | 普通订单 | 100 | 5 | 1 | 0 | 0 | 0 | 0 | 0 | -2 | -4 | 0 | 0 | 5 | 0 | |
2022/7/26 23:47 | AS2022**405_IN | 入账 | 100 | 微信 | 订单结算 | 小店自卖 | PO3 | PO003 | 'SS7124**4950 | 2022/7/19 13:27 | '35**050 | 普通订单 | 100 | 10 | 0 | 4 | 0 | 0 | 0 | 0 | -5 | 0 | -4 | 0 | 4 | 0 | |
2022/7/26 23:47 | AS2022**66994_IN | 入账 | 100 | 微信 | 服务费返还 | 鲁班广告 | PO4 | PO004 | 'SS7124**9584 | 2022/6/18 20:43 | '35**940 | 普通订单 | 100 | 15 | 0 | 3 | 2 | 0 | 0 | 0 | -3 | 0 | 0 | -12 | 3 | 0 |
为了实现抖音账单
正逆向金额的区分,我们引入一张平台金额计算配置表
,以期实现根据每条数据的不同字段,获取对应的金额。
平台金额计算配置表
设置为如下( ( table-7)):
平台 | 平台类型 | 系统类型 | 取值字段 | 平台业务 | 计算方式 | 备注 |
---|---|---|---|---|---|---|
抖音 | 订单结算 | 正向 | 订单实付应结 | 订单实付应结 | 加 | |
抖音 | 订单结算 | 正向 | 运费实付 | 运费实付 | 加 | |
抖音 | 订单结算 | 正向 | 实际平台补贴 | 实际平台补贴 | 加 | |
抖音 | 订单结算 | 逆向 | 平台服务费 | 平台服务费 | 减 | |
抖音 | 订单结算 | 逆向 | 佣金 | 佣金 | 减 | |
抖音 | 服务费返还 | 正向 | 订单实付应结 | 订单实付应结 | 加 | |
抖音 | 服务费返还 | 正向 | 实际平台补贴 | 实际平台补贴 | 加 | |
抖音 | 服务费返还 | 逆向 | 渠道分成 | 渠道分成 | 减 | |
抖音 | 服务费返还 | 逆向 | 招商服务费 | 招商服务费 | 减 | |
支付宝 | 交易付款 | 正向 | 收入金额 | 收入金额 | 加 | |
支付宝 | 交易付款 | 逆向 | 支出金额 | 支出金额 | 减 | |
支付宝 | 交易分账 | 正向 | 收入金额 | 收入金额 | 加 | |
支付宝 | 交易分账 | 逆向 | 支出金额 | 支出金额 | 减 | |
支付宝 | 收费 | 正向 | 收入金额 | 收入金额 | 加 | |
支付宝 | 收费 | 逆向 | 支出金额 | 支出金额 | 减 |
平台账单如下
根据平台和原始账单中的平台类型,将( table-5 、 table-6)的数据,基于( table-7)规整成如下( table-8):
平台账单列表页面 | ||||||||||
序号 | 平台 | 平台订单号 | 正向金额 | 正向数量 | 逆向金额 | 逆向数量 | 转换状态 | ··· | 账单时间 | |
1 | 支付宝 | PO001 | 59 | 0 | 2 | 0 | 未转换 | ··· | 2022/8/8 0:09:37 | |
2 | 抖音 | PO002 | 105 | 0 | 6 | 0 | 未转换 | ··· | 2022/7/26 23:10 | |
3 | 抖音 | PO003 | 114 | 0 | 5 | 0 | 未转换 | ··· | 2022/7/26 23:47 | |
4 | 抖音 | PO004 | 103 | 0 | 12 | 0 | 未转换 | ··· | 2022/7/26 23:47 |
上述表( table-8)中的序号1数据详情页如下,根据平台单号将多条原始账单数据聚合到一个平台账单
中,明细数据是根据( table-7)将对应的每一条原始账单数据拆分成正向和逆向两类。
序号1数据详情页( table-9)
平台账单主表 | ||||||||
平台 | 平台订单号 | 正向金额 | 正向数量 | 逆向金额 | 逆向数量 | 转换状态 | ··· | 生成时间 |
支付宝 | PO001 | 59 | 0 | 2 | 0 | 未转换 | ··· | 2022/8/9 10:00:00 |
平台账单-原始单据明细 | ||||||||
原始账单流水号 | 系统类型 | 平台类型 | 平台业务 | 金额 | 数量 | 转换状态 | 原始账单时间 | |
1170**141 | 正向 | 交易付款 | 收入金额 | 59 | 0 | 未转换 | 2022/8/8 20:09:37 | |
1170**141 | 逆向 | 交易付款 | 支出金额 | 0 | 0 | 未转换 | 2022/8/8 20:09:37 | |
1170**142 | 正向 | 交易分账 | 收入金额 | 0 | 0 | 未转换 | 2022/8/8 20:09:37 | |
1170**142 | 逆向 | 交易分账 | 支出金额 | 1.29 | 0 | 未转换 | 2022/8/8 20:09:37 | |
1170**143 | 正向 | 收费 | 收入金额 | 0 | 0 | 未转换 | 2022/8/8 20:09:37 | |
1170**143 | 逆向 | 收费 | 支出金额 | 0.71 | 0 | 未转换 | 2022/8/8 20:09:37 |
同理,序号2数据详情页如下( table-10)
平台账单主表 | ||||||||
平台 | 平台订单号 | 正向金额 | 正向数量 | 逆向金额 | 逆向数量 | 转换状态 | ··· | 生成时间 |
抖音 | PO002 | 105 | 0 | 6 | 0 | 未转换 | ··· | 2022/8/9 10:00:00 |
平台账单-原始单据明细 | ||||||||
原始账单流水号 | 系统类型 | 平台类型 | 平台业务 | 金额 | 数量 | 转换状态 | 原始账单时间 | |
AS2022**019_IN | 正向 | 订单结算 | 订单实付应结 | 100 | 0 | 未转换 | 2022/8/8 20:09:37 | |
AS2022**019_IN | 正向 | 订单结算 | 运费实付 | 5 | 0 | 未转换 | 2022/8/8 20:09:37 | |
AS2022**019_IN | 正向 | 订单结算 | 实际平台补贴 | 0 | 0 | 未转换 | 2022/8/8 20:09:37 | |
AS2022**019_IN | 逆向 | 订单结算 | 平台服务费 | 2 | 0 | 未转换 | 2022/8/8 20:09:37 | |
AS2022**019_IN | 逆向 | 订单结算 | 佣金 | 4 | 0 | 未转换 | 2022/8/8 20:09:37 |
对账引擎
1、获取外部数据有两种方式,一是通过上述接口获取账单数据,二是通过商家后台下载资金流水文件
2、对账系统需要将接口下载或者用户导入到系统中的资金流水文件写入数据库中,生成对应的平台原始对账单
3、由于各个平台原始账单数据格式不一致,我们需要把不一致的数据规整成为一张统一的平台账单
4、从内部系统中获取对应的订单、退单和退款单,生成系统单据;
5、使用平台账单的数据生成对账结果单;
6、根据关联关系,从系统单据中找到对应的数据写入对账结果单中;
7、把平台金额和系统金额进行比对,得到对账结果。
1~4步,我们在前面的操作将内部数据(订单
、 退单
、退款单
)规整成系统账单
,外部的原始账单
数据规整成平台账单
。
接下来,我们用系统账单
和平台账单
数据执行第5步。
在做第5部操作之前,我们先思考一个问题:
一定要用
平台账单
生成对账结果后,再根据平台单号等关联关系去找到系统账单
数据后写入对账结果单吗?答案是否定的,我们也可以用
系统账单
生成对账结果单之后,根据对应的关联关系去找平台账单
后写入对账结果单中。
在正常情况下,我们的内部数据一定是会比外部数据多的,因为订单和退单等数据是我们内部系统产生的,我们可以第一时间拿到;外部数据则不然很多平台的资金流水数据都是n+1甚至是n+7才能获取到。
用平台账单
生成对账结果单,可以减少对账结果单的数量,用户只需要关注同时有内部和外部数据的订单即可;
用系统账单
生成对账结果单,可以将系统内的数据先处理好,等外部数据拿到后,就可以执行对账引擎的逻辑;
二者各有利弊,需要根据实际情况择优选用。
对账结果单中需要展示出内部金额和数量、外部金额和数量,除此之外,很多公司的财务管理比较精细,需要掌握公司内部每个sku在每一笔订单中的收支情况,便于后期的盘库盘账等操作。因此,我们以( table-4)和( table-9)为例将对账结果单设计成如下( table-11):
对账结果单 | ||||||||||||||||||
平台 | 平台订单号 | 平台账单正向金额 | 平台账单正向数量 | 平台账单逆向金额 | 平台账单逆向数量 | 系统账单正向金额 | 系统账单正向数量 | 系统账单逆向金额 | 系统账单逆向数量 | 封账正向金额 | 封账正向数量 | 封账逆向金额 | 封账逆向数量 | 对账状态 | 封账状态 | ··· | 生成时间 | |
支付宝 | PO001 | 105 | 0 | 6 | 0 | 150 | 6 | 50 | 2 | 0 | 0 | 0 | 0 | 对账失败 | 未封账 | ··· | 2022/8/12 10:00:00 | |
对账结果单sku明细 | ||||||||||||||||||
单据类型 | 系统编号 | sku信息 | sku数量 | sku金额 | 封账数量 | 封账金额 | 对账状态 | ··· | 原始账单时间 | |||||||||
订单 | SO001 | SKU001 | 1 | 50 | 0 | 0 | 对账失败 | ··· | 2022/8/8 20:09:37 | |||||||||
订单 | SO001 | SKU002 | 2 | 40 | 0 | 0 | 对账失败 | ··· | 2022/8/8 20:09:37 | |||||||||
订单 | SO001 | SKU003 | 3 | 60 | 0 | 0 | 对账失败 | ··· | 2022/8/8 20:09:37 | |||||||||
退单 | SRT001 | SKU003 | 2 | 40 | 0 | 0 | 对账失败 | ··· | 2022/8/8 20:09:37 | |||||||||
退款 | SRF001 | SKU002 | 0 | 10 | 0 | 0 | 对账失败 | ··· | 2022/8/8 20:09:37 |
如( table-11)所示,我们将内部数据中的sku信息作为子表关联到这个对账结果单上,等我们对账引擎处理结束之后,就可以将这笔订单中系统内部的sku金额收入和支出完整的展示出来。由于外部数据和内部数据不一致,我们将这个结果单设置为对账失败。
接下来我们讲对账结果的操作
对账结果
在对账引擎中处理完成的数据,可能会出现内外部数据不一致的情况,基于这些数据,我们需要提供一些操作来平账(所谓平账,就是我们需要对这个内外不一致的数据,提供一个统一的结果供后续流程操作)。
平账操作无外乎三种,分别是:
1、对账结果单主表封账金额=平台金额,对账结果单sku明细表中的封账金额可以按比例分摊封账金额;
2、对账结果单主表封账金额=系统金额,对账结果单sku明细表中的封账金额=sku金额;
3、同时调整平台和系统金额,使其一致
经过处理后的对账结果单,设置对账结果=已对账,做封账操作后,不再处理。
前两种操作我们可以在列表页提供两个按钮,让用户选择数据后批量操作;如果需要同时调整平台和系统金额,那么用户要进入到对账结果单详情页,手动输入封账正向金额、封账正向数量、封账逆向金额、封账逆向数量,对账结果单sku明细表中的封账金额可以按比例分摊封账金额;
我们将( table-11)按第三种情况操作后,结果如下:
对账结果单 | ||||||||||||||||||
平台 | 平台订单号 | 平台账单正向金额 | 平台账单正向数量 | 平台账单逆向金额 | 平台账单逆向数量 | 系统账单正向金额 | 系统账单正向数量 | 系统账单逆向金额 | 系统账单逆向数量 | 封账正向金额 | 封账正向数量 | 封账逆向金额 | 封账逆向数量 | 对账状态 | 封账状态 | ··· | 生成时间 | |
支付宝 | PO001 | 105 | 0 | 6 | 0 | 150 | 6 | 50 | 2 | 130 | 5 | 10 | 1 | 已对账 | 未封账 | ··· | 2022/8/12 10:00:00 | |
对账结果单sku明细 | ||||||||||||||||||
单据类型 | 系统编号 | sku信息 | sku数量 | sku金额 | 封账数量 | 封账金额 | 对账状态 | ··· | 原始账单时间 | |||||||||
订单 | SO001 | SKU001 | 1 | 50 | 43.33 | 1 | 已对账 | ··· | 2022/8/8 20:09:37 | |||||||||
订单 | SO001 | SKU002 | 2 | 40 | 34.66 | 2 | 已对账 | ··· | 2022/8/8 20:09:37 | |||||||||
订单 | SO001 | SKU003 | 3 | 60 | 52.01 | 2 | 已对账 | ··· | 2022/8/8 20:09:37 | |||||||||
退单 | SRT001 | SKU003 | 2 | 40 | 8 | 1 | 已对账 | ··· | 2022/8/8 20:09:37 | |||||||||
退款 | SRF001 | SKU002 | 0 | 10 | 2 | 0 | 已对账 | ··· | 2022/8/8 20:09:37 |
此时该对账结果单已经是对账成功,再进行封账操作后,整个对账流程就结束了。
在信息系统这个概念中,人是不可或缺的一个重要组成。
由于电商业务的特殊性,加之各个平台规范不一样,我们需要有技术可以解决很多问题,但是我们还是需要人工介入这样的意识。
这套对账流程可以兼容绝大多数订单的对账需求,但是仍然有对账失败,且在对账结果单上操作无法满足需求的可能,所以我们还需要针对不同的情况,人工处理。