Skip to main content
A Linka notifica o seu sistema em tempo real via webhooks sempre que um evento relevante ocorre. Cada requisicao inclui uma assinatura HMAC-SHA256 para garantir autenticidade.

Configurando um Endpoint de Webhook

1

Crie um endpoint HTTPS no seu servidor

O endpoint deve estar acessivel publicamente via HTTPS e retornar HTTP 200 para confirmação.
2

Registre o webhook na Linka

curl -X POST https://api.linka.com/webhooks \
  -H "Authorization: Bearer {seu_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://seu-sistema.com.br/webhooks/linka",
    "description": "Webhook de produção",
    "eventType": "ALL"
  }'
Resposta 201
{
  "id": "webhook_uuid",
  "url": "https://seu-sistema.com.br/webhooks/linka",
  "eventType": "ALL",
  "secret": "a3f8c2d1e9b4...",
  "isActive": true,
  "createdAt": "2026-04-09T12:00:00.000Z"
}
O campo secret e exibido apenas nesta resposta. Salve-o imediatamente — ele não sera exibido novamente. Use este secret para validar a assinatura HMAC de todos os webhooks recebidos.
3

Implemente a validação de assinatura

Cada webhook inclui o campo signature no payload. Valide-o antes de processar qualquer evento.
const crypto = require('crypto');

function validateWebhookSignature(payload, receivedSignature, secret) {
  const computed = crypto
    .createHmac('sha256', secret)
    .update(JSON.stringify(payload))
    .digest('hex');

  const expected = `hmac-v1-sha256-${computed}`;

  return crypto.timingSafeEqual(
    Buffer.from(expected),
    Buffer.from(receivedSignature)
  );
}

// No seu handler de webhook
app.post('/webhooks/linka', (req, res) => {
  const { signature, ...eventData } = req.body;

  if (!validateWebhookSignature(eventData, signature, process.env.LINKA_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: 'Assinatura invalida' });
  }

  // Processar o evento...
  res.status(200).json({ received: true });
});

Tipos de Evento

eventType no cadastroEventos recebidos
TRANSACTIONTodos os TRANSACTION_*
WITHDRAWALTodos os WITHDRAWAL_*
DISPUTETodos os DISPUTE_* e MED_DISPUTE_*
ALLTodos os eventos acima

Eventos de Transação

TRANSACTION_CREATED

Disparado imediatamente após a criacao da transação, antes da resposta da IP.
{
  "eventType": "TRANSACTION_CREATED",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "PIX",
  "status": "PENDING",
  "description": "Pedido #123",
  "installments": 1,
  "metadata": { "orderId": "order-abc" },
  "pix": null,
  "boleto": null,
  "card": null,
  "customer": { "name": "Jo***", "email": "j***@email.com" },
  "createdAt": "2026-04-09T12:00:00.000Z"
}

TRANSACTION_WAITING_PAYMENT

Disparado quando a IP confirma que o instrumento de pagamento foi gerado e aguarda o pagador.
{
  "eventType": "TRANSACTION_WAITING_PAYMENT",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "PIX",
  "status": "WAITING_PAYMENT",
  "pix": {
    "copyPaste": "00020126580014br.gov.bcb.pix...",
    "expirationDate": "2026-04-09T13:00:00.000Z"
  },
  "createdAt": "2026-04-09T12:00:00.000Z"
}

TRANSACTION_PAID

Pagamento confirmado. Para PIX, o crédito ja foi processado na wallet. Para boleto e cartão, o valor esta em saldo pendente.
{
  "eventType": "TRANSACTION_PAID",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "PIX",
  "status": "PAID",
  "end2endId": "E12345678202604091200...",
  "paidAt": "2026-04-09T12:05:00.000Z",
  "description": "Pedido #123",
  "installments": 1,
  "metadata": { "orderId": "order-abc" },
  "pix": { "copyPaste": "00020126...", "expirationDate": "..." },
  "boleto": null,
  "card": null,
  "payer": { "name": "Ma***", "document": "***456**" },
  "customer": { "name": "Jo***", "email": "j***@email.com" },
  "items": [],
  "createdAt": "2026-04-09T12:00:00.000Z"
}

TRANSACTION_FAILED

Falha técnica, expiração de boleto/PIX, ou erro sem mapeamento.
{
  "eventType": "TRANSACTION_FAILED",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "BOLETO",
  "status": "FAILED",
  "description": "Pedido #456",
  "createdAt": "2026-04-09T12:00:00.000Z"
}

TRANSACTION_EXPIRED

PIX ou boleto vencido sem pagamento.
{
  "eventType": "TRANSACTION_EXPIRED",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "PIX",
  "status": "FAILED",
  "createdAt": "2026-04-09T12:00:00.000Z"
}

TRANSACTION_REFUNDED

Estorno total processado.
{
  "eventType": "TRANSACTION_REFUNDED",
  "signature": "hmac-v1-sha256-...",
  "id": "txn_uuid",
  "amount": 15000,
  "method": "PIX",
  "status": "REFUNDED",
  "refundedAmount": 15000,
  "createdAt": "2026-04-09T12:00:00.000Z"
}

