VipterCentral de Ajuda
Desenvolvedores

Catálogo de eventos

Os 20 tipos de evento que o Vipter envia por webhook, quando cada um dispara e o que vem em data.object, com um exemplo completo de pedido, assinatura, cliente e checkout abandonado.

Todo evento chega no mesmo envelope. O tipo está em type e no cabeçalho Vipter-Event-Type, e o objeto em data.object. Cada tipo pertence a uma família, e a família define o formato do objeto:

FamíliaTiposdata.object.object
Pedidosorder.* (5)"order"
Assinaturassubscription.* (11)"subscription"
Clientescustomer.* (2)"customer"
Checkout abandonadocheckout.* (2)"checkout_abandonment"

Regras que valem para todas as famílias:

  • Todos os campos listados nas tabelas vêm sempre no objeto. Quando não há valor, o campo vem null, nunca ausente. A exceção é o evento de teste.
  • Valores em dinheiro vêm em centavos, como número inteiro: 19700 é R$ 197,00. A moeda está no campo currency do mesmo objeto.
  • Datas dentro de data.object são texto ISO 8601. O created do envelope é outro formato: segundos Unix.
  • Os IDs dos exemplos são fictícios. Trate todo ID como texto opaco e não dependa do prefixo nem do tamanho.
  • Um endpoint recebe só os tipos marcados nele. Sem nenhum marcado, recebe todos, inclusive os tipos criados no futuro. Ignore com 2xx os tipos que o seu sistema não usa.

Pedidos

EventoQuando é enviado
order.paidO pagamento de um pedido foi aprovado: compra no checkout (cartão aprovado ou PIX pago), renovação de assinatura, upsell de um clique, venda no cartão salvo feita pelo painel, cobrança extra numa assinatura, ou pedido marcado como pago pela equipe.
order.failedA cobrança de um pedido foi recusada. Sai uma vez por pedido: novas recusas no mesmo pedido não geram outro evento.
order.refundedO pedido foi reembolsado por inteiro, pelo painel, pelo provedor ou marcado como reembolsado pela equipe.
order.partially_refundedParte do pedido foi reembolsada. Pode chegar mais de uma vez para o mesmo pedido, uma para cada reembolso parcial.
order.charged_backO comprador contestou a compra no banco do cartão (chargeback).

Detalhes que o código garante:

  • Renovações chegam como order.paid com recurrence: "subsequent" e subscription_id preenchido, além do subscription.renewed da assinatura.
  • Status manual. Quando alguém da equipe marca o pedido como pago ou reembolsado, o evento sai com status_source: "manual". Depois disso, mudanças que o provedor informar sobre esse pedido não geram eventos. Veja status manual.
  • O status do objeto é o atual. Um pedido que o Vipter só conhece depois, pela sincronização periódica, pode gerar order.paid já com outro status, como refunded. Leia status em vez de deduzir pelo tipo do evento.
  • O pedido não traz UTMs, origem da campanha nem vendedor. Esses dados ficam no painel.

O objeto order

CampoTipoConteúdo
objecttextoSempre "order".
idtextoID do pedido.
customer_idtexto ou nullID do cliente.
customer_emailtexto ou nullE-mail do comprador.
subscription_idtexto ou nullAssinatura que gerou o pedido, nas renovações e cobranças extras.
statustextopending, pre_authorized, authorized, failed, canceled, refund_pending, partially_refunded, refunded ou charged_back. Veja status de pedido.
total_amountinteiroTotal cobrado, em centavos.
currencytextoCódigo ISO 4217, como BRL.
refunded_amountinteiro ou nullTotal já devolvido, em centavos.
order_typetexto ou nullcheckout, renewal, api, trial_setup ou card_setup.
recurrencetexto ou nullnone (compra avulsa), initial (primeira cobrança de uma assinatura), subsequent (renovação) ou unscheduled.
offer_idtexto ou nullOferta do primeiro item.
payment_methodtexto ou nullcredit_card, debit_card, pix, boleto ou wallet.
provider_slugtexto ou nullProvedor que processou o pagamento, como pagarme.
paid_atdata ou nullQuando o pagamento foi aprovado.
itemslistaOs itens do pedido. Veja abaixo.
external_order_idtexto ou nullReferência externa do pedido, quando existe.
status_sourcetextomanual quando a equipe definiu o status no painel, provider nos outros casos.
created_at, updated_atdata ou nullCriação e última alteração do pedido.
downloadslistaSó em order.paid que não é renovação. Os links de download do comprador. Lista vazia quando o pedido não tem produto com arquivos.

Cada item de items traz estes campos. Trate campos a mais como opcionais:

