Balanced Payment API 是否验证用户身份与账户信息?
明确结论
Balanced Payments 已于 2015 年停止服务,现在已无法通过 Balanced Payment API 验证这些信息。在历史版本中,API 会在商户开户、收款资格审核等流程里收集部分个人和企业资料,用于 KYC(Know Your Customer)及合规审核,但审核通过并不表示每一项数据都已得到真实性验证。
各字段过去的处理方式大致如下:
| 信息 | 历史上的处理方式 |
|---|---|
| Social Security Number(SSN) | 用于美国个人身份和税务合规审核,通常会结合姓名、出生日期和地址进行匹配 |
| Address | 用于身份匹配和风险审核,但不等于认证邮寄地址真实有效 |
| Account number | 创建银行账户时检查格式和路由信息;如需确认账户可用或由申请人控制,通常还要验证银行账户或查看实际 ACH 结果 |
| Legal name | 与其他个人或企业身份资料一起提交,用于 KYC 匹配 |
| EIN | 用于美国企业身份和税务资料审核 |
| Date of birth | 与姓名、地址、SSN 等资料结合,用于个人身份匹配 |
Balanced 主要判断个人或企业能否通过支付合规审核,并不提供一个通用接口,逐项返回”姓名真实""地址真实”或”SSN 有效”。
验证通常发生在哪个阶段
创建普通客户记录并不表示身份已经通过验证。过去,身份审核通常发生在用户申请成为可收款商户,或启用需要 KYC 的支付能力时。
典型流程如下:
- 收集个人或企业资料。
- 由服务端检查资料的格式和完整性。
- 将资料提交给支付平台的商户审核接口。
- 查看接口返回的审核状态。
- 自动审核无法完成时,按平台要求补充资料或转入人工审核。
- 单独验证银行账户,不能把身份审核结果当成银行账户所有权证明。
各字段具体能验证到什么程度
SSN、姓名、出生日期和地址
这些字段通常需要组合验证。支付平台可能会通过第三方身份数据库、信用信息来源、公共记录或其他合规数据源进行匹配。
检查结果一般只能说明资料”匹配""无法确认”或”需要补充资料”,无法保证:
- 提交资料的人就是证件持有人;
- 地址仍是当前居住地址;
- SSN 未被冒用;
- 所有信息都来自同一个真实用户。
业务系统仍需根据风险等级增加手机验证、证件审核或人工复核。
EIN 和企业名称
企业账户通常需要提交企业法定名称、EIN、注册地址和负责人信息。平台可能会将这些资料与企业或税务相关数据进行匹配。
EIN 格式正确,不代表这个 EIN 一定存在,也不能证明提交者有权代表该企业。高风险场景通常还要核验企业负责人和实际受益人。
银行账号
银行账号格式检查和账户所有权验证不是一回事。
API 接收账户资料时,通常只能立即检查:
- Routing number 是否符合基本格式;
- Account number 的长度等基础格式是否正确;
- Account type 是否属于支持的类型;
- 必填字段是否完整。
要确认账户真实存在且由用户控制,通常需要通过微额入账、即时银行验证或 ACH 交易结果来判断。即使某次 ACH 交易成功,也不能把它当作永久有效的账户所有权证明。
服务端校验示例
下面的代码仅演示向支付平台提交资料前的基础校验,并不是 Balanced 历史接口的可运行 SDK 示例。由于 Balanced 已停止服务,实际项目应改用当前支付服务商提供的 KYC 和银行账户验证接口。
function validateApplicant(input) {
const errors = [];
if (!input.legalName?.trim()) {
errors.push("legalName is required");
}
if (!/^\d{4}$/.test(input.ssnLast4 || "")) {
errors.push("ssnLast4 must contain exactly 4 digits");
}
if (!/^\d{2}-\d{7}$/.test(input.ein || "")) {
errors.push("ein must use the NN-NNNNNNN format");
}
if (!/^\d{9}$/.test(input.routingNumber || "")) {
errors.push("routingNumber must contain 9 digits");
}
const dateOfBirth = new Date(input.dateOfBirth);
if (Number.isNaN(dateOfBirth.getTime())) {
errors.push("dateOfBirth is invalid");
}
if (!input.address?.line1 || !input.address?.city ||
!input.address?.region || !input.address?.postalCode) {
errors.push("complete address is required");
}
return {
valid: errors.length === 0,
errors
};
}
基础校验通过后,应由服务端将资料发送给选定的支付服务商:
async function submitVerification(applicant, paymentProvider) {
const validation = validateApplicant(applicant);
if (!validation.valid) {
return {
status: "invalid_input",
errors: validation.errors
};
}
const result = await paymentProvider.createAccount({
businessType: applicant.businessType,
legalName: applicant.legalName,
dateOfBirth: applicant.dateOfBirth,
ssnLast4: applicant.ssnLast4,
ein: applicant.ein,
address: applicant.address,
bankAccountToken: applicant.bankAccountToken
});
return {
status: result.verificationStatus,
requirements: result.requirements
};
}
其中,paymentProvider.createAccount()、verificationStatus 和 requirements 都是抽象示例,并非 Balanced 的实际方法或字段。实际使用的名称应以当前服务商的官方文档为准。
实施时的注意事项
不要在浏览器日志、普通数据库字段或错误信息中记录完整的 SSN、EIN 和银行账号。敏感信息最好直接提交给支付服务商,业务系统只保存并使用相应的 token。
实施时还需注意:
- 前端格式校验不能代替 KYC;
- HTTP 请求成功不等于身份验证成功;
- 应区分
pending、verified、failed和requires_action等业务状态; - 银行账户验证和个人身份验证应分开处理;
- 对敏感字段采取传输加密、访问控制、脱敏和审计措施;
- 保存资料前,应确认 PCI、隐私保护、税务和当地金融监管要求;
- 迁移历史 Balanced 集成时,不要继续使用旧端点或旧密钥。应选择仍在运营,并支持 marketplace、KYC 和 ACH 验证的支付平台。
备注:内容仅供参考。