GH GambleHub

Повторы и backoff в платежах

Повторы и backoff в платежах

1) Зачем нужны повторы

Конверсия: мягкие отказы (timeouts, 3DS-ошибки, сетевые сбои) часто восстанавливаются при повторе: +2–7 п.п. к Auth Rate.
Устойчивость: локальные сбои PSP/ACS/банка сглаживаются ретраями с маршрутами-альтернативами.
Опыт игрока: корректно выстроенные повторы скрывают «шум» инфраструктуры без двойных списаний.


2) Базовые принципы

1. Идемпотентность на уровне «payment intent» (PI): одна операция = один `idempotency_key`; любое повторное обращение не меняет денежное состояние.

2. Разделение ошибок:
  • Hard decline (напр. `Do not honor` при жесткой политике эмитента, `Insufficient funds`) → обычно не ретраим сразу.
  • Soft decline/технические (timeout, `Issuer unavailable`, `Try again`) → разрешенный ретрай.
  • 3. Backoff + ограничение попыток: экспоненциально увеличиваем задержку, добавляем джиттер и не превышаем лимиты (обычно 2–3 попытки).
  • 4. Маршрутизация в связке: ретрай — это не только «повтор у того же PSP», а и смена PSP/MID/3DS-режима/метода.
  • 5. Наблюдаемость: каждый hop фиксируется в Route Journal (PSP, reason, latency, 3DS-режим, fee, результат).

3) Классификация ошибок для решения о ретрае

КлассПримерыРекомендация
Сетевые/техническиеtimeout, 5xx, `Issuer/ACS unavailable`, webhook delayРетрай с backoff; можно сменить PSP/MID/3DS
Soft decline (реверсивные)`Pickup card (soft)`, `Do not honor` (часть кейсов), `Processing error`Ретрай 1–2 раза, возможно с изменением 3DS/маршрута
Hard decline (финальные)`Insufficient funds`, `Invalid card`, `Expired card`, `Restricted card`, `Do not honor` (жесткий)Не ретраим (либо предлагаем альтернативный метод)
3DS-ошибки`Authentication unavailable`, timeout ACS, `Soft decline` после frictionlessРетрай с challenge или через альтернативный метод (open banking)
Риск/комплаенссанкции/PEP, RG-блок, лимиты velocityНе ретраим; бизнес-логика отказа
💡 Примечание: точная матрица зависит от схем/PSP. Храните whitelist/blacklist reason-кодов в конфиге оркестратора.

4) Backoff-стратегии (практика)

4.1 Экспоненциальный backoff с джиттером (рекомендуемый)

База: `delay_n = min(base 2^n, max_delay)`

Джиттер: `delay = rand(0, delay_n)` — снижает «стампеды», когда много запросов повторяются одновременно.
Типовые параметры: `base=200–500 мс`, `max_delay=5–10 с`, `n≤2–3`.

4.2 Линейный backoff

Прост, но хуже при «волнениях» в сети. Уступает экспоненциальному + джиттер.

4.3 Политика тайм-аутов

Client timeout (ваш) ≤ PSP SLA (например, 3–5 с), иначе растет риск дубликатов/зависаний.
Отдельно задавайте время ожидания webhook/confirm: если подтверждение не пришло → компенсирующая сверка (ledger/PSP).


5) Идемпотентность и защита от дублей

Payment Intent (PI) хранит статус, сумму, метод, `idempotency_key`, историю маршрутов.
Каждый hop и retry используют один и тот же ключ.
Компенсирующие транзакции: при рассинхроне (approve в PSP, а у вас timeout) — «reconcile-pull» + корректировка леджера.
Исключайте повторную авторизацию при повторной доставке webhook: проверяйте `transaction_id`/`PSP reference` на уникальность.


6) 3DS/SCA и повторы

Soft decline после frictionless → ретрай с challenge.
ACS timeout/unavailable → экспоненциальный backoff, затем альтернативный канал (open banking/APM) или другой PSP.
При массовой деградации ACS — circuit-breaker, рост `challenge rate`, временные лимиты по суммам.


7) Повторы для APM/open banking

Open banking/instant rails (SEPA Instant/FPS/Pix/UPI):
  • Ретраи ограничены: проверяйте идемпотентность на стороне провайдера и статусы в отложенных webhook’ах.
  • При неопределенном статусе — polling с backoff и строгие сверки.
  • Ваучеры/наличные: ретраи не применяются как к «онлайн-транзакции», но действует контроль срока оплаты и «status refresh».

8) Payouts (выводы): повторы и очереди

Технический сбой банка/PSP → queued payouts с backoff-дреном.
KYT/velocity fail → не ретраим, перевод в ручную проверку.
Приоритизация очереди: VIP/мелкие суммы/давность заявки; дедлайны SLA и авто-эскалации.
Альтернативные рельсы (RTP/FPS/SEPA Instant/Pix) на втором шаге ретрая.


9) Circuit-breaker и ретраи

