Верификация номера по звонку в Node.js: интеграция reverse flash call за 15 минут
Интеграция
14 июля 2026 · 4 мин

Верификация номера по звонку (reverse flash call) в Node.js

Reverse flash call — самый дешёвый способ подтвердить номер: пользователь сам звонит на выданный номер, а вы узнаёте результат по API. Кода вводить не нужно. Разберём интеграцию на Node.js от первого запроса до готового эндпоинта.

Обратный flash-call (reverse flash call) — метод верификации, при котором пользователь совершает короткий звонок на номер, который вы ему показываете. Звонок сбрасывается, деньги за него не списываются, а подтверждение происходит автоматически по Caller ID. Пользователю не нужно ждать SMS, читать и вводить код — достаточно нажать «позвонить».

Это метод по умолчанию в Verificahub: дешевле SMS, устойчив к блокировкам операторов и не зависит от того, установлен ли у пользователя мессенджер. Ниже — практическая интеграция.

Что понадобится

  • Аккаунт в личном кабинете и пара ключей api_key / api_secret.
  • Положительный баланс (оплата — только за успешное подтверждение).
  • Node.js 18+ (в нём есть встроенный fetch).
  • Номера пользователей в формате E.164: российские +7….

Внешний API — server-to-server. api_secret — это пароль: не встраивайте его в браузер или мобильное приложение, все вызовы делайте с бэкенда.

Шаг 1. Инициируем проверку

Отправляем POST /v1/verify с номером и методом reverse_flash_call. Авторизация — HTTP Basic (api_key как логин, api_secret как пароль).

bash
curl -X POST https://api.verificahub.ru/v1/verify \
  -u "vh_live_…:vh_sec_…" \
  -H "Content-Type: application/json" \
  -d '{ "phone_number": "+79991234567", "method": "reverse_flash_call" }'

В ответ приходит 201 Created. Главное поле — number_to_call: именно этот номер нужно показать пользователю. Сам код при этом методе не передаётся и не вводится.

json
{
  "method": "reverse_flash_call",
  "request_id": "8f2c…",
  "phone_number": "+79991234567",
  "status": "sent",
  "cost": { "amount": 3.50, "currency": "RUB" },
  "expires_at": "2026-07-14T09:35:00Z",
  "number_to_call": "+74995551234"
}

Шаг 2. Показываем номер пользователю

На фронтенде выводим number_to_call и просим совершить звонок — кнопкой tel: это делается в один тап. Пока пользователь звонит, сессия живёт expiry_seconds секунд (по умолчанию 300, диапазон 1–600).

js
const AUTH =
  'Basic ' + Buffer.from(`${process.env.VH_KEY}:${process.env.VH_SECRET}`).toString('base64')

async function startVerification(phone) {
  const res = await fetch('https://api.verificahub.ru/v1/verify', {
    method: 'POST',
    headers: { Authorization: AUTH, 'Content-Type': 'application/json' },
    body: JSON.stringify({ phone_number: phone, method: 'reverse_flash_call' }),
  })
  if (!res.ok) throw new Error('verify failed: ' + res.status)
  return res.json() // { request_id, number_to_call, expires_at, ... }
}

Шаг 3. Узнаём результат: polling или webhook

После звонка сессия автоматически переходит в статус verified. Узнать это можно двумя способами.

Опрос статуса — периодически запрашивайте GET /v1/verify/{request_id}, пока status не станет verified, expired или failed:

js
async function getStatus(requestId) {
  const res = await fetch(`https://api.verificahub.ru/v1/verify/${requestId}`, {
    headers: { Authorization: AUTH },
  })
  return res.json() // { status: 'sent' | 'verified' | 'expired' | 'failed', ... }
}

Webhook — если задать URL вебхука в кабинете, Verificahub сам пришлёт POST с событием verification.verified при смене статуса. Это надёжнее и экономичнее опроса; запросы подписаны HMAC-SHA256 (заголовок X-Verificahub-Signature) — проверяйте подпись. Подробности — в документации.

Полный пример на Node.js (Express)

Два эндпоинта: /verify/start инициирует проверку и отдаёт номер фронтенду, /verify/status возвращает текущий статус для опроса.

js
import express from 'express'

const app = express()
app.use(express.json())

const API = 'https://api.verificahub.ru/v1'
const AUTH =
  'Basic ' + Buffer.from(`${process.env.VH_KEY}:${process.env.VH_SECRET}`).toString('base64')

app.post('/verify/start', async (req, res) => {
  const r = await fetch(`${API}/verify`, {
    method: 'POST',
    headers: { Authorization: AUTH, 'Content-Type': 'application/json' },
    body: JSON.stringify({ phone_number: req.body.phone, method: 'reverse_flash_call' }),
  })
  const data = await r.json()
  if (!r.ok) return res.status(r.status).json(data)
  // отдаём фронтенду только номер и id — cost/номер SIM пользователю не нужны
  res.json({ request_id: data.request_id, number_to_call: data.number_to_call, expires_at: data.expires_at })
})

app.get('/verify/status/:id', async (req, res) => {
  const r = await fetch(`${API}/verify/${req.params.id}`, { headers: { Authorization: AUTH } })
  const data = await r.json()
  res.status(r.status).json({ status: data.status })
})

app.listen(3000)

Никогда не проксируйте api_secret на клиент. Фронтенд общается только с вашим бэкендом, а бэкенд — с Verificahub.

Обработка ошибок

Ошибки приходят в формате RFC-7807 со стабильным полем error_code — ветвитесь по нему, а не по тексту detail. При неудачной инициации деньги не списываются.

error_codeHTTPЧто делать
validation_error400Проверьте формат номера (E.164, +7…).
region_not_supported400v1 работает только с номерами РФ +7.
insufficient_balance402Пополните баланс в кабинете.
no_gateway_available402Нет свободного канала — повторите с backoff или предложите другой метод.
rate_limit_exceeded429Учтите Retry-After и снизьте частоту запросов.
not_found404Неверный request_id или он не принадлежит вашему аккаунту.

Сколько это стоит

Модель оплаты — за результат: списание происходит только при успешном подтверждении, а неудачная инициация бесплатна. Обратный flash-call — самый дешёвый метод, от 0,25 ₽ за подтверждение. Актуальные цены и сравнение методов — на странице тарифов.

Что дальше

Если часть пользователей не может позвонить (например, из-за корпоративной АТС), добавьте запасной канал — Telegram OTP: код приходит в мессенджер, а подтверждается через POST /v1/verify/check. Как устроен каскад «звонок → Telegram → SMS», разбираем в отдельном гайде.

Частые вопросы

Нужно ли пользователю вводить код при reverse flash call?

Нет. Пользователь просто звонит на номер number_to_call, звонок сбрасывается, и сессия подтверждается по Caller ID автоматически. Метод /v1/verify/check для этого метода не нужен.

Сколько времени действует запрос на проверку?

По умолчанию 300 секунд. Можно задать своё значение полем expiry_seconds в диапазоне 1–600 при вызове POST /v1/verify.

Что будет, если пользователь не позвонит?

По истечении TTL сессия перейдёт в статус expired. Списания не будет — вы платите только за успешное подтверждение.

Можно ли обойтись без опроса статуса?

Да. Настройте webhook в кабинете — Verificahub пришлёт подписанное HMAC событие verification.verified при смене статуса, и опрашивать API не придётся.

Запуск за 24 часа

Подключите верификацию по звонку

Один API, оплата за результат, обратный flash-call от 0,25 ₽. Поможем внедрить за один день.