VipterCentro de Ayuda
Desarrolladores

Catálogo de eventos

Los 20 tipos de evento que Vipter envía por webhook, cuándo se dispara cada uno y lo que viene en data.object, con un ejemplo completo de pedido, suscripción, cliente y checkout abandonado.

Todo evento llega en el mismo sobre. El tipo está en type y en el encabezado Vipter-Event-Type, y el objeto en data.object. Cada tipo pertenece a una familia, y la familia define el formato del objeto:

FamiliaTiposdata.object.object
Pedidosorder.* (5)"order"
Suscripcionessubscription.* (11)"subscription"
Clientescustomer.* (2)"customer"
Checkout abandonadocheckout.* (2)"checkout_abandonment"

Reglas que valen para todas las familias:

  • Todos los campos listados en las tablas vienen siempre en el objeto. Cuando no hay valor, el campo viene null, nunca ausente. La excepción es el evento de prueba.
  • Los montos de dinero vienen en centavos, como número entero: 19700 es R$ 197,00. La moneda está en el campo currency del mismo objeto.
  • Las fechas dentro de data.object son texto ISO 8601. El created del sobre usa otro formato: segundos Unix.
  • Los IDs de los ejemplos son ficticios. Trata todo ID como texto opaco y no dependas del prefijo ni del tamaño.
  • Un endpoint recibe solo los tipos marcados en él. Sin ninguno marcado, recibe todos, incluso los tipos que se creen en el futuro. Ignora con 2xx los tipos que tu sistema no usa.

Pedidos

EventoCuándo se envía
order.paidSe aprobó el pago de un pedido: compra en el checkout (tarjeta aprobada o PIX, el pago instantáneo de Brasil, pagado), renovación de suscripción, upsell de 1 clic, venta con la tarjeta guardada hecha desde el panel, cobro extra en una suscripción, o pedido marcado como pagado por el equipo.
order.failedSe rechazó el cobro de un pedido. Sale una vez por pedido: los nuevos rechazos en el mismo pedido no generan otro evento.
order.refundedEl pedido se reembolsó por completo, desde el panel, por el proveedor o marcado como reembolsado por el equipo.
order.partially_refundedSe reembolsó parte del pedido. Puede llegar más de una vez para el mismo pedido, una por cada reembolso parcial.
order.charged_backEl comprador disputó la compra con el banco de la tarjeta (contracargo).

Detalles que el código garantiza:

  • Las renovaciones llegan como order.paid con recurrence: "subsequent" y subscription_id completado, además del subscription.renewed de la suscripción.
  • Estado manual. Cuando alguien del equipo marca el pedido como pagado o reembolsado, el evento sale con status_source: "manual". Después de eso, los cambios que el proveedor informe sobre ese pedido no generan eventos. Consulta estado manual.
  • El estado del objeto es el actual. Un pedido que Vipter solo conoce después, por la sincronización periódica, puede generar order.paid ya con otro status, como refunded. Lee status en lugar de deducirlo por el tipo del evento.
  • El pedido no trae UTMs, origen de la campaña ni vendedor. Esos datos quedan en el panel.

El objeto order

CampoTipoContenido
objecttextoSiempre "order".
idtextoID del pedido.
customer_idtexto o nullID del cliente.
customer_emailtexto o nullCorreo del comprador.
subscription_idtexto o nullSuscripción que generó el pedido, en las renovaciones y los cobros extra.
statustextopending, pre_authorized, authorized, failed, canceled, refund_pending, partially_refunded, refunded o charged_back. Consulta estados de pedido.
total_amountenteroTotal cobrado, en centavos.
currencytextoCódigo ISO 4217, como BRL.
refunded_amountentero o nullTotal ya devuelto, en centavos.
order_typetexto o nullcheckout, renewal, api, trial_setup o card_setup.
recurrencetexto o nullnone (compra única), initial (primer cobro de una suscripción), subsequent (renovación) o unscheduled.
offer_idtexto o nullOferta del primer ítem.
payment_methodtexto o nullcredit_card, debit_card, pix, boleto (boleto bancario de Brasil) o wallet.
provider_slugtexto o nullProveedor que procesó el pago, como pagarme.
paid_atfecha o nullCuándo se aprobó el pago.
itemslistaLos ítems del pedido. Consulta abajo.
external_order_idtexto o nullReferencia externa del pedido, cuando existe.
status_sourcetextomanual cuando el equipo definió el estado en el panel, provider en los demás casos.
created_at, updated_atfecha o nullCreación y último cambio del pedido.
downloadslistaSolo en order.paid que no es renovación. Los enlaces de descarga del comprador. Lista vacía cuando el pedido no tiene productos con archivos.