CampoTipoConteúdo
offer_id, offer_nametexto ou nullOferta vendida.
product_id, product_nametexto ou nullProduto da oferta.
billing_cycletexto ou nullCiclo da oferta. none para venda avulsa.
quantityinteiroUnidades. Num pacote de 3, vem 3.
unit_amount, total_amountinteiroPreço por unidade e total da linha, em centavos.
currencytextoMoeda da linha.
installmentsinteiro ou nullNúmero de parcelas.
roletextoQuando existe: main para o produto principal, bump para um order bump. Um item sem role é o produto principal.
pack_labeltextoQuando existe: o nome do pacote vendido.
bump_idtextoQuando existe: o order bump que gerou a linha.

Cada entrada de downloads traz product_id, product_name, expires_at (data ou null) e files, uma lista de { "name", "url" }. Os links abrem no domínio do checkout da loja e deixam de funcionar depois de um reembolso ou chargeback. Veja arquivos para download.

Exemplo: order.paid

{
  "id": "evt_3f9a1c7e5b2d4f6a8c0e1b3d",
  "object": "event",
  "type": "order.paid",
  "created": 1790604191,
  "livemode": true,
  "api_version": "2026-09-01",
  "data": {
    "object": {
      "object": "order",
      "id": "ord_5c1e8a2b9d4f4e7a8b3c6d1e2f7a9b0c",
      "customer_id": "cus_8b2d4f6a1c3e5a7b9d0f2e4c",
      "customer_email": "ana.souza@example.com",
      "subscription_id": null,
      "status": "authorized",
      "total_amount": 19700,
      "currency": "BRL",
      "refunded_amount": null,
      "order_type": "checkout",
      "recurrence": "none",
      "offer_id": "ofr_a3454b7c008d455fbc5c3fc436c1879d",
      "payment_method": "credit_card",
      "provider_slug": "pagarme",
      "paid_at": "2026-09-28T14:03:09.000Z",
      "items": [
        {
          "offer_id": "ofr_a3454b7c008d455fbc5c3fc436c1879d",
          "offer_name": "Acesso vitalício",
          "product_id": "prd_5df6381e9a0b4c2d8e7f6a5b4c3d2e1f",
          "product_name": "Curso de Fotografia",
          "billing_cycle": "none",
          "quantity": 1,
          "unit_amount": 19700,
          "total_amount": 19700,
          "currency": "BRL",
          "installments": 1
        }
      ],
      "external_order_id": null,
      "status_source": "provider",
      "created_at": "2026-09-28T14:02:51.000Z",
      "updated_at": "2026-09-28T14:03:09.000Z",
      "downloads": [
        {
          "product_id": "prd_5df6381e9a0b4c2d8e7f6a5b4c3d2e1f",
          "product_name": "Curso de Fotografia",
          "expires_at": null,
          "files": [
            {
              "name": "Apostila.pdf",
              "url": "https://pay.vipter.com/d/EXEMPLO-TOKEN/0b7e2c4a-9d1f-4e3b-8a6c-5f2d1e0c9b8a"
            }
          ]
        }
      ]
    }
  }
}

Assinaturas

EventoQuando é enviado
subscription.createdUma assinatura foi criada, normalmente pela compra de uma oferta recorrente no checkout.
subscription.renewedA assinatura foi renovada. A cobrança da renovação chega em separado, como order.paid.
subscription.dunningA cobrança da renovação falhou e a assinatura entrou em recuperação (status: "dunning").
subscription.reactivatedA assinatura voltou a ficar ativa: saiu da recuperação de cobrança, ou foi reativada pela equipe ou pelo assinante.
subscription.upgradedO assinante mudou de plano, para um valor maior ou igual ao anterior.
subscription.downgradedO assinante mudou de plano, para um valor menor que o anterior.
subscription.payment_method_changedO cartão usado nas cobranças da assinatura foi trocado.
subscription.pausedA assinatura foi pausada.
subscription.resumedA assinatura pausada voltou a ficar ativa.
subscription.cancelledA assinatura foi cancelada.
subscription.expiredA assinatura terminou (status: "expired").

Detalhes que o código garante:

  • Mudanças feitas pela equipe no painel (cancelar, pausar, retomar, reativar, trocar de plano) e pelo assinante na área do cliente (cancelar, reativar, trocar de plano) geram o evento na hora. O aviso do provedor sobre a mesma mudança pode gerar outro evento do mesmo tipo, com outro id. Veja idempotência.
  • Agendar o cancelamento para o fim do período não gera evento no momento do agendamento. O objeto passa a ter cancel_at_period_end: true e aparece no próximo evento da assinatura.
  • Nas trocas de plano pelo painel e pela área do cliente, o Vipter compara current_amount antes e depois: maior ou igual vira subscription.upgraded, menor vira subscription.downgraded.

O objeto subscription

