什么是 Secure Elements
Secure Elements 是一个 JavaScript SDK,@fluz/secure-elements,它会将一个隔离的、由 Fluz 托管的框架直接挂载到你页面中的某个容器元素内。该框架用于渲染或收集卡片数据;你的页面和服务器只会持有一个短期有效的、不透明的令牌,用于授权某一个具体操作。它涵盖两种能力:
对于展示而言,这是第三种向用户显示其卡片详情的方式,与你已经拥有的两种方式并列:
相同的权衡也适用于卡片收集:小部件允许 Fluz 在其自有的 PCI 范围内捕获 PAN,而 安全卡片输入 则能让你在自己的页面内联实现同样的“从不触达你的服务器”的属性,而非以模态弹窗形式。
如果你已经将 嵌入式小部件 用于所有内容,你并不需要这个。Secure Elements 面向无头或 API 驱动的集成场景,这些场景需要展示或收集卡片信息,但又不想打开完整的小部件模态框或申请
PCI_COMPLIANCE。工作原理
你的后端铸造客户端令牌
使用你现有的 Fluz OAuth 访问令牌 交换一个短期有效的客户端令牌,其范围仅限一次展示或一次卡片添加。
你的前端挂载该 frame
将客户端令牌交给
@fluz/secure-elements,它会把 Fluz 托管的 frame 挂载到你提供的容器中 — 以内联形式嵌入你的页面,而非模态窗口。SDK 通过回调反馈结果
你的页面从不读取原始卡片数据。它只会接收到成功、错误或挂载事件。
先决条件
-
你的应用已在 Fluz 注册。你的访问令牌所需的 scope 取决于你要为哪种能力铸造客户端令牌:
-
对于展示令牌,你还需要一个
ACTIVE状态的虚拟卡 id,且由你要展示的该账户所持有,以便在铸造时传入。
环境
在
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 已经确保不会这么做。
样式化字段
createCardViewer 接受一个可选的 style 对象,它会应用到所挂载的每个字段上:
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 主机: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 应用
了解如何获取你将用于交换客户端令牌的访问令牌。