VipterHelp Center
Developers

Event catalog

The 20 event types Vipter sends by webhook, when each one fires and what comes in data.object, with a full example of an order, a subscription, a customer and an abandoned checkout.

Every event arrives in the same envelope. The type is in type and in the Vipter-Event-Type header, and the object is in data.object. Each type belongs to a family, and the family defines the shape of the object:

FamilyTypesdata.object.object
Ordersorder.* (5)"order"
Subscriptionssubscription.* (11)"subscription"
Customerscustomer.* (2)"customer"
Abandoned checkoutcheckout.* (2)"checkout_abandonment"

Rules that apply to every family:

  • Every field listed in the tables is always present in the object. When there is no value, the field comes as null, never missing. The exception is the test event.
  • Money amounts come in cents, as an integer: 19700 is R$ 197.00. The currency is in the currency field of the same object.
  • Dates inside data.object are ISO 8601 strings. The envelope's created uses another format: Unix seconds.
  • The IDs in the examples are fictitious. Treat every ID as an opaque string and don't depend on its prefix or length.
  • An endpoint receives only the types ticked on it. With none ticked, it receives all of them, including types created in the future. Answer 2xx to ignore the types your system doesn't use.

Orders

EventWhen it is sent
order.paidAn order's payment was approved: a checkout purchase (an approved card or a paid PIX, Brazil's instant payment), a subscription renewal, a one-click upsell, a saved-card sale made from the dashboard, an extra charge on a subscription, or an order marked as paid by the team.
order.failedAn order's charge was declined. It goes out once per order: further declines on the same order don't generate another event.
order.refundedThe order was fully refunded, from the dashboard, by the provider, or marked as refunded by the team.
order.partially_refundedPart of the order was refunded. It can arrive more than once for the same order, one for each partial refund.
order.charged_backThe buyer disputed the purchase with their card's bank (chargeback).

Details the code guarantees:

  • Renewals arrive as order.paid with recurrence: "subsequent" and subscription_id filled in, in addition to the subscription's subscription.renewed.
  • Manual status. When someone on the team marks the order as paid or refunded, the event goes out with status_source: "manual". After that, changes the provider reports about that order don't generate events. See manual status.
  • The object's status is the current one. An order that Vipter only learns about later, through the periodic sync, can generate order.paid already with another status, such as refunded. Read status instead of inferring it from the event type.
  • The order doesn't include UTMs, campaign source or seller. That data stays in the dashboard.

The order object

FieldTypeContent
objectstringAlways "order".
idstringOrder ID.
customer_idstring or nullCustomer ID.
customer_emailstring or nullBuyer's e-mail.
subscription_idstring or nullSubscription that generated the order, on renewals and extra charges.
statusstringpending, pre_authorized, authorized, failed, canceled, refund_pending, partially_refunded, refunded or charged_back. See order statuses.
total_amountintegerTotal charged, in cents.
currencystringISO 4217 code, such as BRL.
refunded_amountinteger or nullTotal already refunded, in cents.
order_typestring or nullcheckout, renewal, api, trial_setup or card_setup.
recurrencestring or nullnone (one-time purchase), initial (first charge of a subscription), subsequent (renewal) or unscheduled.
offer_idstring or nullOffer of the first item.
payment_methodstring or nullcredit_card, debit_card, pix, boleto (Brazilian bank payment slip) or wallet.
provider_slugstring or nullProvider that processed the payment, such as pagarme.
paid_atdate or nullWhen the payment was approved.
itemslistThe order items. See below.
external_order_idstring or nullExternal reference for the order, when there is one.
status_sourcestringmanual when the team set the status in the dashboard, provider in all other cases.
created_at, updated_atdate or nullCreation and last change of the order.
downloadslistOnly on order.paid that is not a renewal. The buyer's download links. An empty list when the order has no product with files.

Each entry in items has these fields. Treat any extra fields as optional:

FieldTypeContent
offer_id, offer_namestring or nullOffer sold.
product_id, product_namestring or nullThe offer's product.
billing_cyclestring or nullThe offer's cycle. none for a one-time sale.
quantityintegerUnits. In a pack of 3, it is 3.
unit_amount, total_amountintegerUnit price and line total, in cents.
currencystringCurrency of the line.
installmentsinteger or nullNumber of installments.
rolestringWhen present: main for the main product, bump for an order bump. An item without role is the main product.
pack_labelstringWhen present: the name of the pack sold.
bump_idstringWhen present: the order bump that generated the line.

Each entry in downloads has product_id, product_name, expires_at (date or null) and files, a list of { "name", "url" }. The links open on the store's checkout domain and stop working after a refund or chargeback. See digital delivery.

Example: 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"
            }
          ]
        }
      ]
    }
  }
}

Subscriptions

EventWhen it is sent
subscription.createdA subscription was created, usually by the purchase of a recurring offer at checkout.
subscription.renewedThe subscription was renewed. The renewal charge arrives separately, as order.paid.
subscription.dunningThe renewal charge failed and the subscription went into dunning (status: "dunning").
subscription.reactivatedThe subscription became active again: it left dunning, or it was reactivated by the team or by the subscriber.
subscription.upgradedThe subscriber changed plans, to an amount greater than or equal to the previous one.
subscription.downgradedThe subscriber changed plans, to an amount lower than the previous one.
subscription.payment_method_changedThe card used for the subscription's charges was changed.
subscription.pausedThe subscription was paused.
subscription.resumedThe paused subscription became active again.
subscription.cancelledThe subscription was cancelled.
subscription.expiredThe subscription ended (status: "expired").