CampoTipoConteúdo
objecttextoSempre "subscription".
idtextoID da assinatura.
customer_id, customer_email, customer_nametexto ou nullO assinante.
statustextotrialing, active, dunning, paused, cancelled ou expired.
current_offer_id, offer_nametexto ou nullPlano atual. Muda numa troca de plano.
product_id, product_nametexto ou nullProduto do plano.
billing_cycletexto ou nulldaily, biweekly, monthly, quarterly, half_yearly, yearly ou custom.
currencytexto ou nullMoeda das cobranças.
current_amountinteiro ou nullValor de cada cobrança, em centavos.
current_period_start, current_period_enddata ou nullPeríodo pago atual.
next_billing_atdata ou nullPróxima cobrança.
trial_start, trial_enddata ou nullPeríodo de teste grátis, quando houve.
cycles_completedinteiro ou nullCiclos já cobrados.
cycle_limitinteiro ou nullNúmero máximo de ciclos, ou null se não há limite.
cancel_at_period_endbooleano ou nulltrue quando o cancelamento está agendado para o fim do período.
cancelled_atdata ou nullQuando a assinatura foi cancelada.
cancellation_reasontexto ou nullMotivo informado no cancelamento.
payment_instrument_idtexto ou nullID do cartão salvo usado nas cobranças.
created_at, updated_atdata ou nullCriação e última alteração da assinatura.

Exemplo: subscription.renewed

{
  "id": "evt_7d0b2e4f6a8c1e3b5d7f9a0c",
  "object": "event",
  "type": "subscription.renewed",
  "created": 1790611502,
  "livemode": true,
  "api_version": "2026-09-01",
  "data": {
    "object": {
      "object": "subscription",
      "id": "sub_23e6db9f0a1b4c5d8e7f6a5b4c3d2e1f",
      "customer_id": "cus_8b2d4f6a1c3e5a7b9d0f2e4c",
      "customer_email": "ana.souza@example.com",
      "customer_name": "Ana Souza",
      "status": "active",
      "current_offer_id": "ofr_0c9b8a7f6e5d4c3b2a1f0e9d8c7b6a5f",
      "offer_name": "Plano mensal",
      "product_id": "prd_1a2b3c4d5e6f4a7b8c9d0e1f2a3b4c5d",
      "product_name": "Clube de Receitas",
      "billing_cycle": "monthly",
      "currency": "BRL",
      "current_amount": 4990,
      "current_period_start": "2026-09-28T16:05:00.000Z",
      "current_period_end": "2026-10-28T16:05:00.000Z",
      "next_billing_at": "2026-10-28T16:05:00.000Z",
      "trial_start": null,
      "trial_end": null,
      "cycles_completed": 4,
      "cycle_limit": null,
      "cancel_at_period_end": false,
      "cancelled_at": null,
      "cancellation_reason": null,
      "payment_instrument_id": "pi_4e6a8c0b2d4f6a8c0e2b4d6f",
      "created_at": "2026-05-28T16:05:00.000Z",
      "updated_at": "2026-09-28T16:05:02.000Z"
    }
  }
}

Clientes

EventoQuando é enviado
customer.createdO Vipter registrou um cliente novo: cadastrado pela equipe no painel, ou visto pela primeira vez numa assinatura ou na sincronização periódica com o provedor.
customer.updatedAlguém da equipe editou o cliente no painel. Cada vez que o formulário é salvo, sai um evento.

Não conte com customer.created para saber de cada comprador novo: ele não sai em todos os caminhos de compra. Para reagir a uma compra, use order.paid, que traz customer_id e customer_email. Mudanças que o comprador faz na área do cliente, como nome e telefone, não geram customer.updated.

O objeto customer

CampoTipoConteúdo
objecttextoSempre "customer".
idtextoID do cliente.
emailtextoE-mail.
nametexto ou nullNome.
phonetexto ou nullTelefone, como +5511987654321.
document_typetexto ou nullcpf, cnpj, passport ou tax_id. O número do documento não vem no evento.
metadataobjeto ou nullMetadados do cliente.
created_at, updated_atdata ou nullCriação e última alteração.

Exemplo: customer.created

{
  "id": "evt_1c3e5a7b9d0f2e4c6a8b0d2f",
  "object": "event",
  "type": "customer.created",
  "created": 1790604190,
  "livemode": true,
  "api_version": "2026-09-01",
  "data": {
    "object": {
      "object": "customer",
      "id": "cus_8b2d4f6a1c3e5a7b9d0f2e4c",
      "email": "ana.souza@example.com",
      "name": "Ana Souza",
      "phone": "+5511987654321",
      "document_type": "cpf",
      "metadata": null,
      "created_at": "2026-09-28T14:02:50.000Z",
      "updated_at": "2026-09-28T14:02:50.000Z"
    }
  }
}

