Demo scenarios · Click2Pay / EMVCo
デモシナリオ・Click2Pay / EMVCo
Requires a user gesture, but it can be any natural UI element in the checkout flow (login button, checkbox,
etc.) — no separate "allow storage" step. When the SRC Common iframe hasn't been granted access yet, it
becomes visible and shows an Allow button — that click is the user gesture triggering
requestStorageAccess(). Works with Firefox ETP because the gesture originates from a click
inside the iframe, which ETP accepts. Safari shows an additional native browser popup after the gesture.
ユーザージェスチャーが必要ですが、チェックアウトフローの自然なUI要素(ログインボタン、チェックボックスなど)で代用できます——別途「ストレージを許可」するステップは不要。SRC Common iframeにアクセスが許可されていない場合、iframeが表示され「Allow」ボタンが現れます——そのクリックがrequestStorageAccess()を呼び出すユーザージェスチャーです。Firefox ETPではiframe内のクリックが起点となるためETPが受け入れます。Safariはジェスチャー後にブラウザのネイティブポップアップを表示します。
allow="storage-access" on merchant pagesマーチャントページのiframeに allow="storage-access" 属性
document.hasStorageAccess() → auto-grant on return (user previously visited src-common as first-party)document.hasStorageAccess() →
再訪時に自動許可(ユーザーがsrc-commonをファーストパーティとして訪問済みの場合)
SRC_SHOW_IFRAME postMessage to parent → iframe becomes visible with
#access-overlay自動許可なし → SRC_SHOW_IFRAME をparentにpostMessage → iframeが
#access-overlay 付きで表示
document.requestStorageAccess() → success →
SRC_HIDE_IFRAMEiframe内「Allow」クリック = ユーザージェスチャー → requestStorageAccess() → 成功 →
SRC_HIDE_IFRAME
fetch('/recognized', { credentials: 'include' })HTTP専用クッキーで認識: fetch('/recognized', { credentials: 'include' })
COOKIE_IS_RECOGNIZED / COOKIE_SET_RECOGNIZED / COOKIE_CLEAR_RECOGNIZED between merchant and bridge (storage: HTTP-only cookie)マーチャントとブリッジ間のpostMessageプロトコル(ストレージ: HTTP専用クッキー)
src-common-debug relays iframe logs to monitor (direct tab)BroadcastChannel src-common-debug でiframeログをモニター(直接タブ)に中継
Recognition relies entirely on an HTTP-only cookie (SameSite=None; Secure) set by the NestJS
backend. The cookie is sent automatically on every fetch with credentials: 'include'. Storage
Access API is called but without any custom UI — the browser must auto-grant access (Chrome does, Firefox
without ETP does). Fails with Firefox ETP (blocks 3rd-party cookies even after SAA grant) and Safari
(requires gesture for SAA).
認識はNestJSバックエンドが設定するHTTP専用クッキー(SameSite=None; Secure)のみに依存します。クッキーはcredentials: 'include'を使った全fetchで自動送信されます。Storage Access APIは呼び出されますが独自UIなし——ブラウザが自動で許可する必要があります(ChromeとETPなしFirefoxは対応)。Firefox ETP(SAA許可後も3rdパーティクッキーをブロック)とSafariでは失敗します。
allow="storage-access" — required for cross-site cookiesallow="storage-access" — クロスサイトクッキーに必須
document.hasStorageAccess() → if false → document.requestStorageAccess() with no UI (auto-grant)falseなら → UIなしで requestStorageAccess()(自動許可)
Set-Cookie: recognized=1; HttpOnly; SameSite=None; SecureHTTP専用クッキー: バックエンドが
Set-Cookie: recognized=1; HttpOnly; SameSite=None; Secure を設定
/recognized use credentials: 'include'/recognized への全fetchで credentials: 'include' を使用
COOKIE_IS_RECOGNIZED / COOKIE_SET_RECOGNIZED / COOKIE_CLEAR_RECOGNIZED + BroadcastChannel debug relaypostMessageプロトコル COOKIE_* + BroadcastChannelデバッグ中継
SRC Common stores data entirely client-side in IndexedDB (src-common-db) on its own origin — no
backend. Cross-site access obtained via requestStorageAccess({ all: true }) (Chrome 125+),
which returns a StorageAccessHandle with unpartitioned handle.indexedDB and
handle.BroadcastChannel. In Firefox, SAA grants only cookie access — IDB remains partitioned by
dFPI, so fails with ETP. No recognition support (store only).
SRC Commonはデータを自身のオリジンのIndexedDB(src-common-db)にクライアント側のみで保存します——バックエンドなし。クロスサイトアクセスはrequestStorageAccess({ all: true })(Chrome 125+)で取得し、非分離のhandle.indexedDBとhandle.BroadcastChannelを持つStorageAccessHandleを返します。FirefoxではSAAはクッキーアクセスのみ許可——IDBはdFPIにより分離されたままのためETPでは失敗します。recognition機能なし(ストアのみ)。
allow="storage-access" on merchant pagesマーチャントページのiframeに allow="storage-access" 属性
document.requestStorageAccess({ all: true }) → StorageAccessHandle (Chrome 125+)StorageAccessHandle を返す(Chrome 125+)
handle.indexedDB instanceof IDBFactory → unpartitioned IDB; fallback:
window.indexedDB (partitioned)非分離IDB; フォールバック: window.indexedDB(分離)
handle.BroadcastChannel → unpartitioned debug channel; fallback:
window.BroadcastChannel非分離デバッグチャンネル; フォールバック: window.BroadcastChannel
#gesture-overlay) inside iframe + SRC_COMMON_NEEDS_GESTURE postMessage to parentiframe内ジェスチャーオーバーレイ + SRC_COMMON_NEEDS_GESTURE をparentにpostMessage
db.transaction('data', 'readwrite').objectStore('data').put(value, key)requestStorageAccess() (cookies-only) → IDB still partitioned →
[FF: IDB still partitioned] in logFFフォールバック: クッキーのみ → IDBは依然分離 → ログに [FF: IDB still partitioned]
credentials: 'include', no backend — pure client-side storagecredentials: 'include' なし、バックエンドなし——純粋なクライアント側ストレージ
State stored entirely server-side (NestJS). SRC Common iframe fetches the backend through the HTTPS proxy — no browser storage APIs, no Storage Access API. Works in all browsers because it bypasses browser storage partitioning entirely. Requires a stable user key passed by merchants — without it every session is anonymous and isolated.
状態はすべてサーバー側(NestJS)に保存されます。SRC Common iframeはHTTPSプロキシ経由でバックエンドにアクセス——ブラウザストレージAPI不使用、Storage Access API不使用。ブラウザのストレージ分離を完全に回避するため全ブラウザで動作します。マーチャントから渡される安定したユーザーキーが必要——なければ各セッションは匿名かつ分離されます。
allow="storage-access" on iframe — SAA not needediframeに allow="storage-access" なし——SAA不要
document.requestStorageAccess anywhere in src-common codesrc-commonコードに document.requestStorageAccess なし
credentials: 'include' — no cookie dependencycredentials: 'include' なし——クッキー依存なし
GET/PUT/DELETE /store/:key via HTTPS reverse-proxyストア: NestJS REST API GET/PUT/DELETE /store/:key、HTTPSリバースプロキシ経由
STORE_READ / STORE_WRITE / STORE_READ_ALL / STORE_DELETEpostMessageプロトコル