Локальный (на PSP/MID/BIN): при всплеске ошибок → останавливаем ретраи на этом маршруте, переключаемся на альтернативный.
Глобальный (на метод/регион): системная деградация → отключаем метод, предлагаем APM/open banking.
Half-open: возвращаем часть трафика (1–5%) для проверки восстановления перед полным возвратом.


10) Псевдокод стратегии ретраев

python def pay_with_retries(pi):
ensure_idempotency(pi.key)
if not compliance_pass(pi): return REJECT

routes = rank_candidates(pi) # по вероятности approve, fee, health attempts = 0 for route in routes:
policy3ds = select_3ds(pi, route)
res = call_psp(route, pi, policy3ds, pi.key, timeout=3.0)
log_attempt(pi, route, res)

if res.approved: return APPROVED

if is_soft_decline(res) or is_transient_error(res):
while attempts < MAX_ATTEMPTS and not breaker_open(route):
delay = backoff_with_jitter(base=0.3, attempt=attempts, cap=8.0)
sleep(delay)
policy3ds = maybe_toggle_3ds(policy3ds, res)
res = call_psp(route, pi, policy3ds, pi.key, timeout=3.0)
log_attempt(pi, route, res)
attempts += 1 if res.approved: return APPROVED if is_hard_decline(res): break перейти к следующему маршруту (PSP-B/APM/open banking)
return DECLINED

11) KPI и целевые ориентиры

Incremental Approvals from Retries: +2–7 п.п. к базовой конверсии.
Avg Retry Attempts per Approved Tx: 1.2–1.5 (держите ниже 1.7).
Retry Success Rate (soft/tech): ≥ 25–40%.
Duplicate Rate: 0 при корректной идемпотентности.
P95 Latency (с учетом ретраев): < 7 с до финального ответа.
Payout SLA (instant share): ≥ 70% легких чеков, просрочки < целевого порога.


12) Плейбуки инцидентов

A. Массовые timeouts на PSP-A

1. Открыть локальный breaker для PSP-A.
2. Перераспределить ретраи на PSP-B/APM.
3. Экспоненциальный backoff с джиттером, лимит 2–3 попытки.
4. Канарейка half-open через 10–15 мин.

B. Деградация ACS/3DS

1. Детект по росту `soft decline`, timeouts.
2. Повысить challenge rate; часть трафика → open banking.
3. Отложить тяжелые чеки, включить лимиты velocity.

C. Задержки по payouts

1. Перевод в очередь, приоритизация VIP/малых сумм.
2. Рераут на альтернативные rails (RTP/FPS/SEPA Instant/Pix).
3. Коммуникация игрокам + авто-эскалации.


13) Наблюдаемость и данные

Route Journal: PSP/MID, BIN/issuer, reason, latency, 3DS-режим, retry chain, итог, fee.
Дашборды: Auth Rate (по банкам), Retry Success, Avg Attempts, Decline Mix, p95 latency, Payout Queue Depth.
Алерты: spikes по reason-кодам, рост попыток/latency, переполнение очередей выводов.


14) Чек-листы внедрения

Архитектура/данные

  • Payment Intent + `idempotency_key` на все hops.
  • Конфиг-матрица reason-кодов: retryable vs non-retryable.
  • Подписанные webhooks, дедупликация по PSP reference.

Backoff/правила

  • Экспоненциальный backoff с джиттером; лимит попыток и время окна.
  • Smart retry: смена 3DS/MID/PSP/метода; различие для карт vs APM/open banking.
  • Circuit-breakers (локальные/глобальные), half-open-канарейки.

Леджер/сверки

  • Компенсирующие транзакции при «подвешенных» статусах.
  • T+0/T+1 сверки: PSP ↔ банк ↔ денежный леджер.
  • Политика тайм-аутов и SLA на confirm/webhook.

Операции/комплаенс

  • RG/санкции/PEP/возраст — до ретраев.
  • KYT/velocity на payouts; правила ручного ревью.
  • Runbooks и RACI для инцидентов/эскалаций.

15) Экономика и риск

Считайте effective rate с учетом 3DS-фии, FX, чарджбек-стоимости, ретрай-оверхеда.
Жестко лимитируйте ретраи по high-risk сегментам, чтобы не разгонять chargeback exposure и резервы.


16) Итог

Повторы работают, когда они управляемы: идемпотентность, ясная матрица reason-кодов, экспоненциальный backoff с джиттером, ограничение попыток и связка с маршрутизацией (смена PSP/3DS/метода). Добавьте circuit-breaker, очереди для payouts и сильные сверки — и вы стабильно поднимете конверсию, не создавая дублей и кассовых «дырок».

Contact

Свяжитесь с нами

Обращайтесь по любым вопросам или за поддержкой.Мы всегда готовы помочь!

Начать интеграцию

Email — обязателен. Telegram или WhatsApp — по желанию.

Ваше имя необязательно
Email необязательно
Тема необязательно
Сообщение необязательно
Telegram необязательно
@
Если укажете Telegram — мы ответим и там, в дополнение к Email.
WhatsApp необязательно
Формат: +код страны и номер (например, +380XXXXXXXXX).

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