Cada ítem de items trae estos campos. Trata los campos adicionales como opcionales:

CampoTipoContenido
offer_id, offer_nametexto o nullOferta vendida.
product_id, product_nametexto o nullProducto de la oferta.
billing_cycletexto o nullCiclo de la oferta. none para una venta única.
quantityenteroUnidades. En un paquete de 3, viene 3.
unit_amount, total_amountenteroPrecio por unidad y total de la línea, en centavos.
currencytextoMoneda de la línea.
installmentsentero o nullNúmero de cuotas.
roletextoCuando existe: main para el producto principal, bump para un order bump. Un ítem sin role es el producto principal.
pack_labeltextoCuando existe: el nombre del paquete vendido.
bump_idtextoCuando existe: el order bump que generó la línea.

Cada entrada de downloads trae product_id, product_name, expires_at (fecha o null) y files, una lista de { "name", "url" }. Los enlaces se abren en el dominio del checkout de la tienda y dejan de funcionar después de un reembolso o contracargo. Consulta entrega digital.

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

Suscripciones

EventoCuándo se envía
subscription.createdSe creó una suscripción, normalmente por la compra de una oferta recurrente en el checkout.
subscription.renewedSe renovó la suscripción. El cobro de la renovación llega por separado, como order.paid.
subscription.dunningEl cobro de la renovación falló y la suscripción entró en morosidad (status: "dunning").
subscription.reactivatedLa suscripción volvió a estar activa: salió de la morosidad, o la reactivó el equipo o el suscriptor.
subscription.upgradedEl suscriptor cambió de plan, a un monto mayor o igual al anterior.
subscription.downgradedEl suscriptor cambió de plan, a un monto menor que el anterior.
subscription.payment_method_changedSe cambió la tarjeta usada en los cobros de la suscripción.
subscription.pausedSe pausó la suscripción.
subscription.resumedLa suscripción pausada volvió a estar activa.
subscription.cancelledSe canceló la suscripción.
subscription.expiredLa suscripción terminó (status: "expired").

Detalles que el código garantiza:

  • Los cambios hechos por el equipo en el panel (cancelar, pausar, reanudar, reactivar, cambiar de plan) y por el suscriptor en el portal del cliente (cancelar, reactivar, cambiar de plan) generan el evento en el momento. El aviso del proveedor sobre el mismo cambio puede generar otro evento del mismo tipo, con otro id. Consulta idempotencia.
  • Programar la cancelación para el final del período no genera un evento en el momento de programarla. El objeto pasa a tener cancel_at_period_end: true, que aparece en el próximo evento de la suscripción.
  • En los cambios de plan desde el panel y desde el portal del cliente, Vipter compara current_amount antes y después: mayor o igual se convierte en subscription.upgraded, menor se convierte en subscription.downgraded.

El objeto subscription

CampoTipoContenido
objecttextoSiempre "subscription".
idtextoID de la suscripción.
customer_id, customer_email, customer_nametexto o nullEl suscriptor.
statustextotrialing, active, dunning, paused, cancelled o expired.
current_offer_id, offer_nametexto o nullPlan actual. Cambia en un cambio de plan.
product_id, product_nametexto o nullProducto del plan.
billing_cycletexto o nulldaily, biweekly, monthly, quarterly, half_yearly, yearly o custom.
currencytexto o nullMoneda de los cobros.
current_amountentero o nullMonto de cada cobro, en centavos.
current_period_start, current_period_endfecha o nullPeríodo pagado actual.
next_billing_atfecha o nullPróximo cobro.
trial_start, trial_endfecha o nullPeríodo de prueba gratis, cuando lo hubo.
cycles_completedentero o nullCiclos ya cobrados.
cycle_limitentero o nullNúmero máximo de ciclos, o null si no hay límite.
cancel_at_period_endbooleano o nulltrue cuando la cancelación está programada para el final del período.
cancelled_atfecha o nullCuándo se canceló la suscripción.
cancellation_reasontexto o nullMotivo informado en la cancelación.
payment_instrument_idtexto o nullID de la tarjeta guardada que se usa en los cobros.
created_at, updated_atfecha o nullCreación y último cambio de la suscripción.