O evento de teste

O botão Enviar evento de teste cria um customer.created com um objeto reduzido. Ele tem só estes campos e "test": true:

{
  "object": "customer",
  "id": "cust_test",
  "email": "test@example.com",
  "name": "Test Customer",
  "test": true,
  "created_at": "2026-09-28T14:10:00.000Z"
}

Descarte eventos com data.object.test === true antes de gravar qualquer coisa. Cada clique cria um evento novo, com outro id. Veja Tentativas, desativação e reenvio.

Checkout abandonado

EventoQuando é enviado
checkout.abandonedO comprador preencheu o e-mail no checkout, não tentou pagar e ficou sem atividade. O registro nasce depois de 15 minutos parado, e o evento sai 60 minutos depois do registro, se ele não comprou nesse meio-tempo. A verificação roda a cada 10 minutos, então o horário real varia. Sai uma vez por registro.
checkout.recoveredUm checkout abandonado cujo checkout.abandoned já tinha saído terminou em compra paga do mesmo comprador e do mesmo produto, até 7 dias depois do abandono.

Um cartão recusado e um PIX gerado e não pago não contam como abandono. Várias visitas do mesmo comprador ao mesmo produto viram um registro só, com session_count maior que 1. As regras completas estão em Recuperação de checkout abandonado.

O objeto checkout_abandonment

CampoTipoConteúdo
objecttextoSempre "checkout_abandonment".
idtextoID do registro de abandono. É o mesmo nos dois eventos.
customerobjetoid (null se o comprador ainda não é cliente), email, name, phone e country.
offer_id, offer_nametexto ou nullOferta do checkout.
product_id, product_nametexto ou nullProduto da oferta.
quantityinteiroUnidades: o tamanho do pacote, ou 1.
pack_labeltexto ou nullNome do pacote, quando o link era de um pacote.
amountinteiro ou nullValor do produto que o comprador viu, com o preço do pacote, antes de cupons e frete. Em centavos.
currencytexto ou nullMoeda do checkout.
localetexto ou nullIdioma em que o checkout estava, como pt.
utmobjeto ou nullOs parâmetros utm_source, utm_medium, utm_campaign, utm_content, utm_term e utm_id que vieram com o comprador.
referrertexto ou nullPágina de onde o comprador chegou.
checkout_session_idtextoSessão de checkout mais recente.
session_countinteiroQuantas visitas foram juntadas neste registro.
recovery_urltextoLink que reabre o checkout com os dados do comprador preenchidos. Veja link de recuperação.
first_seen_atdataInício da primeira visita.
abandoned_atdataQuando o abandono foi registrado.

checkout.recovered traz o mesmo objeto e mais quatro campos:

CampoTipoConteúdo
resolutiontextoSempre "recovered".
order_idtextoO pedido pago que fechou o abandono.
resolved_atdataQuando o abandono foi fechado.
recovered_by_linkbooleanotrue se o comprador abriu o recovery_url antes de comprar.

Exemplo: checkout.abandoned

{
  "id": "evt_9e1a3c5e7b9d0f2a4c6e8b0d",
  "object": "event",
  "type": "checkout.abandoned",
  "created": 1790609400,
  "livemode": true,
  "api_version": "2026-09-01",
  "data": {
    "object": {
      "object": "checkout_abandonment",
      "id": "6f1d2c3b-4a5e-4f6a-9b8c-7d6e5f4a3b2c",
      "customer": {
        "id": null,
        "email": "bruno.lima@example.com",
        "name": "Bruno Lima",
        "phone": "+5521998765432",
        "country": "BR"
      },
      "offer_id": "ofr_7b8c9d0e1f2a4b3c8d7e6f5a4b3c2d1e",
      "offer_name": "Kit 3 unidades",
      "product_id": "prd_9f8e7d6c5b4a4f3e8d2c1b0a9f8e7d6c",
      "product_name": "Chá Detox",
      "quantity": 3,
      "pack_label": "Kit com 3",
      "amount": 24900,
      "currency": "BRL",
      "locale": "pt",
      "utm": {
        "utm_source": "instagram",
        "utm_medium": "stories",
        "utm_campaign": "black-friday"
      },
      "referrer": "https://l.instagram.com/",
      "checkout_session_id": "cs_2b4d6f8a0c2e4a6b8d0f2a4c",
      "session_count": 2,
      "recovery_url": "https://pay.vipter.com/kit-cha?pack=3&rec=EXEMPLO-TOKEN",
      "first_seen_at": "2026-09-28T13:12:40.000Z",
      "abandoned_at": "2026-09-28T13:40:05.000Z"
    }
  }
}

O que fazer a seguir

Nesta página