PAYATHON 2026

如何区分 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,可用于查询发卡机构、卡组织、国家和资金类型。不过,这种查询仍有一些限制:

  1. BIN/IIN 数据会变化。旧数据库可能把新发行的借记卡识别为信用卡。
  2. 同一家发卡机构可能使用相近的号码段发行信用卡、借记卡和预付卡。
  3. 部分支付服务商只有在授权后才能返回准确的资金类型。
  4. 不同数据源可能会将联名卡、商业卡、公共福利卡和预付卡归入不同类别。
  5. 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 值。

处理流程应为:

  1. 服务端创建或获取 Payment Method。
  2. 从可信的支付服务商响应中读取资金类型。
  3. 根据商户协议、适用法律和卡组织规则计算费用。
  4. 在提交支付前向用户清楚展示总金额。
  5. 服务端再次校验费用,防止请求参数被修改。

手续费规则可能受到州法律、卡组织规则、收单合同、公用事业类型和付款渠道影响,不能仅凭“这是 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 当成第三种支付卡。应优先采用支付服务商或收单机构提供的卡片元数据,并根据授权结果判断交易是否成功。

备注:内容仅供参考。