Flonk
Flonk Docs

Frontend ↔ Backend Integration

Integrate Flonk KYC with full TypeScript SDK or REST API for any backend language.

Last updated: 8/25/2026
5 min read

Building a native mobile app or a fully custom UI without the widget? See Direct API (No SDK) — the same flow driven with plain REST calls.

Quick Start (Node.js SDK)

npm install @flonkid/kyc
bash
ImportUse
@flonkid/kycBrowser — widget iframe + postMessage
@flonkid/kyc/serverNode.js — sessions API + webhook verification
@flonkid/kyc/typesTypeScript types only

1. Backend: Create session endpoint

Your backend creates a KYC session using the secret key, then returns sessionId + embedToken (+ qrCodeUrl for the mobile-transfer QR) to the frontend.

1import { FlonkKYCServer } from '@flonkid/kyc/server';
2
3const flonk = new FlonkKYCServer({
4 secretKey: process.env.FLONK_SECRET_KEY!,
5 // apiBase: 'https://api.flonk.id/v1', // optional, default
6});
7
8// Express / Next.js API route
9app.post('/api/kyc/create-session', async (req, res) => {
10 try {
11 const session = await flonk.createSession({
12 clientMetadata: req.body.clientMetadata,
13 expiryMinutes: 30,
14 language: 'de',
15 });
16
17 // Return what the browser SDK needs. Map `id` → `sessionId`, and include
18 // `qrCodeUrl` so the desktop→mobile QR renders.
19 res.json({
20 sessionId: session.id,
21 embedToken: session.embedToken,
22 qrCodeUrl: session.qrCodeUrl,
23 });
24 } catch (err) {
25 console.error('Session creation failed:', err.message);
26 res.status(err.statusCode || 500).json({ error: err.message });
27 }
28});
typescript

2. Frontend: Start KYC

The snippets below are React. Vue / Svelte / Angular use the same FlonkKYC class imported from @flonkid/kyc/core (the React-free entry — see Frontend SDK), and no-build pages (WordPress, Rails, plain HTML) load one <script> tag from the API — see Script Tag (No Build Step). The session flow (A vs B) below is identical across all of them.

There are two integration approaches. Choose one:

Option A: SDK handles everything (serverUrl)

SDK auto-creates the session via your backend endpoint, opens the widget, and handles cleanup. Simplest approach — one component, zero state management.

If your backend requires authentication, pass requestHeaders:

<FlonkKYCWidget
publishableKey="pk_live_..."
serverUrl="/api/kyc/create-session"
requestHeaders={{ Authorization: `Bearer ${token}` }}
...
/>
tsx

publishableKey loads your project branding (colors, logo) instantly while the session is being created. Find it in Dashboard → API Keys.

1import { FlonkKYCWidget } from '@flonkid/kyc';
2
3export default function KYCVerification() {
4 return (
5 <FlonkKYCWidget
6 publishableKey="pk_live_..."
7 serverUrl="/api/kyc/create-session"
8 clientMetadata={{
9 email: 'user@example.com',
10 userId: 'user_123', // optional
11 }}
12 lang="de"
13 onSuccess={(result) => console.log('KYC completed:', result)}
14 onError={(error) => console.error('KYC failed:', error)}
15 onCancel={() => console.log('KYC cancelled')}
16 />
17 );
18}
19
20// With authentication (JWT)
21function KYCWithAuth({ token }: { token: string }) {
22 return (
23 <FlonkKYCWidget
24 publishableKey="pk_live_..."
25 serverUrl="/api/kyc/create-session"
26 requestHeaders={{ Authorization: `Bearer ${token}` }}
27 lang="de"
28 onSuccess={(result) => console.log('KYC completed:', result)}
29 onError={(error) => console.error('KYC failed:', error)}
30 onCancel={() => console.log('KYC cancelled')}
31 />
32 );
33}
tsx

React@flonkid/kyc. Vue / Angular / vanillaFlonkKYC from @flonkid/kyc/core (React-free). No build step → one <script> tag from https://api.flonk.id/v1/public/widget-v2.js, driven through the window.KYCWidget global (full reference).

Option B: You control session creation (sessionId + embedToken)

Your frontend creates the session first (via your API), then passes credentials to the widget. More control — you decide when and how to create sessions.

Best for:

  • Custom UI before verification (e.g. confirmation screen, age check)
  • Conditional session creation (e.g. only after payment)
  • Existing backend API integration
import { FlonkKYCWidget } from '@flonkid/kyc';
function KYCVerification() {
const [session, setSession] = useState(null);
const startKYC = async () => {
// Your backend creates the session
const res = await fetch('/api/kyc/create-session', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email: user.email }),
});
const data = await res.json();
setSession(data); // { sessionId, embedToken, qrCodeUrl }
};
return (
<>
<button onClick={startKYC}>Start Verification</button>
{session && (
<FlonkKYCWidget
sessionId={session.sessionId}
embedToken={session.embedToken}
qrCodeUrl={session.qrCodeUrl}
lang="de"
onSuccess={(result) => {
setSession(null);
console.log('Verified:', result);
}}
onError={(error) => {
setSession(null);
console.error('Failed:', error);
}}
onCancel={() => setSession(null)}
/>
)}
</>
);
}
tsx

Which one to choose?

Option A (serverUrl)Option B (sessionId + embedToken)
Setup1 componentButton + state + API call + component
ControlSDK manages session lifecycleYou manage session lifecycle
Best forQuick integration, simple flowsCustom UX, conditional flows
AuthrequestHeaders propYour own fetch with auth

3. Webhooks: Handle verification results

Verify the HMAC-SHA256 signature, then process the event.

1import { FlonkKYCServer } from '@flonkid/kyc/server';
2
3const flonk = new FlonkKYCServer({
4 secretKey: process.env.FLONK_SECRET_KEY!,
5});
6
7// Express webhook handler (use raw body for signature verification)
8app.post('/webhooks/kyc',
9 express.raw({ type: 'application/json' }),
10 (req, res) => {
11 const signature = req.headers['x-signature-256'] as string;
12
13 try {
14 // Automatically detects signature format (sha256= or t=...,v1=...)
15 const event = flonk.webhooks.constructEvent(
16 req.body.toString(),
17 signature,
18 process.env.FLONK_WEBHOOK_SECRET!,
19 );
20
21 // Process the verified event
22 const verification = event.data.object;
23 console.log(`Verification ${verification.id}: ${verification.status}`);
24 console.log('Extracted data:', verification.extracted_data);
25
26 res.sendStatus(200);
27 } catch (err) {
28 console.error('Webhook verification failed:', err instanceof Error ? err.message : err);
29 res.sendStatus(400);
30 }
31 }
32);
typescript

Detailed documentation: Webhooks Integration →