FACEKYC API — Creación de sesiones

Endpoint para abrir una sesión KYC/KYB y obtener URLs de inicio del flujo.

POST https://api.facekyc.com/v1/orderrequest.php Auth: Bearer / ApiKey / X-API-Key Content-Type: application/json

Endpoint para abrir una sesión KYC/KYB y obtener URLs de inicio del flujo.

API para Cajeros y Control de Accesos

Para los cajeros y control de accesos, utiliza la siguiente API:

curl -X POST "https://api.facekyc.com/v1/orderrequest.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "atmId": "ES_ONLINE",
        "reference": "order_123"
      }'
// JavaScript (fetch)
const res = await fetch("https://api.facekyc.com/v1/orderrequest.php", {
  method: "POST",
  headers: {
    "Authorization": "Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    atmId: "ES_ONLINE",
    reference: "order_123"
  })
});
const data = await res.json();
console.log("session:", data.session_id, "pwa:", data.pwa_url);
<?php
// PHP with GuzzleHttp
require __DIR__."/vendor/autoload.php";
use GuzzleHttp\Client;

$client = new Client(["base_uri" => "https://api.facekyc.com"]);

try {
  $r = $client->post("/v1/orderrequest.php", [
    "headers" => ["Authorization" => "Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"],
    "json"    => ["atmId" => "ES_ONLINE", "reference" => "order_123"],
    "http_errors" => false
  ]);
  $status = $r->getStatusCode();
  $body   = json_decode((string)$r->getBody(), true);
  var_dump($status, $body);
} catch (\Throwable $e) {
  echo "Error: ".$e->getMessage();
}

Respuesta de ejemplo

{
  "ok": true,
  "session_id": "6a6b0d78e6c84e8490b3f1c2f6a1b2cd",
  "status": "pending",
  "atm_id": "ES_ONLINE",
  "atm_url": "https://api.facekyc.com/atm/start_session.php?session=...&atmId=ES_ONLINE",
  "pwa_url": "https://api.facekyc.com/pwa/?session=...&atmId=ES_ONLINE",
  "service": { "id": 12, "name": "CONTROL DE ACCESOS", "price": 1.0, "cost_units": 1 },
  "contract": { "contrato_id": 345, "empresa_id": 78 },
  "credits": { "debited": 1, "remaining": 149 },
  "reference": "order_123",
  "filled_meta": true
}

Body (JSON)

Campo Tipo Req. Descripción
atmIdstringcond. Canal/ATM (A-Z0-9_-). Si lo omites y existe ATM_DEFAULT en tu configuración, se usará ese.
referencestringopcional Referencia libre (order_id, user_id, etc.).

Autenticación

  • Authorization: Bearer <API_KEY>
  • Authorization: ApiKey <API_KEY>
  • X-API-Key: <API_KEY>

La API key es alfanumérica (con guiones) de longitud ≥36. Guarda las claves solo en backend.

Errores

HTTPerrorComentario
201(ok)Sesión creada, créditos descontados.
400INVALID_BODYJSON mal formado.
400ATM_NOT_PROVIDEDFalta atmId y no hay ATM_DEFAULT.
401UNAUTHORIZEDFalta API key o es inválida.
402INSUFFICIENT_CREDITSSaldo insuficiente (incluye required/available).
403FORBIDDENServicio/contrato suspendido.
403SERVICE_DISABLEDServicio inactivo.
404SERVICE_NOT_FOUNDServicio del contrato no existe.
404COMPANY_NOT_FOUNDEmpresa no encontrada.
405METHOD_NOT_ALLOWEDDebe ser POST.
500SERVER_ERRORError interno (mensaje informativo).
500CONFIG_NOT_FOUNDNo se pudo cargar config.

API para KYC

POST https://api.facekyc.com/v1/orderkyc.php Auth: Bearer / ApiKey / X-API-Key Content-Type: application/json

Para KYC, utiliza la siguiente API:

curl -X POST "https://api.facekyc.com/v1/orderkyc.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "user_id": "user_123",
        "document_type": "DNI",
        "document_number": "12345678Z"
      }'

Probar con Postman

Puedes probar ambos endpoints con Postman. Crea una petición POST y usa Bearer <API_KEY>:

POST https://api.facekyc.com/v1/orderrequest.php (Cajeros / Control) POST https://api.facekyc.com/v1/orderkyc.php (KYC)

1) Cajeros / Control de Accesos

  • Auth: Bearer <API_KEY>
  • Headers: Content-Type: application/json
  • Body (JSON): {"atmId":"ES_ONLINE","reference":"order_123"}
curl -X POST "https://api.facekyc.com/v1/orderrequest.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "atmId": "ES_ONLINE",
        "reference": "order_123"
      }'

2) KYC

  • Auth: Bearer <API_KEY>
  • Headers: Content-Type: application/json
  • Body (JSON): {"user_id":"user_123","document_type":"DNI","document_number":"12345678Z"}
curl -X POST "https://api.facekyc.com/v1/orderkyc.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "user_id": "user_123",
        "document_type": "DNI",
        "document_number": "12345678Z"
      }'

Abrir Postman

Probar con Insomnia

