Verify

SDK как у Sumsub: ключ, запуск, события

Схема такая же по смыслу: ваш сервер выдает короткий accessToken, приложение передает его в SDK, SDK открывает проверку документа и лица, а результат возвращается в callback и webhook.

Без выдумок

Сейчас SDK отдаем как готовые файлы Swift и Kotlin: скачали, положили в проект, вызвали `SNSMobileSDK`. CocoaPods, SPM и Maven можно публиковать отдельно после регистрации пакетов.

Совместимость

Публичные серверные пути и подпись сделаны под поддержанные Sumsub-compatible методы. Секретный ключ остается только на вашем сервере.

1. Сервер

Создайте accessToken перед запуском SDK

Мобильное приложение не хранит секрет. Оно спрашивает ваш бэкенд, а бэкенд подписывает запрос и получает временный ключ проверки.

import crypto from "node:crypto";

async function signedPost(path, payload) {
  const body = JSON.stringify(payload);
  const ts = Math.floor(Date.now() / 1000).toString();
  const sig = crypto
    .createHmac("sha256", SUMSUB_COMPAT_SECRET)
    .update(ts + "POST" + path + body)
    .digest("hex");

  const response = await fetch("https://verify.umbrellax.io" + path, {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-App-Token": SUMSUB_COMPAT_TOKEN,
      "X-App-Access-Ts": ts,
      "X-App-Access-Sig": sig
    },
    body
  });
  return response.json();
}

await signedPost("/resources/applicants", {
  externalUserId: "user_123",
  email: "user@example.com",
  fixedInfo: {
    firstName: "Ivan",
    lastName: "Ivanov",
    dob: "1990-01-01",
    country: "KZ",
    idDocType: "PASSPORT"
  }
});

const { token } = await signedPost("/resources/accessTokens/sdk", {
  userId: "user_123",
  ttlInSecs: 600
});
2. iOS Swift

Один файл в проект

Добавьте `UmbrellaXVerifySDK.swift`, разрешения камеры и микрофона, затем запускайте проверку из вашего экрана.

let sdk = SNSMobileSDK(accessToken: accessToken)
  .withLocale(Locale(identifier: "ru"))
  .withConf(SNSInitConfig(email: "user@example.com"))
  .withAutoCloseOnApprove(0)
  .tokenExpirationHandler { finish in
    finish(fetchFreshAccessToken())
  }

guard sdk.isReady else {
  print(sdk.verboseStatus)
  return
}

sdk.onStatusDidChange = { status in print(status) }
sdk.onComplete = { result in
  print(result.status, result.verificationId ?? "")
  print(result.faceSimilarity ?? 0, result.reasons)
  result.evidence.forEach { item in
    print(item.id, item.status, item.value)
  }
}
sdk.onError = { error in print(error) }
sdk.launch(from: self)

Info.plist:

<key>NSCameraUsageDescription</key>
<string>Камера нужна для съемки документа и живого лица</string>
<key>NSMicrophoneUsageDescription</key>
<string>Микрофон нужен для защищенной живой проверки</string>
3. Android Kotlin

Один файл в приложение

Добавьте `UmbrellaXVerifySDK.kt`, объявите Activity и разрешения, затем вызовите builder из вашей Activity.

val tokenExpirationHandler = object : TokenExpirationHandler {
  override fun onTokenExpired(): String? {
    return fetchFreshAccessToken()
  }
}

val snsSdk = SNSMobileSDK.Builder(this)
  .withAccessToken(accessToken, onTokenExpiration = tokenExpirationHandler)
  .withLocale(Locale("ru"))
  .withConf(SNSInitConfig(email = "user@example.com"))
  .withAutoCloseOnApprove(0)
  .withHandlers(
    onStatusDidChange = { status -> println(status) },
    onComplete = { result ->
      println(result.status + " " + result.verificationId)
      println("${result.faceSimilarity} " + result.reasons.joinToString(","))
      result.evidence.forEach { item ->
        println("${item.id} ${item.status} ${item.value}")
      }
    },
    onError = { error -> println(error) }
  )
  .build()

snsSdk.launch()

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-permission android:name="android.permission.NFC" />

<activity
  android:name="io.umbrellax.verify.UmbrellaXVerifyActivity"
  android:screenOrientation="portrait"
  android:exported="false" />
4. Web

Виджет для сайта

Для сайтов и личных кабинетов: вставьте скрипт, передайте accessToken, получите результат.

<script src="https://verify.umbrellax.io/sdk/faces.js" defer></script>
<div id="faces"></div>
<script>
  Faces.mount("#faces", {
    token: "faces_sdk_live_...",        // accessToken с вашего сервера
    locale: "ru",
    onStatusDidChange: (status) => console.log(status),
    onComplete: (result) => {            // accepted | retry | rejected
      console.log(result.status, result.verificationId);
      console.log(result.faceSimilarity, result.reasons);
      console.table(result.evidence);     // документ, лицо, живая проверка
    }
  });
</script>
REST API

Совместимые серверные методы

Можно подключаться через REST без SDK и проверять статус по заявке.

POST https://verify.umbrellax.io/resources/applicants
POST https://verify.umbrellax.io/resources/accessTokens/sdk
GET  https://verify.umbrellax.io/resources/applicants/{id}/status
POST https://verify.umbrellax.io/resources/applicants/{id}/info/idDoc

# Заголовки такие же:
# X-App-Token, X-App-Access-Ts, X-App-Access-Sig

Что возвращает SDK

`onStatusDidChange` показывает готовность потока. `onComplete` возвращает `accepted`, `retry` или `rejected`, номер проверки, риск, причины решения, процент совпадения лица и краткий журнал доказательств.

Что делает сервер

Сервер хранит секрет, выпускает короткие токены, принимает документы, пишет журнал доказательств и отправляет итог через webhook.

Получить ключ в кабинетеSwiftKotlinWeb JS