# Retiros

Consulta tus retiros y retira tu saldo de Polar a tu cuenta de cobro.

> [!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 sobre Polar (Merchant of Record), sin SDK oficial**. Migración: <https://developers.vexorpay.com/docs/migracion-desde-el-sdk>

Fuente: <https://developers.whop.vexorpay.com/docs/api/payouts>

`GET /api/v1/payouts`

Lista tus retiros de Polar, del más nuevo al más viejo: los que hiciste desde vexorpay (dashboard o API) y los que hiciste directamente en Polar. `source` dice cuál (`vexorpay` o `polar`). Se actualizan al crearlos y cada 10 minutos.

El entorno lo define la API key. Parámetros: `limit`, `starting_after` y `ending_before`.

**curl**

```bash
curl "https://api.vexorpay.com/api/v1/payouts?limit=10" \
  -H "Authorization: Bearer vxp_live_tu_clave"
```

**Node.js**

```js
const res = await fetch(
  'https://api.vexorpay.com/api/v1/payouts?limit=10',
  {
    headers: { Authorization: 'Bearer vxp_live_tu_clave' },
  },
)

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

**PHP**

```php
<?php

$client = curl_init('https://api.vexorpay.com/api/v1/payouts?limit=10');
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/payouts',
    params={'limit': '10'},
    headers={'Authorization': 'Bearer vxp_live_tu_clave'},
)
data = response.json()
```

**Go**

```go
req, _ := http.NewRequest("GET", "https://api.vexorpay.com/api/v1/payouts?limit=10", 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": "6a1d2e3f4b5c6d7e8f901234",
      "provider": "polar",
      "polarPayoutId": "4f1c2d3e-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
      "amountCents": 4462,
      "feesCents": 51,
      "grossCents": 4513,
      "currency": "usd",
      "status": "paid",
      "accountCurrency": "ars",
      "accountAmount": 6756659,
      "source": "vexorpay",
      "sandbox": false,
      "createdAt": "2026-10-31T12:00:00.000Z",
      "paidAt": "2026-11-02T09:30:00.000Z"
    }
  ],
  "has_more": false,
  "total_count": 1,
  "url": "/v1/payouts?limit=10"
}
```

`status` toma los valores `pending`, `held`, `in_transit`, `paid`, `failed` o `canceled`. `accountAmount` es lo que se acreditó en tu cuenta de cobro, en la unidad menor de `accountCurrency` (exacto).

Cuando un retiro se acredita se dispara el webhook `payout.paid`, también para los que haces directamente en Polar.

## Estimar un retiro

`GET /api/v1/payouts/estimate`

Lo que llegaría a tu cuenta de cobro si retiras ahora todo tu saldo disponible de Polar:

```json
{
  "currency": "usd",
  "grossCents": 4513,
  "feesCents": 51,
  "netCents": 4462,
  "localEstimate": {
    "currency": "ars",
    "amount": 6756659,
    "rate": 1514.26,
    "asOf": "2026-10-31T12:00:00.000Z",
    "source": "stripe_fx_quote"
  }
}
```

`feesCents` son las comisiones de retiro de Polar. `localEstimate` usa la cotización de Stripe, la misma que se aplica al retirar (`null` si tu cuenta de cobro está en USD o no hay cotización). Si el disponible no alcanza para un retiro responde `400 insufficient_balance`. Si todavía no configuraste tu cuenta de cobro en Polar responde `409 payout_account_not_ready`.

## Retirar

`POST /api/v1/payouts`

Retira **todo** tu saldo disponible de Polar a tu cuenta de cobro (Polar no acepta un monto parcial). El body va vacío.

```bash
curl -X POST "https://api.vexorpay.com/api/v1/payouts" \
  -H "Authorization: Bearer vxp_live_tu_clave" \
  -H "Idempotency-Key: retiro-2026-10-31"
```

Responde `201` con el retiro (mismo formato que en la lista, con `source: "vexorpay"`). Con la misma `Idempotency-Key`, un reintento devuelve el mismo retiro sin crear otro.

| Error | Cuándo |
| --- | --- |
| `403 insufficient_scope` | Con OAuth (apps y MCP): la conexión no tiene el permiso `payouts:write`. |
| `409 polar_not_connected` | No hay una cuenta de Polar conectada. |
| `409 polar_reconnect_required` | La conexión de Polar es anterior a este permiso: hay que reconectar Polar desde el dashboard. |
| `409 payout_account_not_ready` | La cuenta de cobro de Polar no está lista: se termina de configurar en Polar. |
| `400 insufficient_balance` | El disponible no alcanza para un retiro. |
| `409 payout_in_progress` | Ya hay un retiro creándose. |
| `502 polar_payout_failed` | Polar no procesó el retiro. |