Details the code guarantees:

  • Changes made by the team in the dashboard (cancel, pause, resume, reactivate, change plan) and by the subscriber in the customer portal (cancel, reactivate, change plan) generate the event right away. The provider's notice about the same change can generate another event of the same type, with another id. See idempotency.
  • Scheduling the cancellation for the end of the period doesn't generate an event when it is scheduled. The object gets cancel_at_period_end: true, which shows up in the subscription's next event.
  • On plan changes from the dashboard and the customer portal, Vipter compares current_amount before and after: greater or equal becomes subscription.upgraded, lower becomes subscription.downgraded.

The subscription object

FieldTypeContent
objectstringAlways "subscription".
idstringSubscription ID.
customer_id, customer_email, customer_namestring or nullThe subscriber.
statusstringtrialing, active, dunning, paused, cancelled or expired.
current_offer_id, offer_namestring or nullCurrent plan. It changes on a plan change.
product_id, product_namestring or nullThe plan's product.
billing_cyclestring or nulldaily, biweekly, monthly, quarterly, half_yearly, yearly or custom.
currencystring or nullCurrency of the charges.
current_amountinteger or nullAmount of each charge, in cents.
current_period_start, current_period_enddate or nullCurrent paid period.
next_billing_atdate or nullNext charge.
trial_start, trial_enddate or nullFree trial period, when there was one.
cycles_completedinteger or nullCycles already charged.
cycle_limitinteger or nullMaximum number of cycles, or null if there is no limit.
cancel_at_period_endboolean or nulltrue when the cancellation is scheduled for the end of the period.
cancelled_atdate or nullWhen the subscription was cancelled.
cancellation_reasonstring or nullReason given at cancellation.
payment_instrument_idstring or nullID of the saved card used for the charges.
created_at, updated_atdate or nullCreation and last change of the subscription.

Example: 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"
    }
  }
}

Customers

EventWhen it is sent
customer.createdVipter registered a new customer: added by the team in the dashboard, or seen for the first time in a subscription or in the periodic sync with the provider.
customer.updatedSomeone on the team edited the customer in the dashboard. Each time the form is saved, an event goes out.

Don't rely on customer.created to learn about every new buyer: it doesn't go out on every purchase path. To react to a purchase, use order.paid, which includes customer_id and customer_email. Changes the buyer makes in the customer portal, such as name and phone, don't generate customer.updated.

The customer object

FieldTypeContent
objectstringAlways "customer".
idstringCustomer ID.
emailstringE-mail.
namestring or nullName.
phonestring or nullPhone, such as +5511987654321.
document_typestring or nullcpf, cnpj, passport or tax_id. CPF and CNPJ are the Brazilian individual and company taxpayer IDs. The document number doesn't come in the event.
metadataobject or nullCustomer metadata.
created_at, updated_atdate or nullCreation and last change.

Example: 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"
    }
  }
}

The test event

The Send test event button creates a customer.created with a reduced object. It has only these fields and "test": true:

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

Discard events with data.object.test === true before storing anything. Each click creates a new event, with another id. See Retries, disabling and resending.

Abandoned checkout

EventWhen it is sent
checkout.abandonedThe buyer filled in their e-mail at checkout, did not try to pay and went idle. The record is created after 15 minutes of inactivity, and the event goes out 60 minutes after the record, if they didn't buy in the meantime. The check runs every 10 minutes, so the actual time varies. It goes out once per record.
checkout.recoveredAn abandoned checkout whose checkout.abandoned had already gone out ended in a paid purchase by the same buyer for the same product, up to 7 days after the abandonment.

A declined card and a PIX generated but not paid don't count as abandonment. Several visits by the same buyer to the same product become a single record, with session_count greater than 1. The full rules are in Abandoned checkout recovery.

The checkout_abandonment object

FieldTypeContent
objectstringAlways "checkout_abandonment".
idstringID of the abandonment record. It is the same in both events.
customerobjectid (null if the buyer is not a customer yet), email, name, phone and country.
offer_id, offer_namestring or nullOffer of the checkout.
product_id, product_namestring or nullThe offer's product.
quantityintegerUnits: the pack size, or 1.
pack_labelstring or nullName of the pack, when the link was for a pack.
amountinteger or nullAmount of the product the buyer saw, with the pack price, before coupons and shipping. In cents.
currencystring or nullCurrency of the checkout.
localestring or nullLanguage the checkout was in, such as pt.
utmobject or nullThe utm_source, utm_medium, utm_campaign, utm_content, utm_term and utm_id parameters that came with the buyer.
referrerstring or nullPage the buyer came from.
checkout_session_idstringMost recent checkout session.
session_countintegerHow many visits were merged into this record.
recovery_urlstringLink that reopens the checkout with the buyer's details filled in. See recovery link.
first_seen_atdateStart of the first visit.
abandoned_atdateWhen the abandonment was recorded.

checkout.recovered has the same object plus four fields:

FieldTypeContent
resolutionstringAlways "recovered".
order_idstringThe paid order that closed the abandonment.
resolved_atdateWhen the abandonment was closed.
recovered_by_linkbooleantrue if the buyer opened the recovery_url before buying.

Example: 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"
    }
  }
}

What to do next

On this page