Когда карта используется для покупки, эквайер присылает одноразовый код подтверждения (3DS). SIM-карта не нужна: коды приходят письмом на почту карты, мы получаем их сразу при поступлении и отдаём через API и вебхук.
GET /cards/:id/otp/latestНужно право cards.sensitive.
curl 'https://b2b.lumowallet.io/cards/8c7f1823-.../otp/latest' \
-H 'X-API-Key: YOUR_API_KEY'{
"id": "a1b2c3d4-...",
"cardId": "8c7f1823-...",
"code": "582130",
"maskedCard": "1234",
"subject": "3DS Verification",
"receivedAt": "2026-04-23T12:00:10.000Z",
"expiresAt": "2026-04-23T12:05:10.000Z",
"consumedAt": null
}cardId— id карты в нашем API, тот же, что вы передали в пути.maskedCard— окончание номера карты из письма эквайера.expiresAt—receivedAt+ 5 минут.
Эндпоинт отдаёт самый свежий код, срок которого ещё не истёк. Если такого кода нет, ответ — 200 с пустым телом, а не JSON null: проверяйте длину тела перед разбором.
Событие card.otp_received приходит на ваш webhookUrl сразу после того, как письмо с кодом дошло до нас:
{
"event": "card.otp_received",
"cardId": "8c7f1823-...",
"code": "582130",
"maskedCard": "1234",
"receivedAt": "2026-04-23T12:00:10.000Z",
"expiresAt": "2026-04-23T12:05:10.000Z",
"createdAt": "2026-04-23T12:00:11.000Z"
}Вебхук приходит не на каждое письмо:
- если письмо дошло позже чем через 15 минут после отправки, код сохраняется, но вебхук не отправляется — такой код уже недействителен;
- тот же код по той же карте в течение 8 минут повторно не отправляется.
Подписываться на событие отдельно не нужно: все события компании приходят на один webhookUrl.
Опрашивайте эндпоинт каждые 3–5 секунд после того, как пользователь начал 3DS-проверку, пока не придёт код с подходящим receivedAt. Код действует 5 минут (expiresAt).
async function getLatestOtp(cardId) {
const res = await fetch(
`https://b2b.lumowallet.io/cards/${cardId}/otp/latest`,
{ headers: { 'X-API-Key': process.env.LUMO_API_KEY } },
);
const text = await res.text();
return text ? JSON.parse(text) : null; // пустое тело — кода нет
}cardsTestMode = true всегда возвращает фиксированный код 843903 со сроком 2 минуты от текущего момента — удобно для автотестов.