# Eventos de reconciliación

Consulta el histórico de eventos para reconciliar tus webhooks con la API.

> [!WARNING]
> El SDK `vexor` de npm (Stripe, MercadoPago, PayPal, Square, Talo) está **deprecado**: ya no se mantiene y no debe usarse. vexorpay es hoy una **API REST de links de pago en USD, sin SDK oficial**. Migración: <https://developers.vexorpay.com/docs/migracion-desde-el-sdk>

Fuente: <https://developers.staging.vexorpay.com/docs/api/events>

`GET /api/v1/events` — histórico de eventos de negocio para reconciliar lo que recibiste por webhook con la API.

## Cómo funciona

Cada evento tiene un **id determinístico** (`evt_...`) que es **exactamente el mismo** que se envía firmado en los webhooks salientes (header `vexorpay-Event-Id`). Por eso puedes:

1. Recibir un webhook `payment.completed` con `evt_abc`.
2. Si tienes dudas o se perdió el POST, consultar `GET /api/v1/events` y encontrar el mismo `evt_abc`.
3. Deduplicar: procesar cada `evt_` una sola vez.

El histórico trae los mismos tipos de evento que los [webhooks](/docs/api/webhooks), del más nuevo al más viejo, con el mismo `data.object` (una [venta](/docs/api/orders), una [suscripción](/docs/api/subscriptions) o una [disputa](/docs/api/disputes)).

## Request

`GET /api/v1/events`

### Parámetros

| Parámetro | Descripción |
| --- | --- |
| `type` | Filtro: `payment.completed`, `payment.refunded`, `subscription.created`, `subscription.updated`, `subscription.canceled`, `dispute.created` o `dispute.updated`. |
| `created[gte]` / `created[lte]` | Rango de fecha del evento (ISO 8601). |
| `limit` / `starting_after` / `ending_before` | Paginación por cursor por id de evento (default 10, máximo 100). |

### Ejemplo

**curl**

```bash
curl "https://api.vexorpay.com/api/v1/events?type=payment.completed&limit=5" \
  -H "Authorization: Bearer vxp_live_tu_clave"
```

**Node.js**

```js
const res = await fetch(
  'https://api.vexorpay.com/api/v1/events?type=payment.completed&limit=5',
  {
    headers: { Authorization: 'Bearer vxp_live_tu_clave' },
  },
)

const data = await res.json()
```

**PHP**

```php
<?php

$client = curl_init(
  'https://api.vexorpay.com/api/v1/events?type=payment.completed&limit=5',
);
curl_setopt_array($client, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['Authorization: Bearer vxp_live_tu_clave'],
]);

$data = json_decode(curl_exec($client), true);
```

**Python**

```python

response = requests.get(
    'https://api.vexorpay.com/api/v1/events',
    params={'type': 'payment.completed', 'limit': '5'},
    headers={'Authorization': 'Bearer vxp_live_tu_clave'},
)
data = response.json()
```

**Go**

```go
req, _ := http.NewRequest("GET", "https://api.vexorpay.com/api/v1/events?type=payment.completed&limit=5", nil)
req.Header.Set("Authorization", "Bearer vxp_live_tu_clave")

res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
```

### Respuesta exitosa

`200 OK`

```json
{
  "data": [
    {
      "id": "evt_6c2314a4fb4a408c07c2",
      "type": "payment.completed",
      "created": "2026-01-02T12:05:00.000Z",
      "sandbox": false,
      "data": {
        "object": {
          "id": "67f1c1e2c8a4b0d1f2e3a4b5",
          "paymentLinkId": "66f1c1e2c8a4b0d1f2e3a4b5",
          "subscriptionId": null,
          "checkoutId": "ch_4f8a2c9d1e7b",
          "reference": "ORD-1001",
          "metadata": null,
          "status": "paid",
          "billingReason": "one_time",
          "currency": "usd",
          "subtotalCents": 1900,
          "taxCents": 0,
          "totalCents": 1900,
          "feeCents": 190,
          "feeBreakdown": {
            "vexorpay": { "amountCents": 151, "percent": 2.7, "fixedCents": 100 },
            "extras": [
              { "type": "cross_border", "amountCents": 29, "percent": 1.5 },
              { "type": "fraud_prevention", "amountCents": 7, "percent": null },
              { "type": "authentication", "amountCents": 3, "percent": null }
            ]
          },
          "netCents": 1710,
          "refundedCents": 0,
          "refundableCents": 1900,
          "customerEmail": "cliente@mail.com",
          "customerName": "Ana Pérez",
          "productName": "Ebook UX en 30 días",
          "sandbox": false,
          "createdAt": "2026-01-02T12:05:00.000Z"
        }
      }
    }
  ],
  "has_more": false,
  "total_count": 1,
  "url": "/v1/events?limit=5"
}
```

`data.object` tiene **la misma forma** que el recurso de la API y que el payload del webhook: una venta en `payment.*`, una suscripción en `subscription.*` y una disputa en `dispute.*`. `sandbox` viene a nivel raíz y dentro del objeto.

## Errores

| Error | HTTP | Causa |
| --- | --- | --- |
| `validation_error` | 400 | `type` no es uno de los tipos de evento válidos. |