Ejemplo: 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

EventoCuándo se envía
customer.createdVipter registró un cliente nuevo: agregado por el equipo en el panel, o visto por primera vez en una suscripción o en la sincronización periódica con el proveedor.
customer.updatedAlguien del equipo editó el cliente en el panel. Cada vez que se guarda el formulario, sale un evento.

No cuentes con customer.created para enterarte de cada comprador nuevo: no sale en todos los caminos de compra. Para reaccionar a una compra, usa order.paid, que trae customer_id y customer_email. Los cambios que el comprador hace en el portal del cliente, como el nombre y el teléfono, no generan customer.updated.

El objeto customer

CampoTipoContenido
objecttextoSiempre "customer".
idtextoID del cliente.
emailtextoCorreo.
nametexto o nullNombre.
phonetexto o nullTeléfono, como +5511987654321.
document_typetexto o nullcpf, cnpj, passport o tax_id. CPF y CNPJ son los números de contribuyente de Brasil para personas y empresas. El número del documento no viene en el evento.
metadataobjeto o nullMetadatos del cliente.
created_at, updated_atfecha o nullCreación y último cambio.

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

El evento de prueba

El botón Enviar evento de prueba crea un customer.created con un objeto reducido. Tiene solo estos campos y "test": true:

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

Descarta los eventos con data.object.test === true antes de grabar cualquier cosa. Cada clic crea un evento nuevo, con otro id. Consulta Reintentos, desactivación y reenvío.

Checkout abandonado

EventoCuándo se envía
checkout.abandonedEl comprador completó el correo en el checkout, no intentó pagar y quedó sin actividad. El registro se crea después de 15 minutos sin actividad, y el evento sale 60 minutos después del registro, si no compró en el intervalo. La verificación se ejecuta cada 10 minutos, así que el horario real varía. Sale una vez por registro.
checkout.recoveredUn checkout abandonado cuyo checkout.abandoned ya había salido terminó en una compra pagada del mismo comprador y del mismo producto, hasta 7 días después del abandono.

Una tarjeta rechazada y un PIX generado y no pagado no cuentan como abandono. Varias visitas del mismo comprador al mismo producto se convierten en un solo registro, con session_count mayor que 1. Las reglas completas están en Recuperación de checkout abandonado.

El objeto checkout_abandonment

CampoTipoContenido
objecttextoSiempre "checkout_abandonment".
idtextoID del registro de abandono. Es el mismo en los dos eventos.
customerobjetoid (null si el comprador todavía no es cliente), email, name, phone y country.
offer_id, offer_nametexto o nullOferta del checkout.
product_id, product_nametexto o nullProducto de la oferta.
quantityenteroUnidades: el tamaño del paquete, o 1.
pack_labeltexto o nullNombre del paquete, cuando el enlace era de un paquete.
amountentero o nullMonto del producto que vio el comprador, con el precio del paquete, antes de cupones y envío. En centavos.
currencytexto o nullMoneda del checkout.
localetexto o nullIdioma en que estaba el checkout, como pt.
utmobjeto o nullLos parámetros utm_source, utm_medium, utm_campaign, utm_content, utm_term y utm_id que vinieron con el comprador.
referrertexto o nullPágina desde donde llegó el comprador.
checkout_session_idtextoSesión de checkout más reciente.
session_countenteroCuántas visitas se juntaron en este registro.
recovery_urltextoEnlace que vuelve a abrir el checkout con los datos del comprador completados. Consulta enlace de recuperación.
first_seen_atfechaInicio de la primera visita.
abandoned_atfechaCuándo se registró el abandono.

checkout.recovered trae el mismo objeto y cuatro campos más:

CampoTipoContenido
resolutiontextoSiempre "recovered".
order_idtextoEl pedido pagado que cerró el abandono.
resolved_atfechaCuándo se cerró el abandono.
recovered_by_linkbooleanotrue si el comprador abrió el recovery_url antes de comprar.

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

Qué hacer después

  • Entiende los campos del sobre y cómo tratar las repeticiones.
  • Verifica la firma antes de procesar cualquier evento.

En esta página