由于公司业务需要,花两周时间实现了一个小型的支付系统,麻雀虽小五脏俱全,各种必须的模块如账户加锁,事务性保证,流水对帐等都是有完整实现的,整个开发过程中有很多经验积累,再加上在网上搜索了一下,大部分都是些研究性的论文,对实际使用价值不大,所以这次特意拿出来和大家分享一下。
这个系统可以用作小型支付系统,也可以用做第三方应用接入开放平台时的支付流水系统。
原来的需求比较负责,我简化一点说:
对每个应用,对外需要提供 获取余额,支付设备,充值 等接口
后台有程序,每月一号进行清算
账户可以被冻结
需要记录每一次操作的流水,每天的流水都要和发起方进行对账
针对上面的需求,我们设置如下数据库:
CREATE TABLE `app_margin`.`tb_status` (
`appid` int(10) UNSIGNED NOT NULL,
`freeze` int(10) NOT NULL DEFAULT 0,
`create_time` datetime NOT NULL,
`change_time` datetime NOT NULL,
PRIMARY KEY (`appid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app_margin`.`tb_account_earn` (
`appid` int(10) UNSIGNED NOT NULL,
`create_time` datetime NOT NULL,
`balance` bigint(20) NOT NULL,
`change_time` datetime NOT NULL,
`seqid` int(10) NOT NULL DEFAULT 500000000,
PRIMARY KEY (`appid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app_margin`.`tb_bill` (
`id` int AUTO_INCREMENT NOT NULL,
`bill_id` int(10) NOT NULL,
`amt` bigint(20) NOT NULL,
`bill_info` text,
`bill_user` char(128),
`bill_time` datetime NOT NULL,
`bill_type` int(10) NOT NULL,
`bill_channel` int(10) NOT NULL,
`bill_ret` int(10) NOT NULL,
`appid` int(10) UNSIGNED NOT NULL,
`old_balance` bigint(20) NOT NULL,
`price_info` text,
`src_ip` char(128),
PRIMARY KEY (`id`),
UNIQUE KEY `unique_bill` (`bill_id`,`bill_channel`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app_margin`.`tb_assign` (
`id` int AUTO_INCREMENT NOT NULL,
`assign_time` datetime NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app_margin`.`tb_price` (
`name` char(128) NOT NULL,
`price` int(10) NOT NULL,
`info` text NOT NULL,
PRIMARY KEY (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `app_margin`.`tb_applock` (
`appid` int(10) UNSIGNED NOT NULL,
`lock_mode` int(10) NOT NULL DEFAULT 0,
`change_time` datetime NOT NULL,
PRIMARY KEY (`appid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT `app_margin`.`tb_assign` (`id`,`assign_time`) VALUES (100000000,now());
详细解释如下:
tb_status 应用的状态表。负责账户是否被冻结,账户的类型是什么(真实的需求是应用可能有两种账户,这里为简单所以没有列出) 阅读全文 »