Pular para o conteúdo principal

O que são Webhooks?

Webhooks são notificações HTTP enviadas pela Owem para sua aplicação quando eventos importantes ocorrem. Ao invés de fazer polling constante, você recebe os dados assim que algo acontece.

Tempo Real

Receba notificações instantaneamente.

Confiável

Sistema de retry automático em falhas.

Seguro

Valide origem por IP e headers.

Flexível

Configure quais eventos deseja receber.

Como Funciona

1

Configure o Webhook

Cadastre a URL do seu endpoint no painel ou via API.
2

Evento Ocorre

Um pagamento é confirmado, transferência concluída, etc.
3

Owem Envia

Fazemos um POST para sua URL com os dados do evento.
4

Você Processa

Sua aplicação processa o evento e responde com 200 OK.

Catálogo de Eventos

EventoDisparo
pix_in:qrcode_paidPagamento realizado via QR Code (PIX IN).
pix_in:creditedCrédito recebido via chave PIX.
pix_in:refunded_processingEstorno de PIX IN iniciado (retorna succeeded/failed).
pix_in:refunded_med_processingEstorno de PIX IN iniciado por MED (retorna succeeded/failed).
pix_out:processingTransferência PIX OUT registrada (retorna succeeded/failed).
pix_out:refunded_processingDevolução de PIX OUT iniciada (retorna succeeded/failed).
med:receivedMED (Mecanismo Especial de Devolução) recebido.
Use "*" na configuração para receber todos os eventos, ou liste eventos específicos.

Estrutura do Payload

Campos Top-Level

CampoTipoDescrição
webhookIdstringID da configuração de webhook que originou o evento.
userIdstringUsuário proprietário.
accountIdstringConta relacionada ao evento.
eventstringTipo do evento (ex.: pix_out:processing).
objectobjetoDados específicos do evento.

Campos do object — eventos PIX

CampoTipoDescrição
idstringIdentificador do lançamento.
externalIdstringID definido pelo cliente (idempotência/conciliador).
idempotencyKeystringChave de idempotência do lançamento.
typeenumcredit ou debit.
reasonenumRazão contábil (ex.: pix_out:processing).
statusenumprocessing, succeeded, failed.
grossAmountnumberValor bruto.
feeAmountnumberTarifa aplicada.
netAmountnumberValor líquido.
endToEndIdstringIdentificador E2E PIX.
parentEndToEndIdstringE2E original em estornos/devoluções.
payerobjetoDados do pagador (ispb, cpfCnpj, name, agency, accountNumber).
receiverobjetoDados do recebedor.
createdAtnumberEpoch millis (criação).
updatedAtnumberEpoch millis (última atualização).

Exemplo — pix_out:processing

{
  "webhookId": "wh_abc123",
  "userId": "usr_abcdef12",
  "accountId": "987654321000",
  "event": "pix_out:processing",
  "object": {
    "id": "E000111222333444555AAA999BBB000CCC",
    "externalId": "TX-20250101-001",
    "idempotencyKey": "debit:pix_out:processing:E000111222333444555AAA999BBB000CCC",
    "type": "debit",
    "reason": "pix_out:processing",
    "status": "succeeded",
    "grossAmount": 100.0,
    "feeAmount": 0.5,
    "netAmount": 99.5,
    "endToEndId": "E000111222333444555AAA999BBB000CCC",
    "parentEndToEndId": null,
    "payer": {
      "ispb": "12345678",
      "personType": "company",
      "cpfCnpj": "11111111000191",
      "name": "EMPRESA EXEMPLO LTDA",
      "agency": "0001",
      "accountNumber": "987654321000"
    },
    "receiver": {
      "ispb": "87654321",
      "personType": "person",
      "cpfCnpj": "12345678900",
      "name": "MARIA SILVA",
      "agency": "0001",
      "accountNumber": "300543881811"
    }
  }
}

Campos do object — evento med:received

CampoTipoDescrição
endToEndIdstringIdentificador E2E relacionado ao MED.
detailsstringDescritivo do motivo do MED.
medIdstringID único do MED.
dtHrCreationReasonstringData/hora ISO-8601 da criação do MED.
entryIdstringtxId (QR pago) vinculado.

Exemplo — med:received

{
  "webhookId": "wh_abc123",
  "userId": "usr_abcdef12",
  "accountId": "987654321000",
  "event": "med:received",
  "object": {
    "endToEndId": "E000111222333444555AAA999BBB000CCC",
    "details": "Cliente reporta não recebimento do produto.",
    "medId": "med_123e4567-e89b-12d3-a456-426614174000",
    "dtHrCreationReason": "2025-01-01T00:02:57.933Z",
    "entryId": "f929fba7e3744b6ea1def9bafe"
  }
}

Segurança

Validação de IP

Valide que o webhook veio da Owem verificando o IP de origem:
IP Owem
34.134.50.53
35.238.101.57
const OWEM_IPS = ["34.134.50.53", "35.238.101.57"]

app.post("/webhook", (req, res) => {
  const clientIp = req.headers["x-forwarded-for"] || req.socket.remoteAddress

  if (!OWEM_IPS.includes(clientIp)) {
    return res.status(403).send("Forbidden")
  }

  // Processar webhook
  res.status(200).send("OK")
})

HTTPS Obrigatório

Seu endpoint deve usar HTTPS com certificado válido.

Entrega e Timeout

  • Responda em até 3 segundos com HTTP 2xx (200/201/204) para confirmar o recebimento.
  • Respostas > 3s ou códigos 4xx/5xx contam como falha de entrega.
  • Em falha, a Owem aplica reentrega com backoff exponencial.
Múltiplas falhas consecutivas podem desativar o webhook até revisão manual.

Autenticação no Callback

Se configurado um authHeader na sua configuração de webhook, a Owem enviará esse valor no header Authorization em todas as chamadas.
Recomendação: valide IP de origem + header de autorização no seu endpoint.

Requisitos do Endpoint

RequisitoDescrição
ProtocoloHTTPS obrigatório
MétodoAceitar POST
TimeoutResponder em até 3 segundos
RespostaStatus 2xx para sucesso
Content-TypeAceitar application/json

Endpoints Relacionados


Exemplo de Handler

const express = require("express")
const app = express()

const OWEM_IPS = ["34.134.50.53", "35.238.101.57"]

app.use(express.json())

app.post("/webhooks/owem", (req, res) => {
  // 1. Valida IP
  const clientIp =
    req.headers["x-forwarded-for"]?.split(",")[0] || req.socket.remoteAddress
  if (!OWEM_IPS.includes(clientIp)) {
    console.log("IP não autorizado:", clientIp)
    return res.status(403).send("Forbidden")
  }

  // 2. Processa evento
  const { event, data } = req.body

  switch (event) {
    case "pix_in:qrcode_paid":
      console.log("Pagamento recebido:", data.txId, data.amount)
      // Atualizar pedido como pago
      break

    case "pix_out:succeeded":
      console.log("Transferência concluída:", data.endToEndId)
      // Atualizar status do pagamento
      break

    case "pix_out:failed":
      console.log("Transferência falhou:", data.externalId, data.reason)
      // Notificar equipe financeira
      break

    default:
      console.log("Evento não tratado:", event)
  }

  // 3. Responde rápido
  res.status(200).send("OK")
})

app.listen(3000)

Boas Práticas

Responda Rápido

Processe em background e responda 200 imediatamente.

Seja Idempotente

Trate webhooks duplicados sem efeitos colaterais.

Logue Tudo

Registre todos os webhooks para debugging.

Monitore Falhas

Acompanhe taxa de sucesso dos seus endpoints.