一、序言
去年年底接的微信商城小程序终终终于完工了,哥几个也成功拿到了进度开发款,等月底上线完尾款也很快到手了。
在这个项目中,有两个很重要的模块就是商家结算和返佣,返佣又分为学子返佣和代理商返佣。
学子返佣的业务背景为高校大学生可以小程序进行学子认证,认证成功后别人购买分享的商品可以按比例获得返佣。
代理商返佣的业务背景为小程序用户帮助平台地推商户,地推成功后代理商会和该商户绑定,绑定后该商户下所有交易会给一定比例代理商返佣。
为了更好地用户体验,我们决定为商家、学子、代理商开设一个虚拟钱包,订单结算时由结算人员确认单天结算金额后,再统一划账到各角色钱包上。
今天咱们一起聊聊返佣提现钱包设计,金融系统开发老鸟出品,绝对百分百干货!话不多说,直接开整!
二、钱包提现业务流程
先来张时序图,三者钱包入金的触发时间都在结算时触发,也就是说系统会在订单确认收获次日分别生成商家、学子、代理商结算报表。
图里面没有画钱包什么时候生成,商家结算钱包账户会在商家入驻成功后生成,学子返佣钱包会在学子认证后生成,代理商返佣钱包会在申请代理商成功后生成。
钱包提现分别在小程序和商家端触发,并且能看到各自的总提现金额、待提现金额和Pending中提现金额,同时用户还能看到提现记录。
三、数据库设计
这里不讲结算该怎么设计,只说明钱包应该如何设计,怎样更好地记账,交易回溯,余额变动等等。
1、账户信息表
我们已经明确了系统有三种不同的角色,分别对应三种不同的钱包账户。这里我们加入了冻结金额,这个字段基本是所有账户系统必备的存在,适用于很多异步扣账,尤其是接第三方渠道的场景。
# 账户信息表
create table `t_account_info`
(
`id` bigint primary key auto_increment comment '主键ID',
`account_no` varchar(24) not null comment '账户号',
`account_type` varchar(2) not null comment '账户类型: S-学子账户, M-商家账户, A-商家代理人账户',
`account_owner` varchar(24) not null comment '账户所属人(商户号或者用户号)',
`status` varchar(2) not null comment '账户状态:A-已激活, F-已冻结',
`total_balance` decimal(12, 2) not null default '0.0' comment '总余额',
`available_balance` decimal(12, 2) not null default '0.0' comment '可用余额',
`frozen_balance` decimal(12, 2) not null default '0.0' comment '冻结金额',
`create_time` datetime not null default current_timestamp comment '创建时间',
`update_time` datetime not null default current_timestamp comment '更新时间'
)comment '账户信息表';
create index `idx_tai_account_no` on t_account_info(account_no);
2、账户余额变动表
这个表主要用于回溯账户余额的变动,可以清晰地看出账户何时因为什么操作入账、扣账、冻结或者释放,实在是账户系统必备。
# 账户余额变动表
create table `t_account_balance_change`
(
`id` bigint primary key auto_increment comment '主键ID',
`account_no` varchar(24) not null comment '账户号',
`trans_id` varchar(24) not null comment '交易ID',
`trans_sn` varchar(24) not null comment '交易流水号',
`trans_amount` decimal(12, 2) not null comment '交易金额',
`trans_type` varchar(16) not null comment '交易类型',
`org_total_balance` decimal(12, 2) not null comment '原总余额',
`current_total_balance` decimal(12, 2) not null comment '当前总余额',
`org_avail_balance` decimal(12, 2) not null comment '原可用金额',
`current_avail_balance` decimal(12, 2) not null comment '当前可用金额',
`org_frozen_balance` decimal(12, 2) not null comment '原冻结金额',
`current_frozen_balance` decimal(12, 2) not null comment '当前冻结金额',
`remark` varchar(64) null comment '备注',
`create_time` datetime not null default current_timestamp comment '创建时间'
) comment '账户余额变动表';
create index `idx_tabc_account_create_time` on t_account_balance_change (account_no, create_time);
3、账户交易记录表
这个表主要用于记账,记账主要分为单式记账和复式记账,由于账户入金来源于系统外部,我们采用单式记账就好。
# 账户交易记录
create table `t_account_trans_log`
(
`id` bigint primary key auto_increment comment '主键ID',
`account_no` varchar(24) not null comment '账户号',
`account_owner` varchar(24) not null comment '账户所属人(商户号或者用户号)',
`trans_sn` varchar(24) not null comment '交易流水号',
`trans_amount` decimal(12, 2) not null comment '交易金额',
`trans_type` varchar(16) not null comment '交易类型',
`status` varchar(2) not null default 'P' comment '交易状态:P-处理中, S-交易成功, F-交易失败',
`remark` varchar(255) null comment '备注',
`create_time` datetime not null default current_timestamp comment '创建时间',
`update_time` datetime not null default current_timestamp comment '更新时间'
) comment '账户交易记录表';
create index `idx_tatl_trans_sn_create_time` on t_account_trans_log(trans_sn, create_time);
create index `idx_tatl_owner_create_time` on t_account_trans_log(account_owner, create_time);
4、微信商家转账到零钱业务表
这个是提现业务表,由于我们是通过微信商家转账到零钱
来实现,所以这个表主要为了业务层使用,比如处理交易回调。
# 微信商家转账到零钱申请表
create table `t_wx_merchant_transfer`
(
`id` bigint primary key auto_increment comment '主键ID',
`account_no` varchar(24) not null comment '账号',
`batch_no` varchar(32) not null comment '批次号',
`batch_status` varchar(2) not null default 'A' comment '批次状态: W-待付款确认, A-已受理, P-转账中, F-已完成, C-已关闭',
`detail_no` varchar(32) not null comment '明细单号',
`detail_status` varchar(2) not null comment '明细状态: I-初始态, W-待付款确认, P-转账中, S-转账成功, F-转账失败',
`total_amount` decimal(12, 2) not null comment '转账金额',
`total_num` int not null default 1 comment '转账总笔数',
`batch_id` varchar(64) null comment '微信内部批次单号',
`detail_id` varchar(64) null comment '微信内部明细单号',
`transfer_remark` varchar(32) null comment '转账备注',
`batch_close_reason` varchar(64) null comment '批次关闭原因(批次状态为关闭才有)',
`batch_fail_reason` varchar(64) null comment '批次失败原因',
`detail_fail_reason` varchar(64) null comment '明细失败原因',
`create_time` datetime not null default current_timestamp comment '创建时间',
`update_time` datetime not null default current_timestamp comment '更新时间'
) comment '微信商家转账到零钱申请表';
create index `idx_twmt_batch_no_create` on t_wx_merchant_transfer (batch_no, create_time);
create index `idx_twmt_detail_no_create` on t_wx_merchant_transfer (detail_no, create_time);
备注:查可提现金额直接从账户信息表取可用余额即可,查已提现或者待提现金额统计账户交易记录表即可。
四、交易类型和操作说明
1、3种交易类型
根据系统业务,我们主要定义了三种交易类型,分别是结算充值、返现充值和提现。
- 结算充值:结算人员次日结算,点击确认结算后
入账到商家钱包
触发的交易。 - 返现充值:结算人员次日结算,点击确认结算后
入账到学子和代理商钱包
触发的交易。 - 提现:商家、学子、代理商
提现
时触发的交易。
2、4种动账操作
钱包账户充值、提现会触发4种动账操作,这里详细讲解一下资金的流向。
资金操作 | 触发时间 | 备注 |
---|---|---|
加可用余额、加总金额 | 确认结算触发 | |
减可用余额、加冻结金额 | 申请提现时触发 | 加冻结金额是为了保证资金够扣、以及释放 |
减冻结金额、减总余额 | 微信回调通知,提现成功时触发 | |
减冻结金额、加可用余额 | 微信回调通知,提现失败时触发 |
五、结语
设计就到这里,整体业务流程还是相对不复杂的,了解基本的账户概念就可以上手。
这里不得不提微信商家转账到零钱出新版API了,老版本的API设计说实话有点复杂,引入了转账批次和转账详情的概念,但实际业务场景不用拆分。
重点是升级后的API版本对用户收款的体验做了优化,大家有类似接入微信商家转账到零钱的需求可以使用最新版本,API更简单。