Required Claims
{ "api_key": "ekyc_xxx", "phone": "registered_vendor_phone", "ref_no": "your_unique_reference", "iat": now, "exp": now + 300 }
Main Flow

1. Vendor panel se `API Key`, `JWT Secret`, aur registered vendor `phone` lo.

2. Apni side par HS256 JWT generate karo.

3. `POST /ext-api/v1/sessions/create` call karo.

4. Response se `session_token` lo.

5. Applicant ko open karao: https://fitfuel.fun/kyc/start?token=<session_token>

Endpoints
POST /ext-api/v1/sessions/create GET /ext-api/v1/sessions GET /ext-api/v1/sessions/{token} GET /ext-api/v1/sessions/{token}/recording GET /ext-api/v1/sessions/{token}/recording/download GET /ext-api/v1/sessions/{token}/logs
Vendor Callback

Vendor panel me har API key ke against HTTPS callback URL save karo. Session `approved`, `rejected`, ya `ended` hote hi callback fire hoga.

Callback payload me `status`, `notes`, `latitude`, `longitude`, `location_label`, `recording_access_url`, `recording_api_url`, `snapshot_urls`, `merchant_code`, aur `session_token` jayega.

Security headers:

X-EKYC-Event: session.completed X-EKYC-Key: <api_key> X-EKYC-Timestamp: <unix_timestamp> X-EKYC-Signature: sha256=<hash_hmac_sha256(timestamp + '.' + raw_json_body, jwt_secret)>
Sample PHP

Ready sample file path: laravel-ekyc/documentation/vendor_api_sample.php

<?php
$apiKey = 'ekyc_xxx';
$jwtSecret = 'your_secret_here';
$vendorPhone = '6666666666';
$refNo = 'REF' . time();

$header = ['alg' => 'HS256', 'typ' => 'JWT'];
$payload = [
    'api_key' => $apiKey,
    'phone' => $vendorPhone,
    'ref_no' => $refNo,
    'iat' => time(),
    'exp' => time() + 300,
];

function b64($data) {
    return rtrim(strtr(base64_encode(json_encode($data)), '+/', '-_'), '=');
}

$unsigned = b64($header) . '.' . b64($payload);
$signature = hash_hmac('sha256', $unsigned, $jwtSecret, true);
$jwt = $unsigned . '.' . rtrim(strtr(base64_encode($signature), '+/', '-_'), '=');

$ch = curl_init('https://fitfuel.fun/ext-api/v1/sessions/create');
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        'Authorization: Bearer ' . $jwt,
        'Accept: application/json',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS => json_encode(['merchant_code' => 'MEXR123456']),
]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;