Skip to content

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

  1. Your backend mints a verification URL with POST /api/s2s/kyc/sessions, passing the player’s contact email and, optionally, a returnOrigin for the completion signal.
  2. Your page opens the URL in a popup windowwindow.open, not an iframe. The verification page refuses framing outright (it ships frame-ancestors 'none'), so an iframe embed renders nothing. A plain window.open(kycUrl) popup, PSP-checkout style, is the supported shape.
  3. 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.
  4. The platform team reviews the submission and confirms or rejects it.
  5. You track every step via the kyc_status_changed webhook — 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
StatusMeaning
PENDINGA verification request is open; the player hasn’t finished uploading.
SUBMITTEDThe player finished uploading; the submission awaits review.
CONFIRMEDReviewed and approved. Terminal.
REJECTEDReviewed and refused. Terminal.
  • A decision (CONFIRMED / REJECTED) can arrive from PENDING or SUBMITTED — 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 own PENDING event. 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_DISABLED and 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_finished means “the player finished the wizard”, not “approved” — the decision arrives later via kyc_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.