Skip to Content
API 參考身分驗證
View as Markdown

身分驗證

InfraIO Pay 有兩個 API 介面,各自採用不同的驗證模型。請依照 呼叫者身份選擇:

介面路徑前綴對象驗證
商家 B2B/b2b/v1/*你的伺服器HMAC-SHA256 請求簽章
儀表板供商家儀表板使用商家儀表板的瀏覽器 sessionBearer JWT

本頁介紹 B2B 介面,也就是你從伺服器以 API 金鑰組呼叫的介面。 儀表板介面由 InfraIO Pay 商家儀表板使用,並非公開的整合介面。

請一律傳送含 /b2b 前綴的完整路徑,並對同一路徑簽章(見下文)。

Endpoints

環境Base URL
Testhttps://api-dev.infraio.xyz
Livehttps://api.infraio.xyz

URL 模式相同 — 環境是由金鑰前綴(pk_test_… vs pk_live_…) 控制,而非 URL。

金鑰組

你會從商家儀表板取得兩個值(Developers → API keys → + Add key):

  • Publishable key(pk_test_… 或 pk_live_…)— 識別你的帳號。 以 X-Client-ID 傳遞。可以安全地嵌入瀏覽器 bundle(SDK 已經這樣做)。
  • Secret key(sk_test_… 或 sk_live_…)— HMAC 簽章金鑰。 僅限伺服端使用。視同資料庫密碼般保護。

若 secret key 不慎流入瀏覽器 bundle、git repo、log 或聊天室 — 立刻從儀表板撤銷它。撤銷會立即生效,沒有重疊視窗。請發行新金鑰 並重新部署。

簽章請求

每個對 /b2b/v1/* 的呼叫都會帶三個標頭:

X-Client-ID: pk_live_70d0becbd7a53047b0dfe88a960d10ad X-Timestamp: 1715990400 X-Signature: 9a8b7c6d… (hex HMAC-SHA256)

簽章是針對 canonical string 計算的:

METHOD + "\n" + PATH + "\n" + TIMESTAMP + "\n" + BODY
  • METHOD — 大寫的 HTTP verb(POST、GET 等)。
  • PATH — 請求路徑含 /b2b 前綴,不含 host 且不含 query string (例如 /b2b/v1/checkout-sessions/quick)。前綴必須存在。Query 參數 不參與簽章 — 對於 GET …?cursor=…&limit=20,只簽路徑,不要 簽 ?… 部分。
  • TIMESTAMP — Unix 秒,以十進位字串表達(例如 "1715990400"), 須與 X-Timestamp 完全一致。
  • BODY — 原始請求 body 位元組。GET/DELETE 為空字串。

以 secret key 做 HMAC-SHA256,輸出 hex:

import { createHmac } from "node:crypto"; function sign({ method, path, body, secret }: { method: string; path: string; body: string; secret: string; }) { const timestamp = Math.floor(Date.now() / 1000).toString(); const input = [method.toUpperCase(), path, timestamp, body].join("\n"); const signature = createHmac("sha256", secret).update(input).digest("hex"); return { timestamp, signature }; }

為什麼是 HMAC,而非 Bearer?

純 Bearer token 的 API 會在每次請求都把你唯一的 secret 上線傳輸。 任何拿到 TLS 終止點代理 log 的人都能取得你帳號的金鑰。HMAC 簽章 代表 secret 永遠不會旅行 — 只傳遞它派生出的簽章,而該簽章是一次性 的(綁定該確切的請求 + 該確切的分鐘)。

代價是:每次呼叫都要計算簽章。目前尚無伺服器端 SDK, 但上面的輔助程式碼每種語言只需約 15 行。

Timestamp 容差

容差是 ±5 分鐘(300 秒)。超出此視窗的請求會被拒絕, 並回傳 401 invalid_signature。兩項影響:

  1. 同步你的伺服器時鐘(使用 NTP)。長時間執行的 cron,若時鐘 漂移,會間歇性失敗。
  2. 不要預先計算並排隊簽章。 若一個請求在 retry queue 中停留 >5 分鐘,它的簽章會過期。

Key scopes

Secret key 帶有一或多個下列 scope 組合:

Scope預期用途
read列出 / 讀取訂單、session、退款
write_order建立結帳 session、訂單
write_refund發起退款、鑄造退款申請 token
webhook_manage建立 / 更新 / 刪除 webhook endpoint

儀表板預設發行「full access」金鑰(全部四個 scope)。你可以從 Developers → API keys → + Add key 鑄造受限 scope 金鑰,並只 勾選該整合所需的 scope。

Scope 目前尚未強制執行。 Scope 會記錄於金鑰上並顯示在儀表板, 但任何有效的 sk_… 金鑰都能呼叫你商家的任意 /b2b/v1/* endpoint。 請不要把 scope 當成安全邊界,並透過輪替或撤銷金鑰來限制存取。

驗證失敗

若簽章、X-Client-ID 或 timestamp 無效,請求會在到達 API 之前被拒絕, 並回傳 401 INVALID_SIGNATURE。只有 /b2b/v1/* 請求採用這種簽章方式。 Webhook 使用另一套機制(見下文)。

下一步

  • 錯誤 — 4xx/5xx 的回應格式。
  • 安全 → API 金鑰 — 輪替、撤銷,以及 secret 外洩時該怎麼做。
  • Webhooks → 簽章驗證 — 使用不同的 HMAC 機制(標頭 X-Signature: sha256=…,簽 X-Timestamp + "." + raw_body,加上 24 小時輪替寬限視窗內的選用 X-Signature-Prev)。請別把兩套機制混用 — 雖然 hash 演算法相同, 但所簽位元組與 secret 系列(whsec_… vs sk_…)都不一樣。