Referência da API
Todas as chamadas Bearer da API de integração. Autentique com Authorization: Bearer bk_…. Campos marcados com * são obrigatórios.
Entitlements
/v1/entitlementsEntitlements de um cliente (o que ele pode usar AGORA)
Auth: Authorization: Bearer <tenant_api_key>. Lista as assinaturas do cliente (identificado por external_id OU email) que não estão canceled, cada uma com os entitlements do plano, e devolve merged_entitlements: a união das capacidades das assinaturas active, trialing e past_due (uma suspended aparece na lista mas não soma). Os entitlements vêm sempre do catálogo atual: editar o plano reflete aqui na hora. Cliente inexistente = 200 com customer_id: null (nunca 404). Informe external_id (preferido; email em query vira log). Um dos dois é obrigatório (400 sem nenhum).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| string | query | Alternativa ao external_id (evite — PII em query string/logs). | |
| external_id | string | query | O id do cliente no SEU app / SaaS (Customer.external_id). Preferido. |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| customer_id * | string? | null = cliente não encontrado |
| subscriptions * | EntitlementsSubscriptionRow[] | assinaturas não canceladas + entitlements do plano |
| merged_entitlements * | object | a UNIÃO das capacidades de active/trialing/past_due (o que aplicar) |
{
"customer_id": "string",
"subscriptions": [
{
"id": "string",
"status": "string",
"plan_id": "string",
"interval": "string",
"current_period_end": "2026-01-01T00:00:00Z",
"entitlements": {}
}
],
"merged_entitlements": {}
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Assinaturas
/v1/subscriptionsListar as assinaturas do tenant — keyset paginado
Auth: Authorization: Bearer <tenant_api_key>. TODAS as assinaturas do tenant, em lotes. Filtros opcionais: status (um ou vários por vírgula) e offer_id. Pagine até next vir null: pegue next, mande em ?after=, repita. Keyset (id ULID = cronológico), aguenta bases grandes sem degradar. Mesmo shape do webhook e do GET /v1/subscriptions/{id}, sem last_payment/tracking (omitidos nas listas). Não há POST: a assinatura nasce só no checkout.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| after | string | query | cursor da página anterior (o campo `next` da resposta) |
| limit | integer | query | tamanho da página (default 100, máx 500) |
| offer_id | string | query | filtra pela oferta (offer_01...) |
| status | string | query | filtra por status; um ou vários por vírgula (ex.: `active` ou `active,past_due`). Valor fora do conjunto conhecido ⟹ 400. |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| results * | SubscriptionPayload[] | |
| next * | string? | cursor da próxima página (null=fim) |
{
"results": [
{
"subscription_id": "string",
"status": "string",
"customer": {
"id": "string",
"email": "string",
"external_id": "string"
},
"plan_id": "string",
"plan_name": "string",
"interval": "string",
"current_period_end": "2026-01-01T00:00:00Z",
"cancel_at_period_end": true,
"collection_method": "string",
"payment_method": null,
"next_charge_amount_cents": 0,
"currency": "string",
"pending_offer": null,
"entitlements": {},
"last_payment": null,
"tracking": null
}
],
"next": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}Detalhe de UMA assinatura (estado atual, qualquer status)
Auth: Authorization: Bearer <tenant_api_key>. O estado ATUAL da assinatura por id — em QUALQUER status (canceled/suspended inclusive), para o sistema reconciliar quando perde um webhook. Mesmo shape do webhook (subscription_event_payload). O receptor decide por status, nunca pela presença de entitlements. 404 se é de outro tenant ou não existe (indistinguíveis por design).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id * | string | sub_… |
| status * | string | trialing | active | past_due | suspended | canceled | pending_first_payment |
| customer * | SubCustomer | |
| plan_id * | string | identificador oficial do plano (plan_…) |
| plan_name * | string | nome do plano, só para exibição |
| interval * | string | month | year |
| current_period_end * | string? (date-time) | null no trial |
| cancel_at_period_end * | boolean | true = a assinatura será cancelada no fim do ciclo (não renova) |
| collection_method * | string | card_auto | pix_manual |
| payment_method * | any | null em Pix/sem cartão |
| next_charge_amount_cents * | integer | valor do próximo ciclo, em centavos |
| currency * | string | |
| pending_offer * | any | troca agendada, se houver |
| entitlements * | object | capacidades; CHEIO mesmo em suspended/canceled |
| last_payment | any | o pagamento liquidado; null sem cobrança. Omitido nas listas |
| tracking | any | atribuição do link; null sem contexto. Omitido nas listas |
{
"subscription_id": "string",
"status": "string",
"customer": {
"id": "string",
"email": "string",
"external_id": "string"
},
"plan_id": "string",
"plan_name": "string",
"interval": "string",
"current_period_end": "2026-01-01T00:00:00Z",
"cancel_at_period_end": true,
"collection_method": "string",
"payment_method": null,
"next_charge_amount_cents": 0,
"currency": "string",
"pending_offer": null,
"entitlements": {},
"last_payment": null,
"tracking": null
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/cancelCancelar uma assinatura (imediato ou no fim do período)
Auth: Authorization: Bearer <tenant_api_key> com scope write (liberado mesmo com a conta em modo só leitura). Dois modos:
- Imediato (padrão): a assinatura vai para o estado TERMINAL
canceled. RECUSA (422) enquanto houver um QR Pix pagável (cancelar às cegas arriscaria o cliente pagar sobre uma assinatura terminal). Idempotente: já cancelada devolve 200. - No fim do período (
at_period_end: true): AGENDA o cancelamento — o acesso continua até o fim do período pago e o billing run não renova. É REVERSÍVEL porPOST /v1/subscriptions/{id}/cancel/undoenquanto a assinatura segue viva. Sóactive,trialingepast_dueagendam; um teste SEM cartão (sem próxima cobrança) não tem fim de período e é cancelado na hora (resposta{status: canceled}).
reason opcional (≤300) vai ao e-mail de cancelamento. 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| reason | string | motivo do cancelamento (≤300) |
| at_period_end | boolean | true = agenda o cancelamento p/ o fim do período (reversível); false/omitido = cancela imediatamente (terminal) |
Exemplo de requisição
{
"reason": "string",
"at_period_end": false
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| status | string | canceled (modo imediato) |
| ok | boolean | |
| cancel_at_period_end | boolean | true quando agendado p/ o fim do período |
| current_period_end | string? (date-time) | quando agendado: até quando o acesso continua |
{
"status": "string",
"ok": true,
"cancel_at_period_end": true,
"current_period_end": "2026-01-01T00:00:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/cancel-plan-changeCancelar uma troca de plano AGENDADA
Auth: Authorization: Bearer <tenant_api_key> com scope write. Cancela a troca de plano agendada; a assinatura volta sem pending_offer. 422 se não há troca agendada; 404 se a assinatura é de outro tenant/inexistente.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| subscription * | any | assinatura sem o pending_offer |
| plan_change * | object | resultado do cancelamento |
{
"subscription": null,
"plan_change": {}
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string |
{
"error": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/cancel/undoDesfazer um cancelamento agendado
Auth: Authorization: Bearer <tenant_api_key> com scope write. Desfaz o cancelamento AGENDADO (at_period_end) — a assinatura volta a renovar normalmente. Só vale enquanto está agendado e a assinatura segue viva (NÃO ressuscita uma já canceled, nem afeta um cancelamento imediato). Emite subscription.updated. 422 se não há cancelamento agendado; 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| ok * | boolean | |
| cancel_at_period_end * | boolean | false após desfazer |
{
"ok": true,
"cancel_at_period_end": true
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/change-planTrocar o plano de uma assinatura (upgrade/downgrade)
Auth: Authorization: Bearer <tenant_api_key> com scope write. Troca a assinatura (só active ou trialing) para a offer_id alvo (offer_01...). Mesmo intervalo: mais caro = upgrade IMEDIATO com a proração cobrada no cartão salvo; mesmo preço = troca imediata sem cobrar; mais barato = AGENDADO para o fim do período (veja pending_offer). Intervalo diferente: se o valor anualizado sobe, a troca é imediata (mensal para anual cobra o anual menos o crédito do período; anual para mensal vira tempo de crédito, sem cobrar); se cai ou empata, é agendada. Trocas que cobram exigem cartão salvo: numa assinatura Pix elas são agendadas. Proração abaixo do mínimo do gateway: a troca é aplicada sem cobrar. Oferta de outro gateway: gera um link de pagamento no gateway novo (o cartão salvo não atravessa gateways). 400 sem offer_id; 404 se a sub ou a oferta são de outro tenant/inexistentes; 422 se a troca é inválida ({"error": "..."}).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| offer_id * | string | o id da oferta ALVO (offer_01...) |
| keep_coupon | boolean | leva o cupom ativo para a nova oferta (default: false) |
Exemplo de requisição
{
"offer_id": "string",
"keep_coupon": false
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| subscription * | any | a assinatura já atualizada |
| plan_change * | object | resultado da troca. Chaves: kind, effect, charge_cents, applies_at… |
{
"subscription": null,
"plan_change": {}
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/charge-nowCobrar agora (enfileira o billing run da assinatura)
Auth: Authorization: Bearer <tenant_api_key> com scope write. Roda AGORA o billing run desta assinatura, sem esperar a passada diária. Ele só cobra o que já VENCEU (next_billing_at no passado; numa assinatura Pix, emite o QR a partir de 3 dias antes): não antecipa um ciclo futuro, não encerra um teste antes da hora e não adianta a próxima tentativa da régua. Quando cobra, é no cartão salvo (Pix: emite o QR). Diferente do painel, que nunca cobra o cartão (gera link de pagamento), a API cobra direto. A anti-cobrança-dupla/idempotência é do próprio billing run: chamar duas vezes NÃO cobra duas vezes. Responde 202 (enfileirado; não quer dizer que houve cobrança, acompanhe pelos webhooks invoice.paid/invoice.payment_failed). 404 se é de outro tenant ou não existe. 409 se a assinatura não está numa situação cobrável (só active, trialing e past_due são; o corpo traz o status atual) ou se as renovações da conta estão pausadas.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| ok * | boolean | |
| message * | string |
{
"ok": true,
"message": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/gateway-eventsTimeline do gateway de uma assinatura (auditoria)
Auth: Authorization: Bearer <tenant_api_key>. Os eventos que o GATEWAY respondeu nas cobranças desta assinatura (aprovação/recusa/estorno/chargeback) — feature B. Sem PII nem segredo. Teto de 200 eventos (apps/gateways/queries.py); sem paginação (uma sub tem poucos eventos). 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| results * | GatewayEventRow[] |
{
"results": [
{
"id": "string",
"provider": "string",
"kind": "string",
"outcome": "string",
"code": "string",
"gateway_id": "string",
"detail_code": "string",
"http_status": 0,
"amount_cents": 0,
"created_at": "2026-01-01T00:00:00Z"
}
]
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/payment-linkLink de pagamento da fatura em aberto de uma assinatura
Auth: Authorization: Bearer <tenant_api_key>. O link público de pagamento da fatura EM ABERTO desta assinatura (feature C), para o sistema distribuir ao cliente. NUNCA expõe id de invoice/assinatura. 404 se é de outro tenant ou não existe; 409 se não há fatura em aberto ({"error": "nenhuma fatura em aberto"}).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| token * | string | token opaco (access_token da fatura, não o id) |
| url * | string | a URL pública que o cliente abre para pagar |
| amount_cents * | integer | |
| status * | string | status da fatura em aberto |
{
"token": "string",
"url": "string",
"amount_cents": 0,
"status": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/payment-method-linkGerar link de troca de forma de pagamento
Auth: Authorization: Bearer <tenant_api_key>. Gera um link OPACO que o cliente abre para trocar o CARTÃO (ou Pix↔cartão, se a oferta permitir) — SEM cobrança. Use no botão 'alterar forma de pagamento' da área de assinatura do seu app. Expira em 7 dias, SINGLE-USE. Scope write. No Asaas o cartão só é capturado na página hospedada de um pagamento: a troca para um cartão novo acontece ao pagar uma fatura. 404 se é de outro tenant ou não existe; 409 se a assinatura está canceled/pending_first_payment ou em teste sem cartão.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| token * | string | |
| url * | string? | |
| expires_at * | string (date-time) | |
| status * | string |
{
"token": "string",
"url": "string",
"expires_at": "2026-01-01T00:00:00Z",
"status": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/remove-couponRemover o cupom de uma assinatura
Auth: Authorization: Bearer <tenant_api_key> com scope write. Os ciclos FUTUROS deixam de ser descontados; o registro da venda permanece (só para de afetar a renovação). Devolve quantos resgates foram desativados. 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| removed * | integer | quantos resgates foram desativados |
{
"removed": 0
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/renewal-linkGerar link de renovação avulsa de uma assinatura
Auth: Authorization: Bearer <tenant_api_key>. Gera um link de renovação da assinatura (o cliente abre e paga, e o período é ESTENDIDO). Renova sempre a PRÓPRIA oferta da assinatura: offer_id é opcional e, se enviado, tem de ser a oferta atual (para mudar de plano use change-plan). price_cents opcional (inteiro ≥ 1; cortesia/100% off NÃO é suportada); sem ele, o preço é o do próximo ciclo já com o cupom ativo. Expira em 7 dias. Scope write. 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| offer_id | string | opcional; se enviado, a oferta ATUAL da assinatura |
| price_cents | integer | preço em centavos (≥1); default = próximo ciclo com o cupom ativo |
Exemplo de requisição
{
"offer_id": "string",
"price_cents": 0
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| token * | string | |
| url * | string? | |
| price_cents * | integer | |
| expires_at * | string (date-time) | |
| status * | string |
{
"token": "string",
"url": "string",
"price_cents": 0,
"expires_at": "2026-01-01T00:00:00Z",
"status": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/subscriptions/{subscription_id}/rescheduleReagendar a data da próxima cobrança de uma assinatura
Auth: Authorization: Bearer <tenant_api_key> com scope write. Move a próxima cobrança (= fim do ciclo atual) para next_billing_at (ISO 8601, no FUTURO). NÃO cobra — só muda QUANDO cobra; a cadência passa a seguir a nova data. Emite subscription.updated. 400 se a data é inválida (code: data_invalida) ou passada (data_passada); 404 se é de outro tenant; 422 se o status não permite (status); 409 se há uma cobrança/QR Pix em aberto neste ciclo (fatura_em_voo).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| subscription_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| next_billing_at * | string (date-time) | nova data (ISO 8601, no futuro) |
Exemplo de requisição
{
"next_billing_at": "2026-01-01T00:00:00Z"
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| subscription * | object | a assinatura já atualizada (shape do webhook) |
| next_billing_at * | string (date-time) |
{
"subscription": {},
"next_billing_at": "2026-01-01T00:00:00Z"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Clientes
/v1/customers/{external_id}Atualizar o cadastro de um cliente (nome, e-mail, telefone)
Auth: Authorization: Bearer <tenant_api_key> com scope write. Edita os campos INFORMADOS (nome/e-mail/telefone; null/ausente = não mexe) do cliente (por external_id): local + sync no gateway (e-mail, nome e telefone) + AuditLog. doc e external_id NÃO são editáveis (identidade fiscal / chave da integração). O cadastro precisa terminar com um celular válido: phone em formato internacional E.164 (ex.: +5511999999999; número brasileiro sem + vira +55). Cliente antigo sem telefone: qualquer edição exige informar um. 404 se é de outro tenant ou não existe; 422 se o e-mail é inválido/em uso, o telefone é inválido ou falta o celular.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| external_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| name | string | |
| string (email) | ||
| phone | string | celular em E.164, ex.: +5511999999999 |
Exemplo de requisição
{
"name": "string",
"email": "string",
"phone": "string"
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| name * | string | |
| email * | string | |
| phone * | string | |
| notice * | string? | sync do gateway falhou (não-fatal) |
{
"name": "string",
"email": "string",
"phone": "string",
"notice": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/customers/{external_id}/emailAtualizar o e-mail de um cliente
Auth: Authorization: Bearer <tenant_api_key> com scope write. Atualiza o e-mail do cliente (por external_id): local + sync no gateway + AuditLog (a MESMA regra do painel). 404 se é de outro tenant ou não existe; 422 se o e-mail é inválido ({"error": "..."}).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| external_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| email * | string (email) | o novo e-mail do cliente |
Exemplo de requisição
{
"email": "string"
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| email * | string | o e-mail já atualizado |
| notice * | string? | aviso não-fatal (ex.: sync do gateway) |
{
"email": "string",
"notice": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/customers/{external_id}/paymentsHistórico de pagamentos de um cliente — keyset paginado
Auth: Authorization: Bearer <tenant_api_key>. Os pagamentos do cliente (por external_id), recorrentes e avulsos, em lotes. Pagine até next vir null: pegue next, mande em ?after=, repita. Keyset (ordenado por id ULID = cronológico) — aguenta históricos longos sem degradar. 404 se o cliente não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| after | string | query | cursor da página anterior (o campo `next` da resposta) |
| external_id * | string | path | |
| limit | integer | query | tamanho da página (default 100, máx 500) |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| results * | ApiPaymentRow[] | |
| next * | string? | cursor da próxima página (null=fim) |
{
"results": [
{
"payment_id": "string",
"status": "string",
"kind": "string",
"method": "string",
"method_kind": "string",
"amount_cents": 0,
"currency": "string",
"refunded_amount_cents": 0,
"refund_in_flight": true,
"refund_reason": "string",
"failure_code": "string",
"gateway_charge_id": "string",
"provider": "string",
"card": {},
"paid_at": "2026-01-01T00:00:00Z",
"reference": {},
"customer": {}
}
],
"next": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/customers/{external_id}/subscriptionsListar as assinaturas de um cliente
Auth: Authorization: Bearer <tenant_api_key>. Todas as assinaturas do cliente (por external_id), em QUALQUER status (inclusive canceled) — o receptor decide por status, nunca pela presença de entitlements. Mesmo shape do webhook e do GET /v1/subscriptions/{id}, sem last_payment/tracking (omitidos nas listas). 404 se o cliente é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| external_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| customer_id * | string | |
| subscriptions * | SubscriptionPayload[] |
{
"customer_id": "string",
"subscriptions": [
{
"subscription_id": "string",
"status": "string",
"customer": {
"id": "string",
"email": "string",
"external_id": "string"
},
"plan_id": "string",
"plan_name": "string",
"interval": "string",
"current_period_end": "2026-01-01T00:00:00Z",
"cancel_at_period_end": true,
"collection_method": "string",
"payment_method": null,
"next_charge_amount_cents": 0,
"currency": "string",
"pending_offer": null,
"entitlements": {},
"last_payment": null,
"tracking": null
}
]
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Pagamentos
/v1/payments/{payment_id}Detalhe de um pagamento (com itens)
Auth: Authorization: Bearer <tenant_api_key>. O pagamento por id, com a decomposição em itens (plano/bump/juros) e o estado de estorno. 404 se é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| payment_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| payment_id * | string | |
| status * | string | processing | paid | failed | refunded | chargedback |
| kind * | string | recurring | one_time |
| method * | string | card | pix |
| method_kind * | string | |
| amount_cents * | integer | |
| currency * | string | |
| refunded_amount_cents * | integer | |
| refund_in_flight * | boolean | estorno commitado, ainda não reconciliado |
| refund_reason * | string | |
| failure_code * | string | motivo da recusa (ex.: insufficient_funds) |
| gateway_charge_id * | string | |
| provider * | string | pagarme | stripe | asaas |
| card * | object | {brand, last4} — NUNCA o PAN |
| paid_at * | string? (date-time) | |
| reference * | object? | {type: subscription|order, id} |
| customer * | object? | {external_id, email} |
| items * | object[] | itens da cobrança: {id, kind, amount_cents, refunded_amount_cents, refunded} |
{
"payment_id": "string",
"status": "string",
"kind": "string",
"method": "string",
"method_kind": "string",
"amount_cents": 0,
"currency": "string",
"refunded_amount_cents": 0,
"refund_in_flight": true,
"refund_reason": "string",
"failure_code": "string",
"gateway_charge_id": "string",
"provider": "string",
"card": {},
"paid_at": "2026-01-01T00:00:00Z",
"reference": {},
"customer": {},
"items": [
{}
]
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/payments/{payment_id}/refundEstornar um pagamento (total ou parcial)
Auth: Authorization: Bearer <tenant_api_key> com scope write (liberado mesmo com a conta em modo só leitura). Estorna o Payment (por id). reason é OBRIGATÓRIO (≤300). amount_cents em centavos (parcial = menor que o pago; Pix só aceita estorno TOTAL, e um segundo estorno parcial na mesma cobrança só vale nos gateways que somam estornos: Stone/Pagar.me e Stripe). revoke: subscription (cancela a assinatura) | grant (revoga a concessão do pedido) | none (só devolve o dinheiro). Se OMITIDO, o padrão é REVOGAR o acesso apropriado ao pagamento (fatura → cancela a assinatura; pedido → revoga a concessão) — mande revoke:"none" para só devolver sem revogar. Se o estorno desfizer uma extensão/renovação, o tempo concedido é REVERTIDO automaticamente. Anti-2x embutido (o serviço nunca estorna duas vezes). 404 se o pagamento é de outro tenant ou não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| payment_id * | string | path |
Corpo da requisição
| Campo | Tipo | Descrição |
|---|---|---|
| amount_cents * | integer | valor a estornar, em centavos |
| reason * | string | motivo do estorno (obrigatório, ≤300) |
| revoke | string | subscription | grant | none. Se omitido, revoga o acesso apropriado (assinatura p/ fatura, concessão p/ pedido); mande none p/ não revogar |
| confirm_runway | boolean | reenvie true quando o 422 pedir: confirma estornar uma fatura que financiou runway pré-pago |
Exemplo de requisição
{
"amount_cents": 0,
"reason": "string",
"revoke": "string",
"confirm_runway": false
}Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| level * | string | success | warning |
| message * | string |
{
"level": "string",
"message": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | |
| requires_confirmation * | string | "runway" |
{
"error": "string",
"requires_confirmation": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Pedidos
/v1/orders/{order_id}/payment-linkLink de re-acesso ao Pix de um pedido (avulso ou adiantamento)
Auth: Authorization: Bearer <tenant_api_key>. A 2ª via / re-acesso ao QR Pix de um pedido pendente — compra avulsa OU adiantamento de renovação —, para o sistema reenviar ao cliente pagar. Reusa Order.access_token; NUNCA expõe o id do pedido. 404 se é de outro tenant ou não existe; 409 se não há Pix pendente para reabrir ({"error": "pedido sem Pix pendente para reabrir"}).
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| order_id * | string | path |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| token * | string | token opaco (access_token do pedido, não o id) |
| url * | string | a URL pública que o cliente abre para pagar o Pix |
| amount_cents * | integer | |
| status * | string | status do pedido (pending) |
{
"token": "string",
"url": "string",
"amount_cents": 0,
"status": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Indicações
/v1/referrals/linkLink/código de indicação de um cliente + progresso
Auth: Authorization: Bearer <tenant_api_key>. Get-ou-create do código estável do cliente-indicador + a recompensa configurada e o progresso das indicações. Informe external_id OU email (400 sem nenhum). {active:false} se o tenant não tem programa de indicação ativo; 404 se o cliente não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| string | query | e-mail do cliente (alternativa ao external_id) | |
| external_id | string | query | id do cliente no seu app / SaaS (prefira este) |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| active * | boolean | |
| code * | string | código curto compartilhável |
| token * | string | token opaco para a URL pública |
| link * | string | URL que o cliente compartilha (/indique/<token>) |
| reward * | ReferralReward | |
| progress * | ReferralProgress |
{
"active": true,
"code": "string",
"token": "string",
"link": "string",
"reward": {
"kind": "string",
"value": 0,
"cycles": 0,
"currency": "string",
"label": "string"
},
"progress": {
"total": 0,
"qualified": 0,
"rewarded": 0,
"reverted": 0
}
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Campanhas de renovação
/v1/renewal-campaigns/{campaign_id}/linkLink de renovação de UM cliente (botão da plataforma)
Auth: Authorization: Bearer <tenant_api_key> com scope write (cria o link, um documento pagável). Devolve (cria-ou-obtém, idempotente) o link de renovação daquele cliente na campanha — use no botão 'antecipar renovação' do seu app. 400 sem external_id; 404 se a campanha não existe ou está inativa, se o cliente não existe ou se ele não está no público da campanha.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| campaign_id * | string | path | |
| external_id * | string | query | O id do cliente no SEU app / SaaS (Customer.external_id). |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| token * | string | token opaco do link (não é o id da assinatura) |
| url * | string | URL pública que o cliente abre para pagar |
| price_cents * | integer | preço já com desconto, em centavos |
| bonus_cycles * | integer | bônus de tempo (0 = sem bônus) |
| bonus_unit * | string | 'month' | 'year' | '' (herda do plano) |
| status * | string | open | pending | paid | failed | expired | revoked |
| starts_at * | string? (date-time) | início agendado da campanha (null = sem agenda; futuro ⟹ o link só é pagável a partir desta data) |
| offer_id * | string | id da oferta da assinatura |
| plan_id * | string | id do plano |
| product_id * | string | id do produto |
{
"token": "string",
"url": "string",
"price_cents": 0,
"bonus_cycles": 0,
"bonus_unit": "string",
"status": "string",
"starts_at": "2026-01-01T00:00:00Z",
"offer_id": "string",
"plan_id": "string",
"product_id": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}/v1/renewal-campaigns/{campaign_id}/linksTodos os links da campanha (lote, para e-mailar) — keyset paginado
Auth: Authorization: Bearer <tenant_api_key>. Puxa os links já gerados, em lotes. Pagine até next vir null: pegue next, mande em ?after=, repita. Keyset (não offset) — aguenta centenas de milhares sem degradar. Leitura (qualquer scope). 400 se o cursor after é inválido; 404 se a campanha não existe.
Parâmetros
| Campo | Tipo | Em | Descrição |
|---|---|---|---|
| after | string | query | cursor da página anterior (o campo `next` da resposta) |
| campaign_id * | string | path | |
| limit | integer | query | tamanho da página (default 100, máx 500) |
Respostas
| Campo | Tipo | Descrição |
|---|---|---|
| results * | RenewalCampaignLinkRow[] | |
| next * | string? | cursor da próxima página (null = fim) |
{
"results": [
{
"external_id": "string",
"customer_email": "string"
}
],
"next": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}| Campo | Tipo | Descrição |
|---|---|---|
| error * | string | mensagem legível |
| code | string | código estável, quando a rota define um |
{
"error": "string",
"code": "string"
}Eventos (webhooks)
O que a ribbo envia ao seu endpoint (POST assinado) a cada evento. Cada evento traz o envelope + o data. Para o envelope, a validação HMAC e os retries, veja o guia de Webhooks.
Assinatura
subscription.activatedAssinatura ativada
A assinatura foi ativada e o acesso liberado (após a 1ª cobrança aprovada no checkout ou a reativação de uma suspensa). Possíveis status: active | trialing. trialing quando a ativação vem de um checkout com trial (ainda sem cobrança). Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.activated",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.updatedAssinatura atualizada
Re-sync do estado atual, sem status próprio: reagendamento, troca de forma de pagamento, entitlements do plano editados (um evento por assinatura viva do plano, com o mapa novo), ou acompanhando ('companion') um evento de ciclo de vida. Possíveis status: active | past_due | suspended | canceled | trialing. É um evento de RECONCILIAÇÃO: o status reflete o estado ATUAL e pode ser QUALQUER um. Inclusive pode chegar logo após um evento de ciclo de vida (ex.: junto de subscription.canceled, com status: canceled). Trate como "releia o status e reconcilie". pending_offer vem preenchido se houver troca de plano agendada. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.updated",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.plan_changedPlano alterado
A troca de plano foi aplicada (upgrade imediato, ou a troca agendada entrou em vigor). status: active. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.plan_changed",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.plan_change_scheduledTroca de plano agendada
Uma troca de plano foi AGENDADA (downgrade ou troca de ciclo) para o fim do período. Veja pending_offer. status: active. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.plan_change_scheduled",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": {
"offer_id": "offer_01KZ9R...",
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro anual",
"interval": "year",
"amount_cents": 49900,
"effective_at": "2026-09-01T00:00:00Z"
},
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.plan_change_canceledTroca de plano cancelada
Uma troca de plano agendada foi cancelada. pending_offer volta a null. status: active. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.plan_change_canceled",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.migration_link_issuedLink de migração de gateway emitido
Uma troca AGENDADA para uma oferta de OUTRO gateway venceu: em vez de renovar no gateway antigo, foi emitido um link de pagamento no gateway novo (o cartão salvo não atravessa gateways). O cliente é avisado por e-mail; a assinatura migra quando o link é pago. status: active. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.migration_link_issued",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": {
"offer_id": "offer_01KZ9R...",
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro anual",
"interval": "year",
"amount_cents": 49900,
"effective_at": "2026-09-01T00:00:00Z"
},
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.trial_startedTrial iniciado
Um trial começou, antes de qualquer cobrança. current_period_end vem null. status: trialing. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.trial_started",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "trialing",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": null,
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": null,
"tracking": null
}
}subscription.past_dueAssinatura inadimplente
Uma cobrança falhou e a assinatura entrou em inadimplência. A régua tenta de novo em D+1, D+3, D+5 e D+9 contados do vencimento; o acesso continua até a suspensão. status: past_due. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.past_due",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "past_due",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.suspendedAssinatura suspensa
As retentativas se esgotaram (após D+9) e a assinatura foi suspensa; volta a active quando o cliente paga. entitlements continua CHEIO: decida o acesso por status. status: suspended. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.suspended",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "suspended",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}subscription.canceledAssinatura cancelada
A assinatura foi cancelada (terminal). status: canceled. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "subscription.canceled",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "canceled",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}Fatura
invoice.paidFatura paga
Uma fatura foi paga (1ª cobrança ou renovação). Mesmo shape de assinatura. Possíveis status: active | trialing. trialing se for o pagamento inicial de um checkout com trial. last_payment é o pagamento DESTA fatura; tracking traz os UTMs/click-ids (herdados da assinatura na renovação, inherited: true). Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "invoice.paid",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "active",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}invoice.payment_failedFalha no pagamento da fatura
O pagamento de uma fatura falhou. Possíveis status: past_due | suspended. past_due durante a régua de retentativas; suspended quando as retentativas se esgotam (ramo terminal). Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "invoice.payment_failed",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "past_due",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}Pedido
order.paidPedido pago
Um pedido avulso (pagamento único) foi pago. status: paid. tracking carrega os UTMs/click-ids do link de checkout; em renovação/upgrade vem herdado da assinatura (inherited: true). target_subscription_id aponta a assinatura estendida quando o order.paid é de renovação antecipada. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| order_id | string | |
| status | string | |
| customer | object | |
| plan_id | string | |
| plan_name | string | Nome do plano, só para exibição. |
| quantity | integer | |
| amount_cents | integer | |
| unit_amount_cents | integer | |
| currency | string | |
| paid_at | string (date-time) | |
| target_subscription_id | string | A assinatura que um order.paid de renovação/extensão estendeu; senão null. |
| entitlements | object | CRU: nunca multiplicado por quantity. |
| grant_days | integer | CRU: nunca multiplicado por quantity. |
| payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "order.paid",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"order_id": "ord_01J8Z9K2Q7",
"status": "paid",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pacote de créditos",
"quantity": 2,
"amount_cents": 9980,
"unit_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"target_subscription_id": null,
"entitlements": {
"credits": 100
},
"grant_days": 30,
"payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "pix",
"method_kind": "pix",
"card": null,
"amount_cents": 9980,
"paid_amount_cents": 9980,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}order.refundedPedido estornado
Um pedido avulso foi estornado. status: refunded. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| order_id | string | |
| status | string | |
| customer | object | |
| plan_id | string | |
| plan_name | string | Nome do plano, só para exibição. |
| quantity | integer | |
| amount_cents | integer | |
| unit_amount_cents | integer | |
| currency | string | |
| paid_at | string (date-time) | |
| target_subscription_id | string | A assinatura que um order.paid de renovação/extensão estendeu; senão null. |
| entitlements | object | CRU: nunca multiplicado por quantity. |
| grant_days | integer | CRU: nunca multiplicado por quantity. |
| payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "order.refunded",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"order_id": "ord_01J8Z9K2Q7",
"status": "refunded",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pacote de créditos",
"quantity": 2,
"amount_cents": 9980,
"unit_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"target_subscription_id": null,
"entitlements": {
"credits": 100
},
"grant_days": 30,
"payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "pix",
"method_kind": "pix",
"card": null,
"amount_cents": 9980,
"paid_amount_cents": 9980,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}Pagamento
payment.refundedPagamento estornado
Um pagamento foi estornado, total ou parcialmente. Pode ser de ASSINATURA (renovação ou proração de upgrade/troca) ou de PEDIDO avulso. Possíveis status: active | past_due | canceled | paid | refunded. O corpo é SubscriptionEventData (estorno de assinatura) OU OrderEventData (estorno de pedido avulso), um oneOf. Um estorno TOTAL que revoga o acesso acompanha também subscription.canceled (assinatura) ou order.refunded (pedido); um estorno parcial ou cortesia mantém a assinatura ativa (status active/past_due). Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| subscription_id | string | |
| status | any | A ÚNICA fonte de verdade sobre o acesso do cliente. |
| customer | object | |
| plan_id | string | Identificador oficial do plano. |
| plan_name | string | Nome do plano, só para exibição. |
| interval | IntervalEnum | |
| current_period_end | string (date-time) | |
| cancel_at_period_end | boolean | true = cancelamento agendado para o fim do ciclo (não renova). |
| collection_method | CollectionMethodEnum | |
| payment_method | object | Cartão mascarado (nunca o PAN) ou `null` (Pix/sem cartão). |
| next_charge_amount_cents | integer | Valor final do próximo ciclo, em centavos. |
| currency | string | |
| pending_offer | object | Troca de plano AGENDADA (downgrade/troca de ciclo), se houver. |
| entitlements | object | Capacidades do plano. Vem CHEIO mesmo em suspended/past_due/canceled: decida o acesso por `status`, não pela presença disto. |
| last_payment | object | O pagamento liquidado. No invoice.paid é o desta fatura; null sem cobrança. |
| tracking | object | UTMs/click-ids do link do checkout. null sem contexto. Em renovação/upgrade vem herdada da assinatura (inherited: true). client_ip/user_agent NÃO entram (uso interno do envio ao GTM de servidor). `params` = demais parâmetros do link, sem dados pessoais. |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "payment.refunded",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"subscription_id": "sub_01J8Z9K2Q7",
"status": "refunded",
"customer": {
"id": "cus_01J8Z9K2Q7",
"email": "cliente@empresa.com",
"external_id": "user-123"
},
"plan_id": "plan_01KZ9R...",
"plan_name": "Pro",
"interval": "month",
"current_period_end": "2026-09-01T00:00:00Z",
"cancel_at_period_end": false,
"collection_method": "card_auto",
"payment_method": {
"brand": "visa",
"last4": "4242"
},
"next_charge_amount_cents": 4990,
"currency": "brl",
"pending_offer": null,
"entitlements": {
"seats": 5,
"api": true
},
"last_payment": {
"payment_id": "pay_01J8Z9K2Q7",
"status": "paid",
"method": "card",
"method_kind": "card",
"card": {
"brand": "visa",
"last4": "4242"
},
"amount_cents": 4990,
"paid_amount_cents": 4990,
"currency": "brl",
"paid_at": "2026-08-12T14:03:11Z",
"gateway_charge_id": "ch_9vGZ",
"gateway_provider": "pagarme"
},
"tracking": {
"utm_source": "facebook",
"utm_medium": "cpc",
"utm_campaign": "lancamento-agosto",
"utm_term": null,
"utm_content": "ad-v2",
"gclid": null,
"fbclid": "IwAR2xyz",
"fbc": "fb.1.1754990000000.IwAR2xyz",
"fbp": null,
"referrer": "https://l.facebook.com/",
"landing_url": "https://pay.ribbo.app/HSHG356?utm_source=facebook&fbclid=IwAR2xyz",
"params": {
"sck": "bio-instagram"
},
"captured_at": "2026-08-12T13:58:02Z",
"inherited": false
}
}
}Indicação
referral.createdIndicação criada
Uma indicação foi criada (o indicado fez checkout com o código). Ainda não qualificada. status: pending. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| referral_id | string | |
| status | any | pending (created) → qualified → rewarded; ou reverted. |
| referrer | object | Quem indicou (o indicador). |
| referred | object | Quem foi indicado. |
| reward | object | Snapshot da recompensa desta indicação (fallback: config do programa). |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "referral.created",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"referral_id": "rfr_01J8Z9K2Q7",
"status": "pending",
"referrer": {
"id": "cus_01J8Z9AAAA",
"email": "indicador@empresa.com",
"name": "Ana"
},
"referred": {
"id": "cus_01J8Z9BBBB",
"email": "novo@empresa.com",
"name": "Bruno"
},
"reward": {
"kind": "percent_next",
"value": 20,
"cycles": 1
}
}
}referral.qualifiedIndicação qualificada
A indicação atingiu a condição de qualificação. status: qualified. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| referral_id | string | |
| status | any | pending (created) → qualified → rewarded; ou reverted. |
| referrer | object | Quem indicou (o indicador). |
| referred | object | Quem foi indicado. |
| reward | object | Snapshot da recompensa desta indicação (fallback: config do programa). |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "referral.qualified",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"referral_id": "rfr_01J8Z9K2Q7",
"status": "qualified",
"referrer": {
"id": "cus_01J8Z9AAAA",
"email": "indicador@empresa.com",
"name": "Ana"
},
"referred": {
"id": "cus_01J8Z9BBBB",
"email": "novo@empresa.com",
"name": "Bruno"
},
"reward": {
"kind": "percent_next",
"value": 20,
"cycles": 1
}
}
}referral.rewardedRecompensa de indicação concedida
A recompensa da indicação foi concedida ao indicador. status: rewarded. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| referral_id | string | |
| status | any | pending (created) → qualified → rewarded; ou reverted. |
| referrer | object | Quem indicou (o indicador). |
| referred | object | Quem foi indicado. |
| reward | object | Snapshot da recompensa desta indicação (fallback: config do programa). |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "referral.rewarded",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"referral_id": "rfr_01J8Z9K2Q7",
"status": "rewarded",
"referrer": {
"id": "cus_01J8Z9AAAA",
"email": "indicador@empresa.com",
"name": "Ana"
},
"referred": {
"id": "cus_01J8Z9BBBB",
"email": "novo@empresa.com",
"name": "Bruno"
},
"reward": {
"kind": "percent_next",
"value": 20,
"cycles": 1
}
}
}referral.revertedRecompensa de indicação revertida
A recompensa foi revertida (estorno/churn do indicado). status: reverted. Responda 2xx para confirmar; senão a ribbo re-tenta (1min → 5min → 30min → 2h → 6h → 24h; 7 tentativas).
Campos de data
| Campo | Tipo | Descrição |
|---|---|---|
| referral_id | string | |
| status | any | pending (created) → qualified → rewarded; ou reverted. |
| referrer | object | Quem indicou (o indicador). |
| referred | object | Quem foi indicado. |
| reward | object | Snapshot da recompensa desta indicação (fallback: config do programa). |
Exemplo (envelope completo)
{
"id": "evt_01J8Z9K2Q7",
"type": "referral.reverted",
"created_at": "2026-08-01T12:00:00Z",
"tenant_id": "tn_01J8Z9K2Q7",
"data": {
"referral_id": "rfr_01J8Z9K2Q7",
"status": "reverted",
"referrer": {
"id": "cus_01J8Z9AAAA",
"email": "indicador@empresa.com",
"name": "Ana"
},
"referred": {
"id": "cus_01J8Z9BBBB",
"email": "novo@empresa.com",
"name": "Bruno"
},
"reward": {
"kind": "percent_next",
"value": 20,
"cycles": 1
}
}
}