Oceanbris Docs

Webhooks

Eventos e payloads

Todos os tipos de evento, quando cada um é enviado e o formato real do conteúdo.

Todo evento chega com o mesmo envelope:

CampoDescrição
idId do evento (evt_...). Use para não processar o mesmo evento duas vezes.
typeTipo, ex.: charge.paid.
versionVersão do formato (v1).
created_atMomento do fato (UTC).
environmentproduction. O valor sandbox está reservado para o ambiente de testes, que ainda está em preparação.
dataConteúdo do evento (abaixo, por tipo).

Valores em centavos vêm como string. Campos novos podem ser acrescentados ao data sem aviso prévio: ignore o que você não conhece.

Tipos de evento

TipoQuando
charge.pendingO QR foi emitido e a cobrança aguarda pagamento.
charge.paidPagamento confirmado (também em pagamento tardio, com late_payment: true).
charge.expiredA validade acabou sem pagamento, ou a cobrança foi cancelada antes do pagamento (data.status: "cancelled").
charge.failedA emissão do Pix foi recusada ou não pôde ser feita.
charge.refundedUma devolução foi concluída.
charge.duplicate_paymentO mesmo QR foi pago de novo; o valor extra fica retido para devolução.
case.openedUm caso foi aberto: devolução, contestação (MED) ou revisão.
case.resolvedUm caso foi resolvido.
balance.availableValores ficaram disponíveis para saque (por venda, na hora, ou por liquidação).
payout.createdVocê pediu um saque (pelo painel ou pela API); o valor pedido ficou reservado.
payout.approvedA Oceanbris aprovou o saque e vai fazer a transferência.
payout.rejectedA Oceanbris recusou o saque; o valor pedido voltou ao disponível.
payout.channel_changedA Oceanbris vai pagar o saque aprovado por outro meio (transferência feita pela Oceanbris); o valor segue reservado.
payout.paidA Oceanbris transferiu o saque para a sua conta.
payout.failedO saque foi encerrado sem pagamento: cancelado por você antes da análise ou, no envio automático, falhou. O valor pedido voltou ao disponível.
reserve.releasedUma reserva contratual foi liberada para o seu saldo.
pricing.policy_publishedUma nova tarifa foi publicada para a sua conta.
reserve.policy_publishedUma nova regra de reserva contratual foi publicada.

A lista oficial, com a versão e o formato da assinatura, sai em Listar tipos de evento.

Cobranças

charge.pending

Payload de charge.pending
{
  "id": "evt_1a7c3e9b5d2f4a8e9c6b0d3f7a1e5c92",
  "type": "charge.pending",
  "version": "v1",
  "created_at": "2026-10-07T15:30:01.000Z",
  "environment": "production",
  "data": {
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "order_reference": "PEDIDO-1001",
    "status": "pending",
    "amount_cents": "15990",
    "expires_at": "2026-10-07T16:00:00.000Z"
  }
}

charge.paid

O evento mais importante: libere o pedido depois de confirmar pela consulta. Traz bruto (amount_cents), tarifa (fee_cents), líquido (net_cents), reserva, data do pagamento e o identificador fim a fim do Pix. Em pagamento tardio, late_payment vem true e case_id aponta o caso de revisão.

Payload de charge.paid
{
  "id": "evt_2f6b1c9e8a4d4e7f9b3c5a1d0e6f8b27",
  "type": "charge.paid",
  "version": "v1",
  "created_at": "2026-10-07T15:32:11.000Z",
  "environment": "production",
  "data": {
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "order_reference": "PEDIDO-1001",
    "amount_cents": "15990",
    "fee_cents": "320",
    "net_cents": "15670",
    "reserve_cents": "0",
    "paid_at": "2026-10-07T15:32:10.000Z",
    "end_to_end_id": "E12345678202610071532a1B2c3D4e5F",
    "late_payment": false,
    "case_id": null
  }
}

charge.expired

Enviado quando a cobrança deixa de aceitar pagamento: data.status vem expired (a validade acabou) ou cancelled (a cobrança foi cancelada antes do pagamento). Não há evento separado para o cancelamento.

Payload de charge.expired
{
  "id": "evt_3b9d5f1a7c2e4b6d8f0a2c4e6b8d1f37",
  "type": "charge.expired",
  "version": "v1",
  "created_at": "2026-10-07T16:00:05.000Z",
  "environment": "production",
  "data": {
    "charge_id": "b2e7c4d1-9a36-4f58-8c0e-1d5a7f3b6e92",
    "order_reference": "PEDIDO-1002",
    "status": "expired"
  }
}

charge.failed

reason sempre vem e é um código estável do motivo, bom para decidir no código. Para exibir, use failure_message da cobrança (consulta), que é um texto fixo da Oceanbris.

