Skip to main content

Secure Elements 是什麼

Secure Elements 是一個 JavaScript SDK,@fluz/secure-elements,可將一個隔離的、由 Fluz 代管的 frame 直接掛載到你頁面上的容器元素中。該 frame 會渲染或收集卡片資料;你的頁面與伺服器僅會持有一個短期有效、不可讀的權杖,用於授權某一特定動作。它涵蓋兩項能力:
  • Card Reveal — 向使用者顯示其自身的 PAN、到期日與 CVV。
  • Secure Card Input — 收集一張實體卡,並將其新增為該帳戶的付款方式。
針對揭示功能,這是讓使用者查看其卡片資訊的第三種方式,與你已具備的兩種方式並列: 相同的取捨也適用於收集卡片:小工具可讓 Fluz 在其自身的 PCI 範疇內擷取 PAN,而 Secure Card Input 則讓你在自有頁面內嵌方式(非模態)獲得相同的「永不觸及你的伺服器」特性。
如果你已將所有流程都使用 Embedded Widget,那就不需要這個。Secure Elements 適用於無頭或 API 驅動的整合情境,當你需要顯示或收集卡片資訊,但又不想開啟完整的小工具模態視窗、或不打算追求 PCI_COMPLIANCE 時。

運作方式

你的後端產生 client token

以你現有的 Fluz OAuth access token 兌換取得短期有效的 client token,其範圍限於一次揭示或一次加卡。

你的前端掛載 frame

將 client token 交給 @fluz/secure-elements,它會把由 Fluz 代管的 frame 掛載到你提供的容器中 — 內嵌於你的頁面,而非模態。

SDK 透過回呼回報結果

你的頁面永遠不會讀取原始卡片資料。它只會接收到成功、錯誤,或掛載事件。

先決條件

  • 你的應用程式已在 Fluz 註冊。你的 access token 所需的 scope 取決於你為何種能力產生 client token:
  • 就揭示用的 token 而言,你還需要一個屬於你要揭示之帳戶、狀態為 ACTIVE 的 virtual card id,在產生 token 時一併傳入。
在你撰寫任何程式碼之前,請要求 Fluz 將你的來源(origin)加入允許清單。 若非 Fluz 事先核准的來源,frame 會拒絕渲染 — 目前沒有自助開關可供設定,因此若擱置此步驟,可能成為唯一會阻擋你進度的先決條件。請寄信到 partnerships@fluz.app(或聯繫你的客戶經理,若你已有對口)並提供你的應用程式名稱或 ID,以及你需要核准的每個來源 — 你開發時使用的每個 http://localhost:PORT,外加你的測試與正式網域。Fluz 會在後端加入允許清單;完成後你端不需任何設定。

環境

frameHostOrigin 在 createCardViewer 中是選填 — 省略時預設為正式環境(https://secure.fluz.app)。若要指向測試環境,請明確傳入。僅接受這兩個完全相符的來源;其他任何值都會在你呼叫 createCardViewer 的當下(在掛載任何 frame 之前)擲出 FluzElementsError(error.code === "INVALID_FRAME_HOST_ORIGIN")。

載入 SDK

@fluz/secure-elements 不會發布到 npm — 請透過 <script> 標籤從 Fluz 的 CDN 以瀏覽器全域(IIFE)建置載入。它會暴露一個全域 FluzSecureElements:
本頁與 Card Reveal 上的每個程式碼範例,皆假設你已載入該 script 標籤,並如上所示從 FluzSecureElements 解構所需方法。 每次發行都會發布到不可變、更版鎖定的路徑(.../v0.1.0/index.global.js),以及一個浮動的 .../latest/index.global.js,永遠指向最新版本。除原型外,請鎖定特定版本 — latest 可能在未通知的情況下變更。

產生 client token

你的後端會使用你已透過標準 OAuth grant flow 取得的 Fluz OAuth access token 來呼叫此端點。切勿將該 access token 傳到瀏覽器 — 只有此端點回傳的 clientToken / loadToken 配對應交給前端。
purpose 可為 "reveal"(需提供 virtualCardId)或 "tokenization"(不需 virtualCardId — 參見 Secure Card Input)。
成功產生會回傳 201。兩個權杖皆為單一用途且短期有效 — 請每次皆重新產生一對。clientToken 用於授權揭示或加卡本身(有效時間為 expiresIn 秒 — reveal 預設 300 秒,tokenization 為 1800 秒);loadToken 的範圍更窄(60 秒),因為它會在 URL 中傳遞,且只能用於載入 frame,其餘場合皆會被拒絕。請將兩者直接傳入 createCardViewer 或 renderFieldsForTokenization,且切勿自行把 clientToken 放入 URL — SDK 會確保它不會出現在 URL 中。
| Status | Error | Meaning | | :— | :— | :— | | 400 | invalid_purpose | purpose missing or invalid | | 400 | virtual_card_id_required | missing virtualCardId for a reveal token | | 401 | unauthorized | missing access token | | 401 | invalid_token | access token failed verification (malformed, expired, wrong signature) | | 403 | insufficient_scope | access token missing the scope required for this purpose — see Prerequisites | | 403 | app_not_registered | your application isn’t registered — contact Fluz | | 403 | forbidden | card not found, or not owned by this user | | 429 | rate_limited | too many client-token requests for this user — see the Retry-After header | | 500 | internal_error | unexpected server error |

欄位樣式

createCardViewer 可接受選填的 style 物件,會套用至其掛載的每個欄位:
style 會在任何資料送往 frame 之前先行驗證。若某個值與下列文件規格不符,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 Font 會在欄位掛載後才抓取,並非預先打包,因此在冷快取的情況下,欄位會先以瀏覽器的後備字型短暫顯示,之後再切換成你選擇的字型。系統字型則沒有此延遲。
若你想自行驗證字型選擇或建立字型挑選器,兩份清單皆可匯出:

內容安全政策(CSP)

若你的頁面設定了 CSP,請允許你目標的 frame host,以及 SDK 載入的 CDN 主機:
SDK 本身會從 script-src 所允許的主機載入;你自行整合程式中的內嵌 <script> 區塊(如本頁、Card Reveal 與 Secure Card Input 的範例)若 CSP 不允許 'unsafe-inline',仍需要自己的 nonce 或雜湊。若使用 nonce,標籤上的值必須與標頭中的值完全相符:

安全模型

  • 你的 OAuth access token 絕不會離開你的伺服器。
  • 你的前端持有的 client token 是不可讀且單一用途的 — 它不承載任何卡片資料,且不能重放於不同卡片或動作。
  • 卡片資料只會在由 Fluz 代管的 frame 內可讀,並與你的頁面 JavaScript 隔離。每個 frame 皆受 sandbox(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 確認範疇。

下一步

Card Reveal

建立卡片檢視器、掛載它,並控制要揭示哪些欄位。

Secure Card Input

收集一張實體卡,並將其新增為付款方式。

即時示範

於測試環境中查看兩項能力的實際運作。

範例整合

可執行的純 HTML 與 React 範例,皆呼叫真實的測試基礎設施。

OAuth 應用程式

如何取得你將用來兌換 client token 的 access token。