PAYATHON 2026

是否存在与信用卡读卡器通信的标准协议?

支付小周

结论

目前没有一种能被所有信用卡读卡器、收单机构和支付处理商共同支持的“发送金额、返回成功或失败”协议。

EMV、ISO 7816、ISO 14443、ISO 8583、nexo Retailer Protocol 等行业标准确实存在,但各自解决的问题不同。采用这些标准,并不代表任何收银程序都能用同一套接口控制任何读卡器。

实际开发中通常使用“半集成支付”方案。收银程序只把金额和订单标识发给经过认证的支付终端,由终端负责读卡、持卡人验证、加密以及与收单系统通信,再把授权结果返回给收银程序。接口一般由终端厂商、支付网关或收单机构提供。

为什么不能直接支持任意读卡器

“信用卡读卡器”可能是单纯读取卡片数据的外设,也可能是一台完整的支付终端,两者差别很大。

普通读卡外设可能通过 USB HID、串口或厂商驱动输出卡片数据,但不一定能独立完成支付。完整终端通常包含:

  • 磁条、芯片卡和非接触式读卡模块
  • PIN 输入及持卡人验证
  • 密钥和加密模块
  • EMV 交易内核
  • 与收单机构或支付处理商通信的能力
  • 撤销、退款、批结算和交易查询功能

支付终端还要通过 EMV、PCI PTS、卡组织和收单机构等相关认证。终端的软件配置、密钥、商户号和路由通常由收单方或服务商管理,不能通过更换服务器地址来切换支付服务。

所以,“让商户自由配置任何支付服务,同时支持任意终端”通常无法靠一种通用协议实现。

相关标准分别解决什么问题

EMV

EMV 规定芯片卡或非接触式卡与支付终端之间的交易处理方式,包括应用选择、持卡人验证和交易密码计算等。

它描述的主要是“卡与终端”之间的交互,并不是收银应用控制支付终端的统一 API。

ISO 7816 和 ISO 14443

ISO 7816 涉及接触式智能卡,ISO 14443 涉及非接触式卡和近场通信。它们属于较低层次的标准,不能直接解决收银程序与完整支付终端之间的业务交互问题。

ISO 8583

ISO 8583 常用于在支付终端、收单系统和处理网络之间传输授权及交易报文。

它不是一种可以直接连接任意读卡器的即插即用协议。即使双方都声称使用 ISO 8583,字段定义、私有域、报文头、网络封装、安全机制和密钥管理也可能不同。

nexo Retailer Protocol 等零售终端协议

nexo Retailer Protocol 等标准更接近收银系统与支付终端之间的接口,但并非所有终端、收单机构和地区都支持。能否实际使用,还要看设备型号、终端固件,以及支付服务商是否实现并开放了相应协议。

推荐的系统结构

更可行的结构如下:

收银应用
   │
   │ 金额、币种、订单号
   ▼
支付终端或本地支付中间件
   │
   │ 加密后的支付交易
   ▼
收单机构或支付处理商
   │
   │ 授权结果
   ▼
支付终端
   │
   │ approved / declined / cancelled / unknown
   ▼
收银应用

收银应用不读取 PAN、PIN、磁道数据或 EMV 敏感数据,只处理订单金额和非敏感的交易结果。这可以降低安全风险,也可能缩小 PCI DSS 的评估范围。是否适用,仍需根据具体方案由合规机构确认。

实施步骤

1. 定义支付终端适配层

不要让收银业务直接依赖某个厂商的 SDK,可以先定义自己的接口:

type PaymentStatus =
  | "approved"
  | "declined"
  | "cancelled"
  | "pending"
  | "unknown";

interface PaymentRequest {
  orderId: string;
  amountMinor: number;
  currency: string;
}

interface PaymentResult {
  status: PaymentStatus;
  transactionId?: string;
  authorizationCode?: string;
  receiptData?: unknown;
  message?: string;
}

interface PaymentTerminal {
  purchase(request: PaymentRequest): Promise<PaymentResult>;
  query(orderId: string): Promise<PaymentResult>;
  cancel(orderId: string): Promise<PaymentResult>;
}

金额应以最小货币单位的整数表示。例如,1099 表示 10.99 元,这样可以避免直接使用二进制浮点数表示货币。