reasonSignificado
rejected:fraudRecusada pela análise de risco.
rejected:invalid_requestDados da cobrança ou do pagador inválidos ou incompletos.
rejected:complianceRecusada pela análise de conformidade.
rejected:limitLimite de recebimento da conta atingido.
rejected:sectorSegmento da venda não aceito para a conta.
rejected:registrationPendência no cadastro da conta.
rejected:blocked ou rejected:account_suspendedRecebimentos bloqueados ou suspensos para a conta.
rejected:otherOutra recusa definitiva.
not_created:<motivo>Falha técnica na emissão; nada foi criado (ex.: not_created:transient_error).
unknown_resolved_not_createdA emissão ficou sem resposta e, depois de conferida, não tinha sido criada.
expired_before_issueA validade acabou antes de a emissão ser confirmada.

Em todos os casos, nenhum QR Code válido foi entregue: crie uma nova cobrança com outro order_reference.

Payload de charge.failed
{
  "id": "evt_4c0e6a2b8d3f4c7e9a1b3d5f7c9e2a48",
  "type": "charge.failed",
  "version": "v1",
  "created_at": "2026-10-07T15:40:02.000Z",
  "environment": "production",
  "data": {
    "charge_id": "e41a9c7b-2d58-4e06-b3f1-7c9d0a2e5b18",
    "order_reference": "PEDIDO-1003",
    "status": "failed",
    "reason": "rejected:fraud"
  }
}

charge.refunded

refunded_cents é o valor desta devolução.

Payload de charge.refunded
{
  "id": "evt_5d1f7b3c9e4a4d8f0b2c4e6a8d0f3b59",
  "type": "charge.refunded",
  "version": "v1",
  "created_at": "2026-10-08T12:00:04.000Z",
  "environment": "production",
  "data": {
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "case_id": "3c7e1b95-6d2a-4f80-9e4b-a1d5c8f20e63",
    "refunded_cents": "5000"
  }
}

charge.duplicate_payment

Payload de charge.duplicate_payment
{
  "id": "evt_6e2a8c4d0f5b4e9a1c3d5f7b9e1a4c60",
  "type": "charge.duplicate_payment",
  "version": "v1",
  "created_at": "2026-10-07T15:35:20.000Z",
  "environment": "production",
  "data": {
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "order_reference": "PEDIDO-1001",
    "payment_id": "f2c8a5e1-3b7d-4e90-a6c4-8d1f5b2e9a73",
    "classification": "duplicate",
    "amount_cents": "15990",
    "end_to_end_id": "E12345678202610071535f6G7h8J9k0L",
    "case_id": "6a2f9d14-8e3b-4c57-b1d0-5e9a7c3f2b81"
  }
}

Casos

case.opened

Payload de case.opened
{
  "id": "evt_7f3b9d5e1a6c4f0b2d4e6a8c0f2b5d71",
  "type": "case.opened",
  "version": "v1",
  "created_at": "2026-10-08T12:00:00.000Z",
  "environment": "production",
  "data": {
    "case_id": "3c7e1b95-6d2a-4f80-9e4b-a1d5c8f20e63",
    "case_type": "refund",
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "amount_cents": "5000",
    "reason": "Cliente devolveu um item"
  }
}

case.resolved

resolution diz o desfecho (ex.: refunded) e uncovered_cents a parte que não tinha saldo para cobrir, quando houver.

Payload de case.resolved
{
  "id": "evt_8a4c0e6f2b7d4a1c3e5f7b9d1a3c6e82",
  "type": "case.resolved",
  "version": "v1",
  "created_at": "2026-10-08T12:00:04.000Z",
  "environment": "production",
  "data": {
    "case_id": "3c7e1b95-6d2a-4f80-9e4b-a1d5c8f20e63",
    "case_type": "refund",
    "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
    "amount_cents": "5000",
    "resolution": "refunded",
    "uncovered_cents": "0"
  }
}

Saldo

balance.available

amount_cents é o total que ficou disponível. Há dois formatos: por liquidação (settlement_id preenchido; charge_id e payment_id ausentes) e por venda, quando a adquirente libera na hora (settlement_id é null e vêm charge_id e payment_id da venda). Trate settlement_id como opcional.

Payload de balance.available
{
  "id": "evt_9b5d1f7a3c8e4b2d4f6a8c0e2b4d7f93",
  "type": "balance.available",
  "version": "v1",
  "created_at": "2026-10-08T08:00:02.000Z",
  "environment": "production",
  "data": {
    "settlement_id": "9e2d5b7a-3c18-4f6e-b0a4-7d1c9e5f2a83",
    "amount_cents": "15670"
  }
}

Saques

Os saques são pedidos pelo painel ou pela API, a qualquer hora (veja Saques). Todos os eventos de saque trazem payout_id, o valor pedido (requested_cents), a taxa de saque (fee_cents) e o valor enviado à sua conta (amount_cents = pedido − taxa).

payout.created

O pedido foi registrado e o valor pedido saiu do disponível. Ele aguarda a aprovação da Oceanbris (approval_status: "pending").

Payload de payout.created
{
  "id": "evt_a1c6e2b8d4f04a9c8e2b6d0f4a8c1e57",
  "type": "payout.created",
  "version": "v1",
  "created_at": "2026-10-10T17:00:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "a4c81e5d-7f2b-4d39-9e06-3b5f8c1d2e74",
    "requested_cents": "5000",
    "fee_cents": "500",
    "amount_cents": "4500",
    "approval_status": "pending",
    "execution_status": "reserved",
    "scheduled_for": null
  }
}

