Webhooks
Receba eventos da Stater em tempo real no seu sistema.
Webhooks notificam seu sistema sempre que algo importante acontece na Stater. Você registra uma URL HTTPS e seleciona quais eventos quer receber.
Eventos disponíveis
pix.in.received— Pix recebido na conta.pix.payout.succeeded— Pix enviado liquidou.pix.payout.failed— Pix enviado falhou.pix.payout.cancelled— Pix enviado foi cancelado.pix.payout.refunded— Pix enviado foi devolvido.pix.charge.paid— Cobrança paga.pix.charge.expired— Cobrança expirou sem pagamento.pix.charge.refunded— Cobrança recebeu devolução.tev.in.received— TEV (transferência interna) recebida na conta.tev.out.succeeded— TEV enviada liquidou.tev.out.failed— TEV enviada falhou (valor devolvido ao saldo).
Registrar endpoint
curl -X POST https://api.staterpay.io/v1/pix-accounts/$ACCOUNT_ID/webhooks \-H "Authorization: Bearer SUA_API_KEY" \-H "Idempotency-Key: $(uuidgen)" \-H "Content-Type: application/json" \-d '{ "url": "https://api.minhaempresa.com/webhooks/stater", "events": [ "pix.in.received", "pix.payout.succeeded", "pix.charge.paid", "pix.charge.expired" ], "authToken": "um-segredo-forte-gerado-por-voce"}'Você define o authToken ao criar — gere um segredo forte
(UUID v4 ou bytes aleatórios). Guarde-o em local seguro:
o valor só é retornado nesta criação; listagens posteriores não o
incluem.
Verificando a autenticidade
Cada requisição enviada ao seu endpoint contém o header
Authorization com o valor exato do
authToken que você configurou na criação do webhook
(sem prefixo Bearer). Compare-o de forma
time-safe com o valor armazenado para evitar ataques
de timing.
import { timingSafeEqual } from "crypto";import express from "express";const app = express();app.use(express.json());app.post("/stater/webhook", (req, res) => {const received = req.header("authorization") ?? "";const expected = process.env.STATER_WEBHOOK_TOKEN!;const ok = received.length === expected.length && timingSafeEqual(Buffer.from(received), Buffer.from(expected));if (!ok) return res.status(401).end();const event = req.body;// processar event.event / event.data em backgroundres.status(200).end();});Sua resposta deve voltar em até 10 segundos com um status 2xx. Caso contrário a Stater fará retry com backoff exponencial. Processe pesadamente em background.
Payloads de eventos
Pix recebido (pix.in.received)
{"event": "pix.in.received","data": { "payerName": "Pedro Ferreira de Souza", "endToEndId": "E18236120202605041049s078600ecc6", "movementId": "cmor2uwya002inxqkoyow2167", "receivedAt": "2026-05-04T10:49:34.558Z", "amountCents": "120", "payerBranch": "1", "paymentDate": "2026-05-04 10:49:33.995783+00:00", "payerAccount": "49773517", "pixAccountId": "cmokguchz0004duqk7pj3f2e4", "coreAccountId": "cmokguchu0003duqkodsv49bx", "payerDocument": "17227372361", "payerInstitution": "18236120"}}Pix enviado liquidou (pix.payout.succeeded)
{"event": "pix.payout.succeeded","data": { "payoutId": "cmpco4vvd000cb4qkvna8cm71", "endToEndId": "E37319859202605191328CGTFMTDP4RX", "movementId": "cmpco4vtq0009b4qk2g9g7jom", "occurredAt": "2026-05-19T13:28:23.873Z", "amountCents": "1", "payerBranch": "1", "payerAccount": "598375", "beneficiaryName": "Fulano de Tal", "beneficiaryBranch": "1", "beneficiaryPixKey": "fulano@example.com", "beneficiaryAccount": "49773517", "beneficiaryDocument": "12345678900", "beneficiaryPixKeyType": "EMAIL", "beneficiaryAccountType": null, "beneficiaryInstitution": "18236120"}}Pix enviado falhou (pix.payout.failed)
{"event": "pix.payout.failed","data": { "payoutId": "cmor35abc002vnxqkp1q9wzj4", "movementId": "cmor35abc0030nxqk5kf2x8d1", "endToEndId": "E18236120202605041102k08aabb1234", "amountCents": "5000", "occurredAt": "2026-05-04T11:02:14.227Z", "reason": "recipient_not_found"}}Pix enviado cancelado (pix.payout.cancelled)
{"event": "pix.payout.cancelled","data": { "payoutId": "cmor36def0031nxqkqr2xahg9", "movementId": "cmor36def0035nxqk7a8tc4e2", "endToEndId": "E18236120202605041105m08c12cd567", "amountCents": "2500", "occurredAt": "2026-05-04T11:05:42.918Z", "reason": null}}Pix enviado devolvido (pix.payout.refunded)
Devolução parcial:
{"event": "pix.payout.refunded","data": { "payoutId": "cmor37ghi0040nxqk83df9k1m", "movementId": "cmor37ghi0044nxqkpw5lzny6", "endToEndId": "E31841474202605041107T08DEF12345", "amountCents": "250", "occurredAt": "2026-05-04T11:07:23.488Z", "refundEndToEndId": "D00416968202605041108UpxYi1K5gFV", "refundAmountCents": "100"}}Devolução total:
{"event": "pix.payout.refunded","data": { "payoutId": "cmor38jkl0050nxqkk3ce8fr1", "movementId": "cmor38jkl0054nxqkx2td8j6n", "endToEndId": "E18236120202605041109K08FGH67890", "amountCents": "5000", "occurredAt": "2026-05-04T11:09:05.612Z", "refundEndToEndId": "D31841474202605041110ZqRm2L6hHWb", "refundAmountCents": "5000"}}Cobrança paga (pix.charge.paid)
{"event": "pix.charge.paid","data": { "tag": "fatura-2026-04", "txid": "efadb53c80d04f649e77c17e3f2cc5b9", "chargeId": "cmpb9z2jr000183qk5abx20zk", "payerName": "Fulano de Tal", "endToEndId": "E18236120202605181404s07206fbc20", "movementId": "cmpba020w000382qklux6stms", "occurredAt": "2026-05-18T14:04:55.265Z", "amountCents": "10", "paymentDate": "2026-05-18T14:04:38.678Z", "payerDocument": "12345678900", "payerInstitution": "BANCO EXEMPLO S.A.", "refundEndToEndId": null, "payerInstitutionIspb": "00000000"}}Cobrança devolvida (pix.charge.refunded)
Devolução parcial:
{"event": "pix.charge.refunded","data": { "tag": "pedido-9821", "txid": "8f3b22c1d4e74d6a9e1f55a62efa7b3c", "chargeId": "cmor39mno0060nxqkzz1kr7p3", "movementId": "cmor39mno0064nxqkqo2lc8h7", "endToEndId": "E18236120202605041112s08efgh4321", "refundEndToEndId": "D31841474202605041113XyAb3M8jJYc", "amountCents": "10000", "occurredAt": "2026-05-04T11:13:18.954Z", "refundAmountCents": "2500"}}Devolução total:
{"event": "pix.charge.refunded","data": { "tag": null, "txid": "1c4a7e9f2b8d4e3a9c5f1b6d2e7a3c8f", "chargeId": "cmor3aqrs0070nxqkb1d2ef34", "movementId": "cmor3aqrs0074nxqkv4w2l5m8", "endToEndId": "E18236120202605041115z08ijkl9876", "refundEndToEndId": "D00416968202605041116KkLm4N9pPMd", "amountCents": "10000", "occurredAt": "2026-05-04T11:16:42.103Z", "refundAmountCents": "10000"}}Cobrança expirada (pix.charge.expired)
{"event": "pix.charge.expired","data": { "tag": null, "txid": "7c2bb88ca5b842369562de14254c4f2c", "chargeId": "cmor2yuob002qnxqksoxtm6sl", "occurredAt": "2026-05-04T11:08:00.669Z", "amountCents": "1000"}}TEV recebida (tev.in.received)
Enviado à conta de destino quando uma transferência interna é creditada.
endToEndId é o identificador público da TEV (36 caracteres) — o
mesmo valor que aparece em metadata.endToEndId no extrato.
feeCents é a tarifa do lado que recebe o evento.
{"event": "tev.in.received","data": { "tevTransferId": "cmoxample0001qkxyztev000", "movementId": "cmoxample0002qkxyzmvt001", "endToEndId": "8d2635e0-2c87-4b8d-ba9e-18155149ecdb", "amountCents": "1500", "feeCents": "0", "externalRef": "pedido-2026-0001", "description": "Repasse interno pedido #123", "payerAccount": "6002096", "payerBranch": "1", "beneficiaryAccount": "598375", "beneficiaryBranch": "1", "occurredAt": "2026-08-19T13:12:44.905Z"}}TEV enviada liquidou (tev.out.succeeded)
Enviado à conta de origem. Na maioria dos casos chega logo após o
POST /v1/tev retornar done; quando a criação
retornou submitted_unknown, este evento confirma a liquidação
assíncrona. movementId e feeCents são do lado da
origem (débito).
{"event": "tev.out.succeeded","data": { "tevTransferId": "cmoxample0001qkxyztev000", "movementId": "cmoxample0003qkxyzmvt002", "endToEndId": "8d2635e0-2c87-4b8d-ba9e-18155149ecdb", "amountCents": "1500", "feeCents": "0", "externalRef": "pedido-2026-0001", "description": "Repasse interno pedido #123", "payerAccount": "6002096", "payerBranch": "1", "beneficiaryAccount": "598375", "beneficiaryBranch": "1", "occurredAt": "2026-08-19T13:12:44.905Z"}}TEV enviada falhou (tev.out.failed)
Enviado à conta de origem quando a transferência é recusada — o valor e
a tarifa já voltaram ao saldo. reason traz o motivo.
{"event": "tev.out.failed","data": { "tevTransferId": "cmoxample0004qkxyztev001", "movementId": "cmoxample0005qkxyzmvt003", "endToEndId": "b41c92f7-6d10-4c2a-9e77-3fa8c05d21aa", "amountCents": "5000", "feeCents": "0", "externalRef": null, "description": null, "payerAccount": "6002096", "payerBranch": "1", "beneficiaryAccount": "598375", "beneficiaryBranch": "1", "occurredAt": "2026-08-19T13:15:02.331Z", "reason": "Insufficient balance"}}A lista de eventos de um webhook é fixada no momento do cadastro. Para receber
os eventos tev.* em um endpoint já cadastrado, registre-o
novamente incluindo os novos eventos.
Gerenciar endpoints
curl https://api.staterpay.io/v1/pix-accounts/$ACCOUNT_ID/webhooks \-H "Authorization: Bearer SUA_API_KEY"DELETE faz soft delete: retorna
{ id, enabled: false } e o registro permanece em
listagens com enabled: false. Eventos deixam de ser
entregues imediatamente.
Testando localmente
Em desenvolvimento, exponha seu servidor local com ngrok para receber callbacks da Stater. Use a URL HTTPS pública gerada no cadastro do webhook.
ngrok http <porta-do-seu-servidor>URLs do ngrok são efêmeras e não devem ser usadas em produção.
