PAYATHON 2026

POS terminal 能否通过 IP network 直连 payment gateway?

支付老李

结论

可以实现,但通常不能随便购买一台带 Ethernet、PIN PAD 和签名屏的通用终端,再让它连接任意 payment gateway。

实际项目一般使用经过 payment gateway、收单机构或支付服务商认证的 semi-integrated POS 方案:

  • PC software 通过本地 API、SDK、TCP/IP 或 HTTPS 向终端发起交易。
  • 终端负责读卡、输入 PIN、处理 EMV 和加密敏感数据。
  • 终端通过 Ethernet/IP 与支付平台通信。
  • 支付完成后,终端或支付 SDK 只向 PC 返回非敏感的交易结果。

Ethernet 只是通信链路。终端能否直连 payment gateway,还要看终端型号、支付应用、收单渠道、密钥注入、EMV 认证,以及 gateway 是否提供对应的 terminal integration protocol。硬件接口兼容,不代表支付系统兼容。

推荐的系统结构

通常可以采用以下结构:

PC Software
    │
    │ Local SDK / HTTPS / TCP
    ▼
Payment Terminal
    │
    │ TLS over Ethernet/IP
    ▼
Payment Gateway / Processor / Acquirer

PC software 一般只发送业务指令,例如“开始一笔 100.00 元的销售交易”,不会直接读取卡号、CVV 或 PIN。

终端负责完成后续流程:

  1. 提示客户插卡、挥卡或刷卡。
  2. 执行 EMV 流程。
  3. 在需要时采集 PIN 或签名。
  4. 加密并发送支付数据。
  5. 接收授权结果。
  6. 向 PC software 返回交易状态和可安全使用的引用信息。

这样可以减少 PC software 接触敏感持卡人数据的机会,并显著缩小 PCI DSS 合规范围。

PC software 可以获得哪些数据

交易成功后,接口通常会返回:

  • approved 或其他响应状态
  • authorizationCode
  • transactionId
  • referenceNumber
  • maskedPAN,例如 ************1234
  • cardBrand
  • entryMode,例如 CHIP、CONTACTLESS 或 SWIPE
  • amount
  • currency
  • receiptData
  • signatureRequired 或签名引用

具体字段由支付服务商的接口决定。

CVV 不应返回给 PC software,也不能在授权完成后保存。即使接口允许在交易过程中接收 CVV,也不表示应用可以记录、打印或持久化这个值。PIN 同样不能以明文形式离开经过认证的 PIN PAD。

在没有明确业务需要和合规设计的情况下,也不应返回卡片有效期和完整 PAN。大多数集成只需要 masked PAN、last 4 digits、token 和 transaction reference。

签名采集

带触摸屏签名功能的终端可能采用以下处理方式:

  • 将签名随支付交易一起上传并保存在支付平台。
  • 向 PC 返回签名记录的 ID。
  • 通过受控 API 返回签名图片或签名数据。
  • 仅在终端的收据流程中使用,不允许外部系统读取。

能否“拉取签名”,要以具体终端和支付应用的 API 为准。签名是需要保护的数据,应用还要处理访问权限、保存期限、加密和隐私要求。

终端有触摸屏,并不表示它一定开放签名数据接口。

典型交易流程

建议按以下顺序实施:

  1. 先确定收单机构或 payment gateway。
  2. 获取该平台认证的终端型号列表。
  3. 确认终端是否支持 Ethernet、EMV、contactless、PIN 和所需的签名能力。
  4. 获取服务商提供的 POS SDK 或集成协议。
  5. 由 PC software 创建唯一的交易请求。
  6. 终端完成持卡人交互和在线授权。
  7. PC software 保存交易 ID、授权码、金额和 masked PAN。
  8. 退款、撤销和交易查询都通过原始 transaction ID 执行。
  9. 网络超时后先查询交易状态,不要马上重复扣款。

现代银行卡受理应优先支持插卡和 contactless,不能只设计磁条刷卡流程。磁条通常只用于特定场景下的后备处理。

接口示例

下面的抽象示例用于说明 PC software 与终端之间的数据边界。字段名称不对应任何厂商的正式 API。

PC software 发起交易:

POST /terminal/v1/payments
Content-Type: application/json
Idempotency-Key: 7fb39c2e-81cc-4d0b-a93d-43b55c40372e
{
  "terminalId": "LANE-03",
  "operation": "SALE",
  "amount": 12500,
  "currency": "CNY",
  "merchantReference": "ORDER-20260831-001",
  "captureSignature": true
}

