PAYATHON 2026

BlueSnap Payment API 的 PCI 合规级别及范围限制

支付阿杰

明确结论

如果应用通过 BlueSnap Payment API 直接接收、处理或转发银行卡号(PAN)、有效期、持卡人信息或 CVV,应用服务器和相关基础设施通常都会被纳入 PCI DSS 范围。商户一般需要填写 SAQ D,或按收单机构的要求接受更完整的合规评估。

要缩小合规范围,可以改用 BlueSnap 的托管支付方案,例如 Hosted Payment Fields 或托管结账页面。银行卡数据由用户浏览器直接提交给 BlueSnap,应用只接收支付令牌或交易结果。如果满足所有适用条件,这种架构通常可能适用 SAQ A。最终应填写哪种问卷,仍需由 BlueSnap、收单机构或 QSA 确认。

这里需要分清两个容易混淆的概念:

  • PCI 商户级别(Merchant Level):主要取决于年度交易量、卡组织规则,以及是否发生过数据泄露。
  • PCI 合规范围和 SAQ 类型:取决于银行卡数据如何进入系统,以及数据在系统中如何流转和存储。

使用 BlueSnap 本身既不会自动确定商户级别,也不能免除商户承担的 PCI DSS 责任。

为什么直接调用 Payment API 会扩大范围

假设支付流程如下:

Browser
  -> Merchant Application
  -> Merchant Backend
  -> BlueSnap Payment API

银行卡数据会经过商户控制的页面、接口、服务器、日志系统和网络环境。因此,被纳入评估范围的可能不只是支付接口,还包括:

  • Web 前端及其加载的 JavaScript
  • API 网关、负载均衡器和反向代理
  • 应用服务器及容器运行环境
  • 日志、监控、链路追踪和错误报告系统
  • 数据库、缓存及消息队列
  • CI/CD、运维账号和密钥管理系统
  • 其他能够连接或影响持卡人数据环境的系统

应用即使不保存银行卡号,只要接收、处理或转发过这些数据,通常仍在 PCI DSS 范围内。

推荐的缩小范围方案

更合适的数据流如下:

Browser
  -> BlueSnap Hosted Payment Fields
  -> BlueSnap

Browser
  -> Merchant Backend(仅提交 BlueSnap token)
  -> BlueSnap Payment API

实施时可以按以下步骤处理:

  1. 使用 BlueSnap 的 Hosted Payment Fields 或托管结账页面采集银行卡信息。
  2. 确保 PAN 和 CVV 从浏览器直接传给 BlueSnap,不经过商户后端。
  3. 后端只接收 BlueSnap 返回的支付令牌,再用令牌创建交易。
  4. 禁止任何接口接收原始银行卡号和 CVV。
  5. 检查日志、监控和异常上报配置,避免记录支付表单内容或完整请求体。
  6. 使用 BlueSnap 的 vaulted shopper 或其他令牌化功能处理后续支付。
  7. 适当隔离支付页面与其他业务页面,并严格控制第三方脚本。
  8. 保存数据流图、接口清单和责任分工,再交由收单机构或 QSA 确认适用的 SAQ。

代码层面的边界控制

下面是一种实现思路。浏览器端具体使用哪些初始化方法和参数,应以当前 BlueSnap Hosted Payment Fields 文档为准。不要把示例中的占位逻辑直接当作官方 SDK 调用。

// 浏览器端:卡号、有效期和 CVV 由 BlueSnap 托管字段采集。
// 商户代码只获取支付令牌,不读取托管字段中的原始卡数据。

async function submitPayment(blueSnapToken) {
  const response = await fetch("/api/payments", {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify({
      paymentToken: blueSnapToken,
      amount: "49.90",
      currency: "USD"
    })
  });

  if (!response.ok) {
    throw new Error("Payment request failed");
  }

  return response.json();
}

后端应主动拒绝含有原始银行卡字段的请求:

import express from "express";

const app = express();
app.use(express.json());

app.post("/api/payments", async (req, res) => {
  const forbiddenFields = [
    "cardNumber",
    "pan",
    "cvv",
    "cvc",
    "securityCode"
  ];

  const receivedForbiddenField = forbiddenFields.some(
    (field) => req.body[field] !== undefined
  );

  if (receivedForbiddenField) {
    return res.status(400).json({
      error: "Raw card data must be submitted directly to BlueSnap"
    });
  }

  const { paymentToken, amount, currency } = req.body;

  if (!paymentToken || !amount || !currency) {
    return res.status(400).json({
      error: "Missing required payment data"
    });
  }

  // 使用 paymentToken 调用 BlueSnap Payment API。
  // API 地址、认证方式和请求结构以当前 BlueSnap 文档为准。
  const result = await createBlueSnapTransaction({
    paymentToken,
    amount,
    currency
  });

  res.status(200).json({
    transactionId: result.transactionId,
    status: result.status
  });
});

日志也不应输出完整的请求体:

// 不推荐
logger.info("payment request", req.body);

// 推荐:只记录排查交易所需的非敏感信息
logger.info("payment request", {
  orderId: req.body.orderId,
  currency: req.body.currency,
  amount: req.body.amount
});

必须注意的限制

使用令牌不等于自动脱离 PCI 范围

如果原始卡数据先到达商户服务器,再由服务器将其换成令牌,令牌化并不能消除已经发生的数据处理行为。要缩小范围,原始卡数据从一开始就不能进入商户系统。

CVV 不得在授权后保存

CVV 属于敏感认证数据,即使经过加密,也不能在交易授权完成后保存。日志、调试快照、会话回放、客服工单和错误追踪平台也需要逐一检查,防止它们间接记录 CVV。

托管字段不会消除所有安全责任

恶意脚本、遭到篡改的第三方依赖和错误配置仍可能影响支付页面,因此还需要采取以下措施:

  • 使用 HTTPS 和安全响应头
  • 配置 Content Security Policy
  • 尽量减少第三方脚本
  • 控制依赖项和脚本变更
  • 为管理员启用多因素认证
  • 定期轮换密钥并执行最小权限原则
  • 开展漏洞扫描和补丁管理
  • 监控支付页面的完整性

SAQ 类型需要正式确认

不能仅凭“使用了 iframe”或“没有保存卡号”,就判断应当填写 SAQ A、SAQ A-EP 还是 SAQ D。页面脚本、重定向方式、支付表单的控制权、交易流程及收单机构的要求,都可能影响最终结论。

建议向 BlueSnap 或收单机构提供完整的数据流图,并明确询问:

  • 当前集成方式对应哪种 SAQ?
  • 商户后端是否会接触 PAN、有效期或 CVV?
  • 哪些系统属于持卡人数据环境或连接系统?
  • 是否需要外部漏洞扫描(ASV scan)?
  • BlueSnap 与商户分别负责哪些 PCI DSS 控制项?

如果业务必须通过后端直接处理原始银行卡数据,就应按照更大的 PCI DSS 范围设计系统,并尽早请 QSA 参与评估,不要等开发完成后再补做合规边界。

备注:内容仅供参考。