Skip to main content

什么是 Secure Elements

Secure Elements 是一个 JavaScript SDK,@fluz/secure-elements,它会将一个隔离的、由 Fluz 托管的框架直接挂载到你页面中的某个容器元素内。该框架用于渲染或收集卡片数据;你的页面和服务器只会持有一个短期有效的、不透明的令牌,用于授权某一个具体操作。它涵盖两种能力:
  • 卡片展示 — 向用户展示其自己的 PAN、有效期和 CVV。
  • 安全卡片输入 — 收集一张实体卡并将其添加为其账户上的支付方式。
对于展示而言,这是第三种向用户显示其卡片详情的方式,与你已经拥有的两种方式并列: 相同的权衡也适用于卡片收集:小部件允许 Fluz 在其自有的 PCI 范围内捕获 PAN,而 安全卡片输入 则能让你在自己的页面内联实现同样的“从不触达你的服务器”的属性,而非以模态弹窗形式。
如果你已经将 嵌入式小部件 用于所有内容,你并不需要这个。Secure Elements 面向无头或 API 驱动的集成场景,这些场景需要展示或收集卡片信息,但又不想打开完整的小部件模态框或申请 PCI_COMPLIANCE。

工作原理

你的后端铸造客户端令牌

使用你现有的 Fluz OAuth 访问令牌 交换一个短期有效的客户端令牌,其范围仅限一次展示或一次卡片添加。

你的前端挂载该 frame

将客户端令牌交给 @fluz/secure-elements,它会把 Fluz 托管的 frame 挂载到你提供的容器中 — 以内联形式嵌入你的页面,而非模态窗口。

SDK 通过回调反馈结果

你的页面从不读取原始卡片数据。它只会接收到成功、错误或挂载事件。

先决条件

  • 你的应用已在 Fluz 注册。你的访问令牌所需的 scope 取决于你要为哪种能力铸造客户端令牌:
  • 对于展示令牌,你还需要一个 ACTIVE 状态的虚拟卡 id,且由你要展示的该账户所持有,以便在铸造时传入。
在你编写任何代码之前,请求 Fluz 将你的来源域名加入允许列表。 如果来源域名未被 Fluz 预先批准,该 frame 将拒绝渲染 — 目前没有自助开关可用,因此这是唯一一个若被拖延会阻塞你的前置条件。请发送邮件至 partnerships@fluz.app(或你的客户经理,如有),并附上你的应用名称或 ID以及所有需要批准的来源域名 — 包括每个用于开发的 http://localhost:PORT,以及你的预发布与生产域名。Fluz 会在后端将它们加入允许列表;完成后你无需在自己这边进行任何配置。

环境