Eventos de Saque

WITHDRAWAL_PROCESSING

O saque esta sendo processado pela IP.
{
  "eventType": "WITHDRAWAL_PROCESSING",
  "signature": "hmac-v1-sha256-...",
  "id": "wd_uuid",
  "amount": 50000,
  "method": "PIX",
  "pixKey": "***@email.com",
  "pixKeyType": "EMAIL",
  "status": "PROCESSING",
  "createdAt": "2026-04-09T12:00:00.000Z"
}

WITHDRAWAL_COMPLETED

Transferencia concluida com sucesso.
{
  "eventType": "WITHDRAWAL_COMPLETED",
  "signature": "hmac-v1-sha256-...",
  "id": "wd_uuid",
  "amount": 50000,
  "method": "PIX",
  "pixKey": "***@email.com",
  "pixKeyType": "EMAIL",
  "status": "COMPLETED",
  "withdrawalType": "STANDARD",
  "approvedAt": "2026-04-09T12:01:00.000Z",
  "processedAt": "2026-04-09T12:01:05.000Z",
  "end2end": "E12345678202604091201...",
  "externalRef": "ref-ip-123",
  "metadata": null,
  "destinationAccount": {
    "bankCode": "***",
    "agency": "***",
    "account": "***"
  },
  "createdAt": "2026-04-09T12:00:00.000Z"
}

WITHDRAWAL_FAILED

Falha na transferencia. O saldo (amount + feeAmount) foi reembolsado automaticamente para a wallet.
{
  "eventType": "WITHDRAWAL_FAILED",
  "signature": "hmac-v1-sha256-...",
  "id": "wd_uuid",
  "amount": 50000,
  "method": "PIX",
  "pixKey": "***@email.com",
  "pixKeyType": "EMAIL",
  "status": "FAILED",
  "createdAt": "2026-04-09T12:00:00.000Z"
}

Eventos de Disputa

DISPUTE_OPENED

Disputa aberta — chargeback ou MED recebido.
{
  "eventType": "DISPUTE_OPENED",
  "signature": "hmac-v1-sha256-...",
  "id": "dispute_uuid",
  "amount": 15000,
  "status": "OPENED",
  "reason": "Fraude",
  "metadata": null,
  "createdAt": "2026-04-09T14:00:00.000Z"
}

DISPUTE_RESOLVED

Decisão a favor do seller — saldo restaurado.
{
  "eventType": "DISPUTE_RESOLVED",
  "signature": "hmac-v1-sha256-...",
  "id": "dispute_uuid",
  "amount": 15000,
  "status": "RESOLVED",
  "createdAt": "2026-04-09T14:00:00.000Z"
}

DISPUTE_REJECTED

Decisão a favor do comprador — valor debitado permanentemente.
{
  "eventType": "DISPUTE_REJECTED",
  "signature": "hmac-v1-sha256-...",
  "id": "dispute_uuid",
  "amount": 15000,
  "status": "REJECTED",
  "createdAt": "2026-04-09T14:00:00.000Z"
}

MED_DISPUTE_CREATED

MED PIX criado automaticamente pelo BACEN.
{
  "eventType": "MED_DISPUTE_CREATED",
  "signature": "hmac-v1-sha256-...",
  "id": "med_dispute_uuid",
  "status": "OPEN",
  "amount": 15000,
  "transactionId": "txn_uuid",
  "deadline": "2026-04-16T23:59:59.000Z",
  "end2EndId": "E12345678202604091200...",
  "createdAt": "2026-04-09T14:30:00.000Z"
}

Comportamento de Retry

Se o seu endpoint retornar um status de erro (5xx) ou timeout, a Linka tentara reenviar automaticamente com backoff exponencial:
TentativaDelay aproximado
1 (inicial)Imediato
2~2 segundos
3~4 segundos
Erros 4xx (ex: 401, 404) não sao retentados — sao tratados como erro de configuração do seller.
Se todas as tentativas falharem, o evento não e reenfileirado automaticamente. Use o endpoint POST /webhooks/resend-transaction-event para forccar o reenvio manual de eventos específicos.

Reenviando Eventos Manualmente

curl -X POST https://api.linka.com/webhooks/resend-transaction-event \
  -H "Authorization: Bearer {seu_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "transactionIds": ["txn_uuid_1", "txn_uuid_2"]
  }'
curl -X POST https://api.linka.com/webhooks/resend-withdrawal-event \
  -H "Authorization: Bearer {seu_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "withdrawalIds": ["wd_uuid_1"]
  }'

Privacidade dos Dados (LGPD)

Todos os payloads de webhook tem dados pessoais (PII) mascarados antes do envio:
CampoExemplo originalMascarado
customer.nameJoao SilvaJo***
customer.email[email protected]j***@email.com
payer.nameMaria OliveiraMa***
payer.document12345678901***456**
pixKey (saque)[email protected]***@email.com
destinationAccount.*dados bancarios***
Para acessar os dados completos, use GET /transactions/:id ou GET /withdrawals/:id com autenticação.