KYC verification
LootBox Solutions can run identity verification (KYC) for your players end to end: you request a verification link over S2S, the player completes a hosted verification page, the platform’s compliance team reviews the submission, and you mirror the outcome from a webhook. You never handle documents — only statuses.
The flow
- Your backend mints a verification URL with
POST /api/s2s/kyc/sessions, passing the player’s contact email and, optionally, areturnOriginfor the completion signal. - Your page opens the URL in a popup window —
window.open, not an iframe. The verification page refuses framing outright (it shipsframe-ancestors 'none'), so an iframe embed renders nothing. A plainwindow.open(kycUrl)popup, PSP-checkout style, is the supported shape. - The player completes the hosted wizard — uploading their identity documents. The page also offers a QR hand-off so the player can continue on their phone mid-flow; no work on your side.
- The platform team reviews the submission and confirms or rejects it.
- You track every step via the
kyc_status_changedwebhook — including the moment the request is created.
// after your backend fetched { kycUrl } over S2S:const popup = window.open(kycUrl, 'kyc', 'width=480,height=720');The minted URL is valid for 30 minutes and single-use — mint a fresh one each time the player clicks “verify”.
Status lifecycle
PENDING ─▶ SUBMITTED ─▶ CONFIRMED │ │ └───────────┴──────▶ REJECTED| Status | Meaning |
|---|---|
PENDING | A verification request is open; the player hasn’t finished uploading. |
SUBMITTED | The player finished uploading; the submission awaits review. |
CONFIRMED | Reviewed and approved. Terminal. |
REJECTED | Reviewed and refused. Terminal. |
- A decision (
CONFIRMED/REJECTED) can arrive fromPENDINGorSUBMITTED— the reviewer may decide before the player finishes uploading. - Terminal statuses are final for that request. A redo creates a new request
with a new
requestId: subsequent webhooks carry the new id, starting with its ownPENDINGevent. Track per-player state as the latest request wins.
Enabling KYC
Everything lives in Settings → Integration, under the KYC section:
- KYC verification — the master switch. Off by default; while off, the
S2S session mint refuses with
KYC_DISABLEDand players cannot start a verification. - Success email — whether the player is emailed when their verification is confirmed. On by default.
- Rejection email — whether the player is emailed when their verification is rejected. On by default. The rejection email always embeds a fresh restart link, so a rejected player can re-verify without a round-trip through your site; the new request row is only created if the player actually clicks it.
Emails go to the address you pass when minting the session — keep it current
with POST /api/s2s/kyc/email if the
player changes it mid-verification.
The completion signal
When the player reaches the success page, the popup posts a message to the
window that opened it (window.opener), targeted at the returnOrigin you
passed when minting — never broadcast:
window.addEventListener('message', (e) => { if (e.data?.source !== 'lootbox-solutions') return; if (e.data.type === 'kyc_flow_finished') refreshKycStatus();});Treat it as a UX hint, not as truth:
- Also refresh on window focus — the player may close the popup before the success page, and a popup can’t signal you after it’s gone.
- The webhook is the authoritative sync.
kyc_flow_finishedmeans “the player finished the wizard”, not “approved” — the decision arrives later viakyc_status_changed.
If you omit returnOrigin when minting, the popup stays silent and you rely on
the webhook (and focus-refresh) alone.
Data handling
Identity documents are collected and stored privately by the platform. Operators receive verification outcomes only — statuses on the webhook and in the admin — never the documents themselves, and no email or document data ever appears in a webhook payload.