payout.approved

A Oceanbris aprovou o pedido e vai fazer a transferência.

Payload de payout.approved
{
  "id": "evt_b2d7f3c9e5a14b0d9f3c7e1a5b9d2f68",
  "type": "payout.approved",
  "version": "v1",
  "created_at": "2026-10-12T12:10:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "a4c81e5d-7f2b-4d39-9e06-3b5f8c1d2e74",
    "requested_cents": "5000",
    "fee_cents": "500",
    "amount_cents": "4500",
    "approval_mode": "manual",
    "scheduled_for": null
  }
}

payout.rejected

A Oceanbris recusou o pedido. reason é o motivo informado pela Oceanbris; o valor pedido voltou ao disponível.

Payload de payout.rejected
{
  "id": "evt_d4f9b5e1a7c34d2f1b5e9a3c7d1f4b80",
  "type": "payout.rejected",
  "version": "v1",
  "created_at": "2026-10-12T12:15:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "c9e2a7f4-1d6b-4a83-b5e0-6f3d9a2c8b15",
    "requested_cents": "2000",
    "fee_cents": "500",
    "amount_cents": "1500",
    "reason": "Conta de destino diferente da combinada no contrato",
    "execution_status": "cancelled"
  }
}

payout.failed

O saque foi encerrado sem pagamento e o valor pedido voltou ao disponível (execution_status: "cancelled"). Quando você cancela o pedido (Cancelar um saque ou o painel), reason é o motivo que você informou (ou um texto padrão); no envio automático, é o motivo da falha em texto fixo da Oceanbris.

Payload de payout.failed
{
  "id": "evt_f6b2d8e4a0c15f7b3d9e1a5c7b3f6d02",
  "type": "payout.failed",
  "version": "v1",
  "created_at": "2026-10-13T09:31:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "d0b4f8a2-6c1e-4f7b-9a35-2e8c5d1f7b46",
    "requested_cents": "1000",
    "fee_cents": "500",
    "amount_cents": "500",
    "reason": "Pedido feito por engano",
    "execution_status": "cancelled"
  }
}

payout.channel_changed

A Oceanbris aprovou o saque para envio pela conta de saída, mas vai pagá-lo por outro meio: execution_channel passa a manual_transfer (transferência feita pela Oceanbris). O motivo interno não vai no evento (desde 20/10/2026). Nada muda no valor nem na reserva: o saque continua aprovado e termina com payout.paid.

Payload de payout.channel_changed
{
  "id": "evt_e5a1c7d3b9f24e6a2c8d0b4f6a2e5c91",
  "type": "payout.channel_changed",
  "version": "v1",
  "created_at": "2026-10-12T12:40:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "a4c81e5d-7f2b-4d39-9e06-3b5f8c1d2e74",
    "requested_cents": "5000",
    "fee_cents": "500",
    "amount_cents": "4500",
    "execution_channel": "manual_transfer"
  }
}

payout.paid

A Oceanbris transferiu o valor enviado para a sua conta. transfer_reference é a referência da transferência e paid_at, quando ela foi feita.

Payload de payout.paid
{
  "id": "evt_c3e8a4d0f6b24c1e0a4d8f2b6c0e3a79",
  "type": "payout.paid",
  "version": "v1",
  "created_at": "2026-10-12T13:04:00.000Z",
  "environment": "production",
  "data": {
    "payout_id": "a4c81e5d-7f2b-4d39-9e06-3b5f8c1d2e74",
    "requested_cents": "5000",
    "fee_cents": "500",
    "amount_cents": "4500",
    "transfer_reference": "E98765432202610121300Sq4Ke7Mn2Pw",
    "paid_at": "2026-10-12T13:00:00.000Z"
  }
}

Recuperando eventos

Todos os eventos ficam disponíveis pela API, independentemente da entrega. Use para conferir o que pode ter se perdido enquanto o seu endpoint estava fora do ar:

GET/v1/webhooks/events
curl -X GET 'https://api.oceanbris.com/v1/webhooks/events?type=charge.paid&limit=20' \
  -H "Authorization: Bearer $API_KEY"
200Resposta
{
  "items": [
    {
      "id": "evt_2f6b1c9e8a4d4e7f9b3c5a1d0e6f8b27",
      "type": "charge.paid",
      "version": "v1",
      "environment": "production",
      "object_type": "charge",
      "object_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
      "created_at": "2026-10-07T15:32:11.000Z",
      "data": {
        "charge_id": "8d3f6a12-4b9e-4c71-a2d5-6e0f1b3c9a47",
        "order_reference": "PEDIDO-1001",
        "amount_cents": "15990",
        "fee_cents": "320",
        "net_cents": "15670",
        "reserve_cents": "0",
        "paid_at": "2026-10-07T15:32:10.000Z",
        "end_to_end_id": "E12345678202610071532a1B2c3D4e5F",
        "late_payment": false,
        "case_id": null
      }
    }
  ],
  "next_cursor": null
}