YooBankDocumentação pública

Webhooks PAY-IN

Webhook é opcional. Zero-code YooCheckout não precisa dele. Merchants API (Modelos B/C) usam-no para notificação push.

MERCHANT_DATABASE_SCHEMA_CHANGE_REQUIRED=no
WEBHOOK_EVENT_TABLE_REQUIRED=no

A YooBank não exige uma tabela específica no merchant. Logs não são idempotência financeira.

Entrega

O merchant deve processar de forma idempotente.

IdentidadePapel
intent_uuidIdempotência financeira recomendada
event_uuidIdentidade do evento (auditoria / dedupe opcional)
delivery_uuidIdentidade da tentativa de entrega; estável nos retries da mesma entrega

event_uuid e delivery_uuid não são intercambiáveis.

Eventos

Headers

X-YooBank-Event-Id
X-YooBank-Delivery-Id
X-YooBank-Event-Type
X-YooBank-Timestamp
X-YooBank-Signature

X-YooBank-Event-Id = event_uuid no JSON.

Assinatura (contrato congelado)

Algoritmo: HMAC-SHA256 (hex).

Entrada exacta:

timestamp + "\n" + event_uuid + "\n" + delivery_uuid + "\n" + event_type + "\n" + raw_body

O timestamp é obrigatório, sintaxe ATOM, e entra tal qual no HMAC.

WEBHOOK_TIMESTAMP_FRESHNESS_WINDOW_ENFORCED=no

A YooBank não aplica janela ±5 minutos. Uma verificação extra de replay no receiver é hardening do merchant, não requisito canónico YooBank.

Verifique o body cru (php://input) antes de json_decode. Não re-serializar JSON para calcular HMAC. Compare com hash_equals.

Payload (campos reais)

{
  "event_uuid": "01234567-89ab-7def-8000-123456789abc",
  "intent_uuid": "01234567-89ab-7def-8000-123456789abd",
  "merchant_uuid": "01234567-89ab-7def-8000-123456789abe",
  "status": "paid",
  "asset": "usdt",
  "rail": "bep20",
  "expected_amount": "10.5",
  "reference": "order-12345",
  "created_at": "2026-09-07T12:00:00+00:00",
  "expires_at": "2026-09-07T14:00:00+00:00",
  "updated_at": "2026-09-07T12:05:00+00:00"
}

UUIDs acima são sintéticos. Não confie só neste JSON para mutação irreversível.

Reconciliação recomendada (pay_in.paid)

  1. Autenticar HMAC no body cru.
  2. Extrair intent_uuid.
  3. GET o PAY-IN na API YooBank.
  4. Verificar merchant, status=paid, asset, montante e reference.
  5. Executar a operação local idempotente por intent_uuid.
  6. Responder 2xx se processou agora ou se já tinha processado com segurança.

pay_in.created e pay_in.awaiting_payment: autenticar, registar, 2xx, sem efeito financeiro irreversível.

Evento autenticado mas desconhecido: 2xx sem efeito, para não gerar retry infinito.

Respostas e retries (produção)

Resposta do merchantEfeito
2xxEntregue
429Retry
qualquer 5xxRetry
falha de redeRetry
outros 4xxPermanente

Princípio zero-schema

Receiver mínimo:

HMAC → GET de reconciliação → operação de negócio idempotente por intent_uuid.

Opcional: persistir event_uuid para auditoria. Não é obrigatório.