En Insomnia, crea una petición POST y usa Auth → Bearer Token con tu clave:

POST https://api.facekyc.com/v1/orderrequest.php (Cajeros / Control) POST https://api.facekyc.com/v1/orderkyc.php (KYC)

1) Cajeros / Control de Accesos

  • Auth: Bearer <API_KEY> (tab “Auth” → “Bearer Token”)
  • Headers: Content-Type: application/json
  • Body (JSON): {"atmId":"ES_ONLINE","reference":"order_123"}
curl -X POST "https://api.facekyc.com/v1/orderrequest.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "atmId": "ES_ONLINE",
        "reference": "order_123"
      }'

2) KYC

  • Auth: Bearer <API_KEY>
  • Headers: Content-Type: application/json
  • Body (JSON): {"user_id":"user_123","document_type":"DNI","document_number":"12345678Z"}
curl -X POST "https://api.facekyc.com/v1/orderkyc.php" \
  -H "Authorization: Bearer fk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
        "user_id": "user_123",
        "document_type": "DNI",
        "document_number": "12345678Z"
      }'

Abrir Insomnia

📱 Integración en Aplicaciones Nativas (iOS/Android)

Si cargas el formulario KYC dentro de una aplicación nativa mediante WebView, debes configurar la reproducción de video inline. Sin esta configuración, el video de la cámara se abrirá en pantalla completa y los overlays (recuadro, botones, cuenta atrás) desaparecerán.

Express:
allowsInlineMediaPlayback={true}
mediaPlaybackRequiresUserAction={false}

⚠️ Importante: Estas configuraciones deben aplicarse antes de crear el WebView. Si no se configuran, la experiencia del usuario será incorrecta en iOS.

iOS - Swift (WKWebView)

Configura el WKWebViewConfiguration antes de crear el WebView:

import WebKit

// 1. Crear configuración ANTES del WebView
let config = WKWebViewConfiguration()
config.allowsInlineMediaPlayback = true
config.mediaTypesRequiringUserActionForPlayback = []
config.allowsPictureInPictureMediaPlayback = false

// 2. Crear WebView con la configuración
let webView = WKWebView(frame: .zero, configuration: config)

// 3. Cargar la URL del KYC
let url = URL(string: "https://api.facekyc.com/pwa/kyc_form.php?session=xxx&atmId=xxx")!
webView.load(URLRequest(url: url))

iOS - React Native (WebView)

Usa las props necesarias en el componente WebView:

import { WebView } from 'react-native-webview';

<WebView
  source={{ 
    uri: 'https://api.facekyc.com/pwa/kyc_form.php?session=xxx&atmId=xxx' 
  }}
  allowsInlineMediaPlayback={true}
  mediaPlaybackRequiresUserAction={false}
  allowsFullscreenVideo={false}
  javaScriptEnabled={true}
  domStorageEnabled={true}
  onPermissionRequest={(request) => {
    if (request.resources.includes('camera')) {
      request.grant();
    }
  }}
/>

Android - Kotlin/Java (WebView)

Configura los WebSettings y el WebChromeClient:

import android.webkit.WebView
import android.webkit.WebSettings
import android.webkit.WebChromeClient
import android.webkit.PermissionRequest

// Configurar WebSettings
val webView = findViewById<WebView>(R.id.webview)
val webSettings = webView.settings

webSettings.javaScriptEnabled = true
webSettings.domStorageEnabled = true
webSettings.mediaPlaybackRequiresUserGesture = false

// Gestionar permisos de cámara
webView.webChromeClient = object : WebChromeClient() {
    override fun onPermissionRequest(request: PermissionRequest) {
        request.grant(request.resources)
    }
}

// Cargar URL
webView.loadUrl("https://api.facekyc.com/pwa/kyc_form.php?session=xxx&atmId=xxx")

Configuraciones Requeridas

Plataforma Propiedad Descripción
iOS allowsInlineMediaPlayback Permite que el video se reproduzca inline en lugar de pantalla completa
iOS mediaTypesRequiringUserActionForPlayback Array vacío permite reproducción automática sin tocar la pantalla
iOS allowsPictureInPictureMediaPlayback Desactiva picture-in-picture para evitar conflictos
Android mediaPlaybackRequiresUserGesture False permite que la cámara inicie automáticamente
Android WebChromeClient.onPermissionRequest Gestiona permisos de cámara y micrófono

Permisos Requeridos

iOS - Info.plist:

<key>NSCameraUsageDescription</key>
<string>Necesitamos acceso a la cámara para verificación de identidad KYC</string>

<key>NSMicrophoneUsageDescription</key>
<string>Necesitamos acceso al micrófono para grabación de vídeo KYC</string>

Android - AndroidManifest.xml:

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-feature android:name="android.hardware.camera.autofocus" />
💡 Consejo: Prueba la integración con un dispositivo físico, no con simuladores. Los simuladores de iOS no tienen cámara real y pueden comportarse de forma diferente.

Buenas prácticas

  • Idempotencia: Reutiliza tu reference para evitar duplicados en reintentos.
  • Seguridad: Guarda la API key solo en backend (nunca en apps cliente).
  • Backoff: Ante 402/403/5xx reintenta con espera exponencial.