2. 为不同方案编写适配器

每种实际支持的终端或支付服务都需要一个适配器:

class VendorTerminalAdapter implements PaymentTerminal {
  constructor(
    private readonly endpoint: string,
    private readonly terminalId: string
  ) {}

  async purchase(request: PaymentRequest): Promise<PaymentResult> {
    // 下列字段和地址仅用于展示适配层结构,
    // 不能作为任何真实终端的接口规范。
    const response = await fetch(`${this.endpoint}/payments`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "Idempotency-Key": request.orderId
      },
      body: JSON.stringify({
        terminalId: this.terminalId,
        reference: request.orderId,
        amount: request.amountMinor,
        currency: request.currency
      })
    });

    if (!response.ok) {
      return {
        status: "unknown",
        message: `Terminal request failed: HTTP ${response.status}`
      };
    }

    const result = await response.json();

    return {
      status: mapVendorStatus(result.status),
      transactionId: result.transactionId,
      authorizationCode: result.authorizationCode,
      receiptData: result.receipt
    };
  }

  async query(orderId: string): Promise<PaymentResult> {
    throw new Error("Implement according to the selected terminal API");
  }

  async cancel(orderId: string): Promise<PaymentResult> {
    throw new Error("Implement according to the selected terminal API");
  }
}

这里使用 HTTP 和 JSON 只是为了说明适配层的结构。真实终端可能通过串口、USB、TCP/IP、本地代理程序、厂商动态库或云端 API 通信,具体字段也必须以供应商文档为准。

3. 选择明确支持收银集成的供应商

需要向终端厂商或收单机构确认:

  • 是否提供 POS/ECR integration
  • 是否支持 semi-integrated 模式
  • 通信方式是串口、USB、局域网还是云端 API
  • 是否提供 SDK、协议文档和测试终端
  • 支持哪些收单机构和处理平台
  • 商户是否可以更换收单方
  • 是否支持交易查询、撤销、退款和批结算
  • 是否提供认证环境及集成认证流程
  • 终端断网或应用超时时,如何确认最终交易状态

如果供应商只提供读卡硬件,没有支付应用、密钥部署和收单连接,通常无法独立完成所需的交易。

不能只返回一个布尔值

支付结果不应只设计成 true 或 false,至少需要区分:

  • approved:已经明确批准
  • declined:已经明确拒绝
  • cancelled:顾客或收银员取消
  • pending:仍在处理中
  • unknown:请求超时或连接中断,最终结果尚未确定

其中,unknown 很重要。应用超时时,交易可能已经在终端或收单系统中获批。如果此时立即重新扣款,可能产生重复交易。应当使用唯一订单号或幂等键查询原交易,确认结果后再决定是否重试。

还要保存终端返回的交易标识、授权码、时间和必要的回执信息,供退款、撤销和对账使用。

安全与合规注意事项

不要要求终端把完整卡号、磁道数据、PIN 或敏感认证数据返回给收银程序。即使硬件可以输出这些数据,也会大幅增加安全和合规负担。

还需要注意:

  • 不要自行存储完整磁道数据或 PIN。
  • 日志中应屏蔽卡号、令牌及其他敏感字段。
  • 使用经过支付方案认可的终端、固件和连接方式。
  • 不要自行实现 EMV 内核或支付加密协议,除非准备承担完整的认证工作。
  • 退款、撤销和交易查询必须遵循供应商规定的流程。
  • PCI DSS、PCI P2PE 等要求是否适用,取决于实际的数据流和部署方式。不能因为使用了独立终端,就直接认定系统已经合规。

最现实的产品策略

如果软件需要支持多个商户和支付服务,通常可以采用两条路线:

  1. 选择一家提供半集成终端方案的供应商,先支持该供应商认可的终端和收单渠道。
  2. 在收银软件中建立统一的 PaymentTerminal 接口,再逐个实现不同供应商的适配器。

商户可以在已经支持的适配器中选择支付服务,但产品无法合理承诺“任意读卡器加任意处理商均可直接配置”。终端型号、固件、密钥、商户账户和收单路由必须相互兼容,并组成经过批准的方案。

备注:内容仅供参考。