amount 使用最小货币单位,12500 表示 125.00 元。具体含义仍以服务商文档为准。

终端或支付 SDK 返回:

{
  "status": "APPROVED",
  "transactionId": "txn_8f4c1a2d",
  "referenceNumber": "493812770001",
  "authorizationCode": "A17392",
  "amount": 12500,
  "currency": "CNY",
  "maskedPAN": "************1234",
  "cardBrand": "VISA",
  "entryMode": "CHIP",
  "signatureRequired": false,
  "receiptReference": "receipt_91ad62"
}

返回对象不应包含明文 PIN、PIN block、CVV 或完整磁道数据。

如果交易状态未知,可以使用原始引用号查询:

GET /terminal/v1/payments/by-reference/ORDER-20260831-001
{
  "status": "APPROVED",
  "transactionId": "txn_8f4c1a2d",
  "merchantReference": "ORDER-20260831-001"
}

PC 端处理示例

以下 C# 示例只展示通用处理逻辑。URL、认证方式和字段需要替换为实际服务商提供的接口。

using System.Net.Http.Json;

var request = new
{
    terminalId = "LANE-03",
    operation = "SALE",
    amount = 12500,
    currency = "CNY",
    merchantReference = "ORDER-20260831-001",
    captureSignature = true
};

using var client = new HttpClient
{
    BaseAddress = new Uri("https://127.0.0.1:9443/")
};

using var message = new HttpRequestMessage(
    HttpMethod.Post,
    "terminal/v1/payments");

message.Headers.Add(
    "Idempotency-Key",
    "7fb39c2e-81cc-4d0b-a93d-43b55c40372e");

message.Content = JsonContent.Create(request);

using HttpResponseMessage response = await client.SendAsync(message);
response.EnsureSuccessStatusCode();

PaymentResult? result =
    await response.Content.ReadFromJsonAsync<PaymentResult>();

if (result?.Status == "APPROVED")
{
    // 只保存支付平台允许保存的非敏感字段。
    Console.WriteLine($"Transaction: {result.TransactionId}");
    Console.WriteLine($"Authorization: {result.AuthorizationCode}");
    Console.WriteLine($"Card: {result.MaskedPAN}");
}
else
{
    Console.WriteLine($"Payment status: {result?.Status}");
}

public sealed class PaymentResult
{
    public string? Status { get; set; }
    public string? TransactionId { get; set; }
    public string? AuthorizationCode { get; set; }
    public string? ReferenceNumber { get; set; }
    public string? MaskedPAN { get; set; }
}

即使生产环境使用 127.0.0.1,也不能忽略认证和证书验证。如果服务商通过本地代理连接终端,需要按照其安全规范配置证书、端口和进程权限。

选型时应向供应商确认

询价时不能只列硬件功能,至少要确认以下事项:

  • 终端是否已通过目标收单机构或 gateway 的认证。
  • 服务商是否提供 semi-integrated SDK。
  • PC 与终端之间通过 USB、串口、局域网还是本地代理通信。
  • 终端能否自行通过 Ethernet 完成授权。
  • 是否支持 EMV contact、contactless 和必要的磁条后备流程。
  • 是否支持在线 PIN、离线 PIN,以及所在市场要求的 PIN 类型。
  • 是否支持签名采集和签名数据导出。
  • 返回结果包含哪些字段。
  • 是否提供 tokenization、退款、撤销、预授权和交易查询。
  • 遇到断网、超时、重复请求或终端重启时,如何恢复交易。
  • 由谁注入密钥,谁负责部署和维护终端。
  • PCI PTS、PCI DSS、EMV 及当地支付网络认证分别由哪一方负责。

关键注意事项

不要自行编写 PIN 加密、EMV kernel 或银行卡报文处理程序,也不要让普通 PC software 直接接触磁道数据、完整 PAN、CVV 或 PIN。这类设计会大幅增加安全风险和认证成本。

每笔请求都应带有唯一的 merchantReference 或 idempotency key。请求超时时,交易可能已经成功,只是响应没有返回。此时要先查询交易状态,再决定是否重试,否则可能造成重复扣款。

如果 PC 与终端位于同一局域网,还应限制对终端网段的访问,启用双向认证或厂商规定的配对机制,并阻止未授权设备向终端发起交易。

因此,这种方案在技术上可行,但采购顺序应当是:先确定 gateway 或收单服务,再选择经过认证的终端和 SDK。如果先购买通用终端,再尝试连接任意 payment gateway,很可能会遇到协议不开放、密钥无法注入或缺少收单认证等问题。

备注:内容仅供参考。