如何区分 Debit Card、Check Card 和 Credit Card?
结论
只凭用户输入的卡号,无法可靠判断一张卡是 Debit Card、Check Card 还是 Credit Card。
在美国支付场景中,Check Card 通常是银行对带有 Visa、Mastercard 等网络标识的 Debit Card 的称呼,并不是单独的卡片类型。实际业务一般区分以下几类即可:
credit:信用卡debit:借记卡prepaid:预付卡unknown:暂时无法识别
更可靠的方式是将卡片交给支付服务商进行 tokenization,或者用它创建 Payment Method,然后读取服务商返回的 funding、card_type 或类似字段。BIN/IIN 数据库可以辅助判断,但不适合作为最终依据。
为什么不能直接从卡号判断
卡号虽然遵循支付卡号规则,但其中并不直接包含“信用卡”或“借记卡”属性。卡号前 6 位或 8 位通常称为 BIN/IIN,可用于查询发卡机构、卡组织、国家和资金类型。不过,这种查询仍有一些限制:
- BIN/IIN 数据会变化。旧数据库可能把新发行的借记卡识别为信用卡。
- 同一家发卡机构可能使用相近的号码段发行信用卡、借记卡和预付卡。
- 部分支付服务商只有在授权后才能返回准确的资金类型。
- 不同数据源可能会将联名卡、商业卡、公共福利卡和预付卡归入不同类别。
Check Card没有适用于所有发卡机构的独立统一识别规则。
因此,不应根据卡号长度、卡组织标识、CVV 位数或用户是否输入 PIN 来推断卡片类型。
推荐的处理流程
1. 前端只负责安全采集卡片
使用支付服务商提供的 Hosted Fields、Elements 或托管支付页面采集卡号。不要让卡号经过自己的服务器,也不要将完整卡号写入日志、数据库或分析系统。
前端应得到 token、Payment Method ID 或 nonce,而不是原始卡号。
2. 后端读取支付服务商返回的卡片属性
各支付服务商使用的字段名称不完全相同,常见响应形式如下:
{
"card": {
"brand": "visa",
"funding": "debit",
"country": "US",
"last4": "1234"
}
}
业务代码需要兼容字段缺失和未知值:
function normalizeFundingType(paymentMethod) {
const funding = paymentMethod?.card?.funding;
switch (funding) {
case "credit":
return "credit";
case "debit":
return "debit";
case "prepaid":
return "prepaid";
default:
return "unknown";
}
}
这里的字段结构只是通用示例。实际接入时,应以所用支付服务商的 API 文档和真实响应为准。
3. 不要单独建立 check_card 类型
可以在界面文案中向用户说明:
Debit Card 包括银行可能称为 Check Card 的卡片。
后端统一记录为 debit。例如:
type FundingType = "credit" | "debit" | "prepaid" | "unknown";
interface StoredCardMetadata {
paymentMethodId: string;
brand?: string;
funding: FundingType;
last4?: string;
issuerCountry?: string;
}
除非支付处理商明确返回并定义了 check_card,否则自行增加这一类型通常会造成重复分类。
4. 正常处理 unknown
识别结果不应成为支付能否继续的唯一条件。如果支付服务商允许用该卡发起交易,可以继续授权,并暂时将资金类型记为 unknown:
async function handleUtilityPayment(paymentMethod) {
const funding = normalizeFundingType(paymentMethod);
if (funding === "unknown") {
console.warn("Card funding type is unavailable", {
paymentMethodId: paymentMethod.id
});
}
return authorizePayment({
paymentMethodId: paymentMethod.id,
amount: 12500,
currency: "USD"
});
}
日志只能记录 token、Payment Method ID、品牌和卡号后四位等允许保存的信息,不能记录完整 PAN 或 CVV。
BIN/IIN 查询适合什么场景
如果支付服务商无法返回资金类型,可以使用商业 BIN/IIN 数据源进行预判。查询应在服务器端完成,并至少支持 8 位 IIN,因为只查询传统的前 6 位数据可能不够准确。
伪代码如下:
async function lookupFundingType(binOrIin) {
const result = await binProvider.lookup(binOrIin);
if (!result) {
return "unknown";
}
const type = String(result.fundingType || "").toLowerCase();
if (["credit", "debit", "prepaid"].includes(type)) {
return type;
}
return "unknown";
}
BIN/IIN 查询得到的是元数据判断,并不等同于发卡行对本次交易的最终处理结果。数据库需要持续更新,还要确认其许可条款允许在生产环境中使用。
不要为了查询 BIN/IIN 而将完整卡号发送给额外的第三方。通常只需传送规定长度的卡号前缀,同时仍要评估 PCI DSS 范围和相应的数据安全责任。
“借记卡”还涉及交易路由方式
卡片被识别为 Debit Card,并不能直接说明交易会通过哪条网络处理。在美国,一张带有卡组织标识的借记卡可能支持多种处理方式:
- 作为无 PIN 的网络品牌交易处理
- 作为需要 PIN 的借记交易处理
- 由支付处理商根据可用网络选择路由
Web Payments 通常不会直接采集实体键盘上的 PIN。是否支持 PINless Debit、应该使用哪条网络,以及如何选择路由,需要由收单机构、支付处理商、发卡行和商户配置共同决定。
因此,funding = debit 只能表示资金来源类型,不能代替交易路由信息。如果公用事业支付需要使用特定借记网络、获得较低费率或支持实时入账,应向支付处理商确认:
- 是否支持 PINless Debit
- 支持哪些借记网络
- 是否由处理商自动选择路由
- 失败后是否可以转由其他卡网络处理
- API 中哪个字段表示实际使用的网络
公用事业账单场景的注意事项
手续费不能只靠前端识别决定
如果信用卡和借记卡适用不同的 convenience fee 或 service fee,不要根据用户在页面上选择的卡片类型收费,也不要只相信前端传来的 funding 值。
处理流程应为:
- 服务端创建或获取 Payment Method。
- 从可信的支付服务商响应中读取资金类型。
- 根据商户协议、适用法律和卡组织规则计算费用。
- 在提交支付前向用户清楚展示总金额。
- 服务端再次校验费用,防止请求参数被修改。
手续费规则可能受到州法律、卡组织规则、收单合同、公用事业类型和付款渠道影响,不能仅凭“这是 Debit Card”得出统一结论。生产上线前,应由收单机构或法律合规人员确认。
不要要求用户自行选择卡片类型
让用户勾选“Credit Card”或“Debit Card”可以作为界面提示,但不能作为可信的分类依据。很多用户并不知道银行所说的 Check Card 实际属于 Debit Card,也可能把带有 Visa 标志的借记卡误认为信用卡。
识别结果可能在授权后才出现
有些处理商在创建 Payment Method 时就能返回资金类型,另一些则要等到授权或交易完成后才能提供。系统数据模型应允许先保存 unknown,再根据交易结果更新:
function updateFundingFromTransaction(cardRecord, transaction) {
const funding = transaction?.paymentMethodDetails?.card?.funding;
if (["credit", "debit", "prepaid"].includes(funding)) {
return {
...cardRecord,
funding
};
}
return cardRecord;
}
拒付和余额不足不能靠类型判断
即使卡片被识别为借记卡,也不能提前确认账户余额充足。识别为信用卡,同样不代表一定有可用额度。付款最终能否完成,仍以发卡行对授权请求的响应为准。
实际落地建议
美国公用事业 Web Payments 可以采用以下规则:
Check Card -> 按 Debit Card 处理
Debit Card -> 以支付服务商返回的 funding/card_type 为准
Credit Card -> 以支付服务商返回的 funding/card_type 为准
Prepaid Card -> 单独记录,按业务和合规要求决定是否接受
无法识别 -> 记录为 unknown,通常仍可尝试授权
不要自行解析卡号并将结果作为最终分类,也不要把 Check Card 当成第三种支付卡。应优先采用支付服务商或收单机构提供的卡片元数据,并根据授权结果判断交易是否成功。
备注:内容仅供参考。
