Інтеграція KYC-провайдера (Sumsub, Onfido, Jumio)

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Інтеграція KYC-провайдера (Sumsub, Onfido, Jumio)
Середній
~3-5 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1306
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1218
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    920
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1147
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    610
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    885

Інтеграція KYC-провайдера (Sumsub, Onfido, Jumio)

Вибір KYC-провайдера впливає на conversion rate, вартість верифікації та регіональне покриття. Інтеграція займає 1-3 тижні залежно від провайдера та вимог — головна складність не технічні деталі API, а коректна обробка edge cases та webhook логіка.

Порівняння провайдерів

Параметр Sumsub Onfido Jumio
Покриття документів 220+ країн 195+ країн 200+ країн
Crypto compliance Нативна підтримка Обмежена Обмежена
Вартість Середня Вище середнього Вище середнього
Найкращий для Crypto/fintech WW ЄС ринок Enterprise KYB
Якість SDK Відмінна Хороша Хороша

Для крипто-проектів: Sumsub — стандартний вибір через нативну crypto compliance логіку.

Інтеграція Sumsub

Backend генерація токена

import crypto from "crypto";
import axios from "axios";

const SUMSUB_APP_TOKEN = process.env.SUMSUB_APP_TOKEN!;
const SUMSUB_SECRET_KEY = process.env.SUMSUB_SECRET_KEY!;

function createSignature(timestamp: number, method: string, url: string, body?: string): string {
  const data = timestamp + method + url + (body || "");
  return crypto.createHmac("sha256", SUMSUB_SECRET_KEY).update(data).digest("hex");
}

async function createAccessToken(userId: string, levelName: string): Promise<string> {
  const timestamp = Math.floor(Date.now() / 1000);
  const url = `/resources/accessTokens?userId=${userId}&levelName=${levelName}&ttlInSecs=1800`;
  
  const response = await axios.post(`https://api.sumsub.com${url}`, {}, {
    headers: {
      "X-App-Token": SUMSUB_APP_TOKEN,
      "X-App-Access-Sig": createSignature(timestamp, "POST", url),
      "X-App-Access-Ts": timestamp,
    },
  });
  
  return response.data.token;
}

Обробка webhook

app.post("/webhooks/sumsub", express.raw({ type: "application/json" }), async (req, res) => {
  const signature = req.headers["x-payload-digest"] as string;
  const secret = process.env.SUMSUB_WEBHOOK_SECRET!;
  
  const expected = crypto.createHmac("sha256", secret).update(req.body).digest("hex");
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
    return res.status(401).send("Invalid signature");
  }
  
  const payload = JSON.parse(req.body.toString());
  
  switch (payload.type) {
    case "applicantReviewed":
      await handleApplicantReviewed(payload);
      break;
    case "applicantPending":
      await handleApplicantPending(payload.applicantId);
      break;
    case "applicantPersonalInfoChanged":
      await handlePersonalInfoChanged(payload.applicantId);
      break;
  }
  
  res.status(200).send("OK");
});

async function handleApplicantReviewed(payload: any) {
  const { applicantId, reviewResult } = payload;
  const userId = await getUserByApplicantId(applicantId);
  
  if (reviewResult.reviewAnswer === "GREEN") {
    await approveUser(userId, applicantId);
  } else if (reviewResult.reviewAnswer === "RED") {
    const reasons = reviewResult.reviewRejectType; // масив причин
    await rejectUser(userId, reasons);
  } else if (reviewResult.reviewAnswer === "YELLOW") {
    // Потребує ручної перевірки compliance офіцером
    await flagForManualReview(userId, applicantId);
  }
}

Frontend SDK (React)

import SumsubWebSdk from "@sumsub/websdk";
import { useEffect, useRef } from "react";

interface KYCWidgetProps {
  userId: string;
  levelName: string;
  onApproved: () => void;
  onRejected: (reason: string) => void;
}

export function KYCWidget({ userId, levelName, onApproved, onRejected }: KYCWidgetProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  
  useEffect(() => {
    let sdk: any;
    
    async function initSDK() {
      const { accessToken } = await fetch("/api/kyc/token", {
        method: "POST",
        body: JSON.stringify({ userId, levelName }),
        headers: { "Content-Type": "application/json" },
      }).then(r => r.json());
      
      sdk = SumsubWebSdk.init(accessToken, () => refreshKYCToken(userId), {
        lang: "uk",
        onMessage: (type: string, payload: any) => {
          if (type === "idCheck.onApplicantStatusChanged") {
            if (payload.reviewResult?.reviewAnswer === "GREEN") onApproved();
            if (payload.reviewResult?.reviewAnswer === "RED") {
              onRejected(payload.reviewResult.reviewRejectType?.[0] || "unknown");
            }
          }
        },
      });
      
      sdk.launch(containerRef.current);
    }
    
    initSDK();
    return () => sdk?.destroy();
  }, [userId]);
  
  return <div ref={containerRef} style={{ minHeight: "600px" }} />;
}

Інтеграція Onfido (для ринку ЄС)

import { DefaultApi, Configuration } from "@onfido/api";

const onfido = new DefaultApi(new Configuration({ apiToken: ONFIDO_API_TOKEN }));

// Створення applicant
const applicant = await onfido.createApplicant({
  firstName: "Ivan",
  lastName: "Petrov",
  email: "[email protected]",
});

// SDK токен для frontend
const sdkToken = await onfido.generateSdkToken({
  applicantId: applicant.id,
  referrer: "https://yoursite.com/*",
});

// Запуск перевірки після завантаження документа
const check = await onfido.createCheck({
  applicantId: applicant.id,
  reportNames: ["document", "facial_similarity_photo", "watchlist_enhanced"],
});

Onfido використовує watchlist_enhanced для PEP/sanctions скрининга в тому ж запиті — зручно для EU compliance.

Повна інтеграція KYC провайдера (backend API + webhook + frontend SDK + admin UI) — 2-3 тижні.