在 createCardViewer 中,frameHostOrigin 是可选的 — 省略则默认为生产环境(https://secure.fluz.app)。如需指向 staging,请显式传入。仅接受这两个精确的来源;任何其他值都会在你调用 createCardViewer 时立即抛出 FluzElementsError(error.code === "INVALID_FRAME_HOST_ORIGIN"),在挂载任何 frame 之前即报错。

加载 SDK

@fluz/secure-elements 不会发布到 npm — 请通过 <script> 标签从 Fluz 的 CDN 以浏览器全局(IIFE)构建加载。它会暴露一个全局 FluzSecureElements:
本页以及卡片展示上的每个代码示例都假设你已经加载了上述脚本标签,并从 FluzSecureElements 中解构出所需方法。 每个版本都会发布到一个不可变的、锁定版本的路径(.../v0.1.0/index.global.js),以及一个浮动的 .../latest/index.global.js,它始终指向最新版本。除原型以外的任何场景都应锁定到特定版本 — latest 可能在无通知情况下发生变化。

铸造客户端令牌

你的后端使用你已通过标准 OAuth 授权流程 获取的 Fluz OAuth 访问令牌来调用此接口。切勿将该访问令牌发送到浏览器 — 只有此端点返回的 clientToken / loadToken 对可以到达你的前端。
purpose 可为 "reveal"(需带 virtualCardId),或 "tokenization"(不需 virtualCardId — 见安全卡片输入)。
成功铸造会返回 201。两个令牌均为单一用途且短期有效 — 每次都需重新铸造一对。clientToken 用于授权展示或添加卡片本身(expiresIn 秒 — reveal 默认为 300,tokenization 为 1800);loadToken 的范围更窄(60 秒),因为它会出现在 URL 中,且除用于加载 frame 外会在其他地方被拒绝。将两者直接传入 createCardViewer 或 renderFieldsForTokenization,并且切勿自行将 clientToken 放入 URL — SDK 已经确保不会这么做。
| 状态 | 错误 | 含义 | | :— | :— | :— | | 400 | invalid_purpose | 缺少或无效的 purpose | | 400 | virtual_card_id_required | 为展示令牌缺少 virtualCardId | | 401 | unauthorized | 缺少访问令牌 | | 401 | invalid_token | 访问令牌验证失败(格式错误、过期、签名不匹配) | | 403 | insufficient_scope | 访问令牌缺少此 purpose 所需的 scope — 见 先决条件 | | 403 | app_not_registered | 你的应用尚未注册 — 请联系 Fluz | | 403 | forbidden | 找不到卡,或该卡不属于该用户 | | 429 | rate_limited | 针对此用户的客户端令牌请求过多 — 请查看 Retry-After 响应头 | | 500 | internal_error | 意外的服务器错误 |

样式化字段

createCardViewer 接受一个可选的 style 对象,它会应用到所挂载的每个字段上:
在任何内容发送到 frame 之前,style 会先被校验。如果某个值与下文所述不匹配,await viewer.mount(...) 会以 FluzElementsError 拒绝(error.code === "INVALID_STYLE")— 如果你允许外部配置样式,请用 try/catch 包裹你的 mount() 调用。 fontFamily 必须与以下两个白名单之一精确大小写匹配:
  • 系统字体 — 常见的操作系统/网页安全字体(system-ui、-apple-system、Helvetica Neue、Arial、Georgia、Menlo,以及通用关键词 monospace / serif / sans-serif 等)。这些字体可即时渲染,无需网络请求。
  • Google Fonts — 来自 Google Fonts 目录的任意字体族("Roboto"、"Inter"、"IBM Plex Mono" 等),需与 Google 列示名称完全一致。SDK 会为你加载该字体 — 你无需添加 <link> 标签或 @font-face 规则。
Google 字体会在字段挂载后获取,而不是预先打包,因此在冷缓存情况下会有一个短暂窗口,字段会先使用浏览器的回退字体渲染,然后再切换为你选择的字体。系统字体则没有这种延迟。
如果你想自行校验字体选择,或构建一个字体选择器,这两个列表都会被导出:

内容安全策略(CSP)

如果你的页面设置了 CSP,请允许你所指向的 frame 主机,以及 SDK 加载所用的 CDN 主机:
SDK 自身会从 script-src 允许的主机加载;你自己集成代码中的内联 <script>(如本页、卡片展示 和 安全卡片输入 的示例)如果你的 CSP 不允许 'unsafe-inline',仍需要其自身的 nonce 或哈希。如果你使用 nonce,标签上的值必须与响应头中的值完全一致:

安全模型

  • 你的 OAuth 访问令牌永不离开你的服务器。
  • 你的前端持有的客户端令牌是不透明且单一用途的 — 它不携带任何卡片数据,也不能被重放用于不同的卡片或操作。
  • 卡片数据只会在由 Fluz 托管的 frame 内可读,这些 frame 与你的页面 JavaScript 相互隔离。每个 frame 都被沙箱化(allow-scripts allow-same-origin allow-forms),并设置 referrerPolicy="no-referrer" — SDK 从不在这些 frame 之外将卡片数据放入 DOM。
  • 该 frame 只会在你已经向 Fluz 预注册的来源域名内渲染。
  • 卡片数据永远不会到达你的服务器或页面的 JavaScript — 这是实现 PCI DSS 下 SAQ A 资格的最相关条件之一,此外还需满足 SAQ A 的其他要求(例如你不应以其他方式存储、处理或传输持卡人数据)。你适用的 PCI DSS 义务取决于你的完整持卡人数据环境;请与 QSA 确认你的范围。

下一步

卡片展示

创建卡片查看器、进行挂载,并控制展示哪些字段。

安全卡片输入

收集一张实体卡并将其添加为支付方式。

在线演示

查看两种能力在 staging 环境中的运行效果。

示例集成

可运行的纯 HTML 与 React 示例,均调用真实的 staging 基础设施。

OAuth 应用

了解如何获取你将用于交换客户端令牌的访问令牌。