Quem chama quem
Os endpoints /webhooks/deposit_v2 e /webhooks/deposit documentados na especificação Swagger são chamados pelo provedor de pagamento (stack DePix) para a nossa plataforma — eles não são chamados pelo seu sistema, e estão documentados aqui apenas como referência do formato de payload.
O que você efetivamente implementa é o inverso: um endpoint receptor. Quando você cria uma cobrança via POST /integrated-payment com webhook: 1 e response_url, é a nossa plataforma que faz um POST na sua response_url assim que o pagamento é confirmado — usando exatamente o mesmo formato de payload documentado abaixo para /webhooks/deposit_v2. Você não chama esses endpoints; você recebe chamadas neles ("outgoing merchant callback").
A metadata opcional enviada em details na criação da cobrança é decodificada e mesclada de volta no campo details_transaction desse callback.
⚠️ No seu próprio endpoint receptor (response_url), e em qualquer chamada que você fizer a outros endpoints desta API, sempre envie o header Accept: application/json. Sem ele, uma falha de validação de parâmetro obrigatório retorna um redirect HTML 302 em vez de um erro JSON — reproduzido ao vivo em /integrated-payment. Veja a página de API — Pagamentos para detalhes.
POST/webhooks/deposit_v2
Formato atual e recomendado para novas integrações — é também o formato usado no callback de saída (response_url) descrito acima. Autenticado com Authorization: Basic <TOKEN>, onde <TOKEN> é o valor configurado em TOKEN_API_WEBHOOK_CALLBACK_EULEN. Cabeçalhos incorretos recebem 401.
Limite de taxa efetivo: 60 requisições por minuto (verificado ao vivo via headers X-RateLimit-* em 19/07/2026). A rota em si declara um limite de 100/min, mas existe um limitador global de 60/min por IP aplicado a todas as rotas /api/*, que é mais restrito e é atingido primeiro. Versões anteriores desta documentação diziam 100/min — isso estava incorreto.
Campos do payload
| Campo | Tipo | Descrição |
qrId | string | Identificador da cobrança/QRCode. |
bankTxId | string, nullable | ID da transação bancária, quando presente. Sempre null em callbacks de saída para o integrador. |
blockchainTxID | string, nullable | ID da transação on-chain/Liquid, quando presente. |
customerMessage | string, nullable | Mensagem do pagador. |
payerName | string, nullable | Nome do pagador. |
payerTaxNumber | string, nullable | CPF/CNPJ do pagador (somente dígitos). |
payerEUID | string | Presente apenas quando o pagador é conhecido no cadastro de pagadores DePix. |
expiration | string (date-time ISO-8601) | Timestamp de expiração. |
pixKey | string, nullable | Chave PIX usada na cobrança. |
status | string | Status do pagamento (ex.: depix_sent, paid). |
valueInCents | integer | Valor em centavos. |
details_transaction | object | Presente quando há metadata associada à cobrança. Contém os dados originalmente enviados em details na criação do QRCode, decodificados e mesclados aqui. |
Exemplo de payload recebido
{
"qrId": "0196e8c8cc1071d9ad572ec4c10b8abb",
"bankTxId": "fitbank_...",
"blockchainTxID": "5532bac5c84b06e724f8266566b439011578858d2a03211ea1a261fc3add8f99",
"customerMessage": null,
"payerName": "Jane Doe",
"payerTaxNumber": "12345678901",
"expiration": "2025-05-19T11:03:15-03:00",
"pixKey": "pay@example.com",
"status": "depix_sent",
"valueInCents": 200
}
Exemplo com details_transaction (callback de saída)
{
"qrId": "0196e8c8cc1071d9ad572ec4c10b8aab",
"bankTxId": null,
"blockchainTxID": "5532bac5c84b06e724f8266566b4390115788588da03211ea1a261fc3add8f99",
"customerMessage": null,
"payerName": "Jane Doe",
"payerTaxNumber": "12345678901",
"payerEUID": "EU014794399658321",
"expiration": "2025-05-19T11:03:15-03:00",
"pixKey": "pay@example.com",
"status": "depix_sent",
"valueInCents": 1210,
"details_transaction": {
"list_id_payments": [1, 2, 3, 5],
"list_amount": [100, 253, 21.5, 145.68],
"host": [333, 333, 333, 333],
"condo": [2, 2, 2, 2]
}
}
Exemplo de resposta de sucesso (200)
Resposta real, capturada em produção para um qrId não correspondente a nenhuma cobrança pendente, num domínio sem servidores espelho configurados (19/07/2026):
{
"async": false,
"response": {
"status": [],
"thirdPart": []
},
"forward": []
}
response traz o resultado do matching/liquidação do depósito contra uma cobrança pendente. forward traz os resultados do encaminhamento do webhook para servidores espelho — só é não-vazio nos domínios rodolforomao/blackrocket.
Respostas
| Status | Significado |
| 200 | Confirmado. O processamento interno pode continuar de forma assíncrona. |
| 401 | Não autorizado — cabeçalho Authorization ausente ou inválido. {"success": false, "message": "Unauthorized.", "response": null}. |
| 429 | Limite efetivo de 60 requisições/minuto excedido (veja o aviso acima). {"message": "Too Many Attempts."}. |
POST/webhooks/deposit (legado)
Formato legado, mantido para compatibilidade — use /webhooks/deposit_v2 para novas integrações. Mesma autenticação (Authorization: Basic <TOKEN>). Também documentado apenas como referência: quem chama este endpoint é o provedor de pagamento, não o seu sistema.
Limite de taxa efetivo: 60 requisições por minuto — mesma ressalva do /webhooks/deposit_v2 acima: a rota declara 100/min, mas o limitador global de 60/min por IP em todas as rotas /api/* é mais restrito e é atingido primeiro (verificado ao vivo em 19/07/2026).
Campos do payload
| Campo | Tipo | Descrição |
qrId | string | Identificador da cobrança/QRCode. |
status | string | Status do pagamento (ex.: depix_sent, paid). |
valueInCents | integer | Valor em centavos. |
Exemplo de payload recebido
{
"qrId": "0196e8c8cc1071d9ad572ec4c10b8abb",
"status": "depix_sent",
"valueInCents": 200
}
Exemplo de resposta de sucesso (200)
{
"success": true,
"message": "Webhook received and processing."
}
O processamento interno (matching do depósito, encaminhamento para servidores espelho) acontece de forma assíncrona após o envio dessa resposta.
Respostas
| Status | Significado |
| 200 | Confirmado. O processamento interno pode continuar de forma assíncrona. |
| 401 | Não autorizado — cabeçalho Authorization ausente ou inválido. {"success": false, "message": "Unauthorized."}. |
| 429 | Limite efetivo de 60 requisições/minuto excedido (veja o aviso acima). {"message": "Too Many Attempts."}. |
Implementando seu endpoint receptor (response_url)
O endpoint que você expõe como response_url precisa: (1) validar o cabeçalho Authorization: Basic <TOKEN> antes de processar qualquer coisa, comparando-o com o token combinado com a plataforma; (2) ler o payload no formato v2 documentado acima; (3) responder rapidamente com um status 2xx para confirmar o recebimento — evite processamento pesado de forma síncrona dentro do próprio handler; (4) tratar o evento de forma idempotente, verificando se o qrId já foi processado antes de aplicar qualquer efeito colateral (como liberar um pedido).
Nunca pule a validação do cabeçalho Authorization. Um endpoint receptor que aceita qualquer chamada sem autenticação pode ser explorado para simular pagamentos falsos.
Exemplo em PHP (puro, sem framework)
<?php
// receptor-webhook.php — endpoint que VOCÊ hospeda para receber o callback
// (a plataforma faz o POST aqui quando você usa webhook:1 + response_url em /integrated-payment)
$expectedToken = getenv('MEU_TOKEN_WEBHOOK'); // valor combinado com a plataforma
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
if (!hash_equals("Basic {$expectedToken}", $authHeader)) {
http_response_code(401);
header('Content-Type: application/json');
echo json_encode(['success' => false, 'message' => 'Unauthorized']);
exit;
}
$payload = json_decode(file_get_contents('php://input'), true);
// Payload no formato v2 (mesmo shape de /webhooks/deposit_v2):
// qrId, bankTxId, blockchainTxID, customerMessage, payerName, payerTaxNumber,
// payerEUID?, expiration, pixKey, status, valueInCents, details_transaction?
if (in_array($payload['status'] ?? null, ['depix_sent', 'paid'], true)) {
// Marque o pedido correspondente a $payload['qrId'] como pago.
// Se você enviou metadata em `details` na criação da cobrança, ela
// volta aqui em $payload['details_transaction'].
}
// Responda 2xx rapidamente para confirmar o recebimento.
http_response_code(200);
header('Content-Type: application/json');
echo json_encode(['success' => true]);
Exemplo em Node.js (Express)
// receptor-webhook.js — endpoint que VOCÊ hospeda para receber o callback
// (a plataforma faz o POST aqui quando você usa webhook:1 + response_url em /integrated-payment)
const express = require('express');
const app = express();
app.use(express.json());
const EXPECTED_TOKEN = process.env.MEU_TOKEN_WEBHOOK; // valor combinado com a plataforma
app.post('/webhook/pix-pago', (req, res) => {
const authHeader = req.headers['authorization'] || '';
if (authHeader !== `Basic ${EXPECTED_TOKEN}`) {
return res.status(401).json({ success: false, message: 'Unauthorized' });
}
const payload = req.body;
// Payload no formato v2 (mesmo shape de /webhooks/deposit_v2):
// qrId, bankTxId, blockchainTxID, customerMessage, payerName, payerTaxNumber,
// payerEUID?, expiration, pixKey, status, valueInCents, details_transaction?
if (payload.status === 'depix_sent' || payload.status === 'paid') {
// Marque o pedido correspondente a payload.qrId como pago.
// Se você enviou metadata em `details` na criação da cobrança, ela
// volta aqui em payload.details_transaction.
}
// Responda 2xx rapidamente para confirmar o recebimento.
res.status(200).json({ success: true });
});
app.listen(3000);