rapid-ztx
Version:
Rapid ZTX module
146 lines (127 loc) • 4.57 kB
JavaScript
/**
* Copyright (c) 2017 Lucky Byte, Inc.
*/
const debug = require('debug')('ztx');
const uuid = require('uuid');
const rapid_db = require('rapid-db');
const auth = require('../lib/auth');
const utils = require('../lib/utils');
/**
* 绑定借记卡
*
* 参数:
* info: 绑卡参数,包含下面的数据:
* * sumer: 用户 uuid
* * card_no: 卡号
* * name: 持卡人姓名
* * idno: 持卡人证件号码
*
* 返回:
* 失败抛出异常,成功返回借记卡完整信息
*/
const bind = async (info) => {
const keys = [
'sumer', 'card_no', 'name', 'idno'
];
for (let i = 0; i < keys.length; i++) {
const key = keys[i];
if (!info[key]) {
throw new Error(`绑定借记卡错:缺少参数[${key}]`);
}
}
if (!/^[0-9xX]{18}$/.test(info.idno)) {
throw new Error('绑定借记卡错:证件号码格式错');
}
// 查询用户信息
const sumer = await unique_db.oneOrNone(`
select * from rapid_ctod_sumers where uuid = $1
`, [
info.sumer
]);
if (!sumer) {
throw new Error('绑定借记卡错:绑卡用户不存在');
}
// 用户已绑借记卡情况下,不能再次绑定借记卡
if (sumer.debit_card) {
throw new Error('绑定借记卡错:用户已绑定过借记卡');
}
// 用户已绑定贷记卡的情况下,不能绑定借记卡
// 这种情况应该不会存在,除非程序逻辑错误
if (sumer.credit_cards && sumer.credit_cards.length > 0) {
throw new Error('绑定借记卡错:用户已绑定过贷记卡');
}
// 验证证件号码是否正确
if (!utils.verify_idno(info.idno)) {
throw new Error('绑定借记卡错:身份证号码无效');
}
// 查询卡 BIN 信息,如果查询不到,则无法获取发卡行名称等信息
let bin_info = await rapid_db.cardbin.query(info.card_no);
if (!bin_info) {
throw new Error('绑定借记卡错:查询卡 BIN 信息错,请检查卡号');
}
if (!bin_info.issuer_name) {
throw new Error('绑定借记卡错:未查询到银行卡开户行名称');
}
// 检查是否为借记卡,卡 BIN 信息中有此标识
if (bin_info.debit_credit_flag != 1) {
throw new Error('绑定借记卡错:此卡非借记卡(储蓄卡)');
}
// 查询借记卡开户城市,开户行城市在代付时是必须的,如果没有查询成功,则设置为上海
try {
const result = await utils.query_card_city(info.card_no);
bin_info.issuer_city = result.city || '上海';
} catch (err) {
await rapid_db.notify.warn(err.message);
bin_info.issuer_city = '上海';
}
// 银行卡实名认证
await auth.card_auth(sumer, Object.assign(info, {
card_type: bin_info.debit_credit_flag,
}));
// 绑卡,同时更新用户的姓名和证件号码,清空贷记卡
const debit_card = {
name: info.name,
idno: info.idno,
card_no: info.card_no,
bank_name: bin_info.issuer_name,
bank_city: bin_info.issuer_city,
card_type: bin_info.debit_credit_flag,
issuer_code: bin_info.issuer_code,
card_name: bin_info.card_name,
bin_num: bin_info.bin_num,
bin_len: bin_info.bin_len,
}
// 只有借记卡为空的情况下才能绑定借记卡
const returning = await unique_db.oneOrNone(`
update rapid_ctod_sumers set
debit_card = $1, name = $2, idno = $3, credit_cards = null
where uuid = $4 and debit_card is null
returning debit_card
`, [
debit_card, info.name, info.idno, sumer.uuid
]);
if (!returning) {
throw new Error('绑定借记卡错:重复绑定');
}
// 记录绑卡历史
await unique_db.none(`
insert into rapid_ctod_bhist (
uuid, sumer, action, card, notes
) values (
$1, $2, $3, $4, $5
)
`, [
uuid.v4(), sumer.uuid, 1, debit_card, '绑定借记卡'
]);
// 给代理商联系人发送邮件通知
try {
const html = `
<p>用户[${info.name}][${sumer.mobile}]已绑定借记卡!</p>
`;
await utils.mail_to_agent(sumer.agent, '用户绑卡通知', html);
} catch (err) {
await rapid_db.notify.warn(`发送绑卡通知邮件错: ${err.message}`);
}
return debit_card;
}
module.exports = bind;