Webhooks do Merchant
Gerencie os endpoints de webhook de um Merchant a partir do Dashboard — crie configurações, inspecione entregas e rotacione signing secrets.
Esses endpoints dão suporte à tela de webhooks do Dashboard. Uma configuração de webhook é uma URL para a qual o Tokeflow entrega eventos assinados, além do filtro de eventos e do signing secret que a governam. A partir daqui você registra endpoints, acompanha entregas e suas novas tentativas, e rotaciona o signing secret whsec_….
O signing secret é exibido apenas quando criado ou rotacionado — armazene-o imediatamente. Toda entrega é assinada; o endpoint receptor deve verificar a assinatura antes de agir. Veja Verificando assinaturas.
Esses endpoints alimentam a interface do Tokeflow Dashboard. Eles são autenticados por sessão (JWT bearer) — o token vem do login no Dashboard, não de uma chave de API sk_/pk_. As solicitações também carregam o header x-merchant-id, identificando o Merchant em contexto, e o usuário autenticado deve ser membro com acesso a ele.
Endpoints
GET/api/v1/merchant/webhooks
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Lista as configurações de webhook.
Parâmetros de consulta
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | Número da página (indexado a partir de 1). Padrão 1, mín. 1. |
limit | number | Não | Número de itens por página. Padrão 20, mín. 1, máx. 100. |
Exemplo de solicitação
curl -G https://api.tokeflow.com/api/v1/merchant/webhooks \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
--data-urlencode "page=1" \
--data-urlencode "limit=20"POST/api/v1/merchant/webhooks
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Cria uma configuração de webhook.
Campos da solicitação
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url | string | Sim | A URL para onde os eventos de webhook serão enviados. |
description | string | Não | Descrição opcional para esta configuração de webhook. |
event_filter | array | Não | Lista de tipos de evento a assinar. Se não for fornecida, todos os eventos serão enviados. |
Exemplo de solicitação
curl -X POST https://api.tokeflow.com/api/v1/merchant/webhooks \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
]
}'Exemplo de resposta — 201
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z",
"secret": "whsec_abc123def456..."
}GET/api/v1/merchant/webhooks/deliveries
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Lista todas as entregas de webhook.
Parâmetros de consulta
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | Número da página (indexado a partir de 1). Padrão 1, mín. 1. |
limit | number | Não | Número de itens por página. Padrão 20, mín. 1, máx. 100. |
status | string | Não | Filtra por status de entrega |
from | string | Não | Timestamp inicial (formato ISO 8601) - filtra entregas após este horário |
to | string | Não | Timestamp final (formato ISO 8601) - filtra entregas antes deste horário |
Exemplo de solicitação
curl -G https://api.tokeflow.com/api/v1/merchant/webhooks/deliveries \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
--data-urlencode "page=1" \
--data-urlencode "limit=20" \
--data-urlencode "status=failed" \
--data-urlencode "from=2024-01-01T00:00:00Z"DELETE/api/v1/merchant/webhooks/:id
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Exclui uma configuração de webhook.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Exemplo de solicitação
curl -X DELETE https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"GET/api/v1/merchant/webhooks/:id
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Obtém uma configuração de webhook por ID.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Exemplo de solicitação
curl https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Exemplo de resposta — 200
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"merchant": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"organization": {
"id": "obj_1a2b3c4d",
"name": "Acme Store",
"slug": "acme-store",
"status": "active",
"business_registration_number": "string",
"mcc": "string",
"country_code": "BR",
"external_reference": "string",
"phone_number": "+5511987654321",
"address_line1": "string",
"address_line2": "string",
"city": "string",
"state": "string",
"postal_code": "string",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"memberships": [
{
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"user_id": "string",
"role": "owner",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"organization": {},
"user": {}
}
],
"merchants": [
{}
],
"branding": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"organization": {},
"custom_url": "https://example.com/webhooks/tokeflow",
"site_title": "string",
"favicon": "string",
"logo_light_mode": "string",
"logo_dark_mode": "string",
"collapsible_logo_light_mode": "string",
"collapsible_logo_dark_mode": "string",
"theme_primary_color": "#1c1c1c",
"theme_secondary_color": "#1c1c1c",
"show_name_with_logo": true,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z"
}
},
"name": "Acme Store",
"slug": "acme-store",
"external_reference": "string",
"business_registration_number": "string",
"mcc": "string",
"phone_number": "+5511987654321",
"address_line1": "string",
"address_line2": "string",
"city": "string",
"state": "string",
"postal_code": "string",
"country_code": "BR",
"website": "string",
"status": "active",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"webhook_configs": [
{}
],
"memberships": [
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"user_id": "string",
"role": "owner",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"merchant": {},
"user": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"email": "jane@example.com",
"name": "Acme Store",
"auth_provider": "string",
"auth_subject_id": "string",
"password_hash": "string",
"invitation_token": "string",
"invitation_expires_at": "2026-01-15T12:30:00.000Z",
"is_active": true,
"last_login_at": "2026-01-15T12:30:00.000Z",
"must_change_password": true,
"refresh_token_hash": "string",
"failed_login_attempts": 1,
"locked_until": "2026-01-15T12:30:00.000Z",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"organization": {},
"memberships": [
{}
]
}
}
],
"customers": [
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"merchant": {},
"email": "jane@example.com",
"name": "Acme Store",
"phone": "+5511987654321",
"document_type": "12345678909",
"document_number": "12345678909",
"metadata": {},
"billing_address": {},
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"deleted_at": "2026-01-15T12:30:00.000Z"
}
]
},
"url": "https://example.com/webhooks/tokeflow",
"secret": {},
"description": "Human-readable description",
"event_filter": [
"transaction.created"
],
"is_active": true,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"deleted_at": "2026-01-15T12:30:00.000Z"
}PATCH/api/v1/merchant/webhooks/:id
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Atualiza uma configuração de webhook.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Campos da solicitação
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
url | string | Não | A URL para onde os eventos de webhook serão enviados. |
description | string | Não | Descrição opcional para esta configuração de webhook. |
event_filter | array | Não | Lista de tipos de evento a assinar. |
is_active | boolean | Não | Se esta configuração de webhook está ativa. |
Exemplo de solicitação
curl -X PATCH https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
-H "Content-Type: application/json" \
-d '{
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true
}'Exemplo de resposta — 200
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"merchant": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"organization": {
"id": "obj_1a2b3c4d",
"name": "Acme Store",
"slug": "acme-store",
"status": "active",
"business_registration_number": "string",
"mcc": "string",
"country_code": "BR",
"external_reference": "string",
"phone_number": "+5511987654321",
"address_line1": "string",
"address_line2": "string",
"city": "string",
"state": "string",
"postal_code": "string",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"memberships": [
{
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"user_id": "string",
"role": "owner",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"organization": {},
"user": {}
}
],
"merchants": [
{}
],
"branding": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"organization": {},
"custom_url": "https://example.com/webhooks/tokeflow",
"site_title": "string",
"favicon": "string",
"logo_light_mode": "string",
"logo_dark_mode": "string",
"collapsible_logo_light_mode": "string",
"collapsible_logo_dark_mode": "string",
"theme_primary_color": "#1c1c1c",
"theme_secondary_color": "#1c1c1c",
"show_name_with_logo": true,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z"
}
},
"name": "Acme Store",
"slug": "acme-store",
"external_reference": "string",
"business_registration_number": "string",
"mcc": "string",
"phone_number": "+5511987654321",
"address_line1": "string",
"address_line2": "string",
"city": "string",
"state": "string",
"postal_code": "string",
"country_code": "BR",
"website": "string",
"status": "active",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"webhook_configs": [
{}
],
"memberships": [
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"user_id": "string",
"role": "owner",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"merchant": {},
"user": {
"id": "obj_1a2b3c4d",
"organization_id": "org_4b21e7c3",
"email": "jane@example.com",
"name": "Acme Store",
"auth_provider": "string",
"auth_subject_id": "string",
"password_hash": "string",
"invitation_token": "string",
"invitation_expires_at": "2026-01-15T12:30:00.000Z",
"is_active": true,
"last_login_at": "2026-01-15T12:30:00.000Z",
"must_change_password": true,
"refresh_token_hash": "string",
"failed_login_attempts": 1,
"locked_until": "2026-01-15T12:30:00.000Z",
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"organization": {},
"memberships": [
{}
]
}
}
],
"customers": [
{
"id": "obj_1a2b3c4d",
"merchant_id": "mrc_8a3f12d9",
"merchant": {},
"email": "jane@example.com",
"name": "Acme Store",
"phone": "+5511987654321",
"document_type": "12345678909",
"document_number": "12345678909",
"metadata": {},
"billing_address": {},
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"deleted_at": "2026-01-15T12:30:00.000Z"
}
]
},
"url": "https://example.com/webhooks/tokeflow",
"secret": {},
"description": "Human-readable description",
"event_filter": [
"transaction.created"
],
"is_active": true,
"created_at": "2026-01-15T12:30:00.000Z",
"updated_at": "2026-01-15T12:30:00.000Z",
"deleted_at": "2026-01-15T12:30:00.000Z"
}GET/api/v1/merchant/webhooks/:id/deliveries
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Lista as entregas de um webhook.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Parâmetros de consulta
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
page | number | Não | Número da página (indexado a partir de 1). Padrão 1, mín. 1. |
limit | number | Não | Número de itens por página. Padrão 20, mín. 1, máx. 100. |
status | string | Não | Filtra por status de entrega |
from | string | Não | Timestamp inicial (formato ISO 8601) - filtra entregas após este horário |
to | string | Não | Timestamp final (formato ISO 8601) - filtra entregas antes deste horário |
Exemplo de solicitação
curl -G https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d/deliveries \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9" \
--data-urlencode "page=1" \
--data-urlencode "limit=20" \
--data-urlencode "status=failed" \
--data-urlencode "from=2024-01-01T00:00:00Z"POST/api/v1/merchant/webhooks/:id/deliveries/:deliveryId/resend
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Reenvia uma entrega de webhook específica.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
deliveryId | string | Sim | — |
Exemplo de solicitação
curl -X POST https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d/deliveries/123/resend \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"POST/api/v1/merchant/webhooks/:id/rotate-secret
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Rotaciona o signing secret do webhook.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Exemplo de solicitação
curl -X POST https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d/rotate-secret \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Exemplo de resposta — 201
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"merchant_id": "550e8400-e29b-41d4-a716-446655440001",
"url": "https://api.example.com/webhooks/payments",
"description": "Production payment notifications",
"event_filter": [
"transaction.authorized",
"transaction.failed",
"transaction.refunded"
],
"is_active": true,
"created_at": "2024-01-15T10:30:00.000Z",
"updated_at": "2024-01-15T10:30:00.000Z",
"last_triggered_at": "2024-01-15T10:30:00.000Z",
"secret": "whsec_abc123def456..."
}POST/api/v1/merchant/webhooks/:id/test
Auth: Dashboard session (JWT bearer). É necessário ser membro do Merchant.
Envia um evento de teste para um endpoint de webhook.
Parâmetros de caminho
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
id | string | Sim | — |
Exemplo de solicitação
curl -X POST https://api.tokeflow.com/api/v1/merchant/webhooks/obj_1a2b3c4d/test \
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…" \
-H "x-merchant-id: mrc_8a3f12d9"Erros
Os erros usam o envelope padrão. Os casos mais comuns aqui:
| HTTP | Significado |
|---|---|
400 | Parâmetros inválidos ou um estado que não permite esta operação. |
401 | Token de sessão do Dashboard ausente, expirado ou inválido. |
403 | Autenticado, mas o usuário autenticado não tem acesso a esta entidade. |
404 | O registro não existe ou não é visível para esta entidade. |