Custom Integrations
Integrate UNQVerify directly against the browser-facing API contract without installing the SDK.
Custom Integrations
This section documents the raw browser-facing contract that the JavaScript SDK wraps.
Use it when your shop, CMS, or frontend stack cannot install @unqtech/age-verification-mitid, or when you want to control storage, callbacks, and UI yourself.
If you can install npm packages, use the JavaScript SDK instead. The SDK removes most of the code shown in this section while keeping the same underlying flow.
What stays the same
Even without the SDK, the verification flow is still browser-first:
- Your frontend requests a verification redirect URL from UNQVerify.
- The user completes MitID verification.
- Your callback page receives a
jwtquery parameter. - Your app verifies the JWT signature against the correct JWKS endpoint.
- Your app stores the verification result and updates the checkout or storefront UI.
Prerequisites
Before implementing a custom integration, make sure you have:
- A UNQVerify account
- A public API key from API Keys
- A whitelisted domain in Domains
- A callback page that will act as your
RedirectUri
Use a pk_test_... key during development and a pk_live_... key in production.
How the SDK maps to the raw flow
| SDK helper | What you implement yourself |
|---|---|
init(config) | Keep your own config object with publicKey, ageToVerify, and redirectUri |
startVerificationWithRedirect() | Call POST /api/v1/oidc/create, then redirect the browser to the returned URL |
startVerificationWithPopup() | Call the same endpoint, but load the returned URL into a popup window |
handleRedirectResult() | Read jwt from the callback URL, verify it against JWKS, then store the result |
isVerified() | Read your stored token and confirm that it is still valid |
getVerifiedAge() | Read aldersverificeringdk_verification_age from the verified token |
resetVerification() | Delete your stored token or session state |
Request contract used by the SDK
The SDK chooses the environment from the public key prefix and then calls the browser-facing OIDC session endpoint.
| Environment | Public key prefix | API base |
|---|---|---|
| Test | pk_test_ | https://test.api.aldersverificering.dk |
| Production | pk_live_ | https://api.aldersverificering.dk |
The request shape is:
- Method:
POST - Path:
/api/v1/oidc/create - Header:
x-public-key: pk_test_...orpk_live_... - Query parameters:
RedirectUriandAgeToVerify - Response body: plain-text redirect URL
Choose your path
Redirect flow
Use redirect flow when you want the simplest no-SDK integration.
- Best for: classic storefronts and custom checkout pages
- Docs: Redirect Flow
API reference
Use the API reference when you want exact endpoint, parameter, and response tables.
- Best for: teams building their own wrappers or implementation docs
- Docs: API Reference
Popup flow
Use popup flow when you want to keep the current page visible.
- Best for: modal flows, drawers, and embedded checkout experiences
- Docs: Popup Flow
Token validation
Use the token-validation helpers to match the SDK's JWT verification and storage behavior.
- Best for: merchants who want parity with SDK behavior
- Docs: Token Validation
Recommended architecture
- Start the verification flow in the browser
- Verify the returned JWT before trusting it
- Store the verified token in a secure, short-lived cookie or session
- Re-validate server-side before finalizing restricted actions such as checkout or order placement
If you store the verification JWT with JavaScript, for example via document.cookie, any XSS on the merchant site can read and replay that token. Treat browser-side storage as a UI convenience, not as your final security boundary.
That last point matters. Our WooCommerce integration uses the SDK in the browser, but still validates the returned JWT on the server before accepting an order.