# Cuentas conectadas (marketplace)

Opera en nombre de usuarios conectados a tu app con el header Vexor-Account y gestiona las conexiones.

> [!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 sobre Stripe, siempre en USD, sin SDK oficial**. Migración: <https://developers.vexorpay.com/docs/migracion-desde-el-sdk>

Fuente: <https://developers.vexorpay.com/docs/api/connected-accounts>

La API permite que una **app de marketplace** opere **en nombre de sus usuarios conectados**: crear links de pago y checkouts a su nombre, listar sus links y gestionar las conexiones. La app se autentica con su propia API key (o con un token OAuth de la app) y opera sobre el conectado mandando su id en el header `Vexor-Account`.

> Este flujo requiere que el usuario conectado haya autorizado la app (conexión activa). La creación y gestión de la app se hace desde el dashboard, no por API.

## Header `Vexor-Account`

En los endpoints que lo aceptan (`POST` / `GET /api/v1/payment-links` y `POST /api/v1/payment-links/{id}/checkout`) manda el id del usuario conectado:

```
Vexor-Account: <connected_user_id>
```

- La API valida que el dueño de la credencial tenga una **conexión activa** con ese usuario y en el **mismo modo** (prueba o producción). Si no, responde `403 invalid_connected_account`.
- La operación actúa sobre el conectado (los links y las ventas quedan a su nombre, en su organización de Polar) y se atribuye a la app.
- Sin el header, el comportamiento es el normal: la credencial opera sobre su propia cuenta.
- Con tokens OAuth de app, el header exige el scope `account:operate` (si falta, `403 insufficient_scope`).

> No hay comisión de marketplace: la venta es íntegra del usuario conectado y la cobra Polar como Merchant of Record. Un `POST /api/v1/payment-links` con `marketplace_fee` responde `400 marketplace_fee_not_supported_for_polar`.

## Cuentas conectadas

### Listar

`GET /api/v1/connected-accounts`

Lista las conexiones **activas** de la app, con paginación por cursor (`limit`, `starting_after`, `ending_before`).

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

```json
{
  "data": [
    {
      "id": "66f1c1e2c8a4b0d1f2e3a4b5",
      "connected_user_id": "66f1c1e2c8a4b0d1f2e3a4a1",
      "name": "Tienda de Ana",
      "email": "ana@ejemplo.com",
      "mode": "live",
      "scopes": ["read", "links:write", "account:operate"],
      "created_at": "2026-01-02T12:00:00.000Z",
      "revoked_at": null,
      "sandbox": false
    }
  ],
  "has_more": false,
  "total_count": 1,
  "url": "/v1/connected-accounts?limit=10"
}
```

### Obtener

`GET /api/v1/connected-accounts/{id}`

Devuelve el detalle de una conexión (activa o revocada). `404 not_found` si no existe o es de otra app o modo.

### Revocar

`DELETE /api/v1/connected-accounts/{id}`

Revoca la conexión **de forma idempotente**: revoca los tokens OAuth del conectado para esa app, borra el consentimiento y deja la conexión en `status: revoked`. Revocar una conexión ya revocada devuelve el mismo estado.

```bash
curl -X DELETE https://api.vexorpay.com/api/v1/connected-accounts/66f1c1e2c8a4b0d1f2e3a4b5 \
  -H "Authorization: Bearer vxp_live_tu_clave"
```

## Errores

| Error | HTTP | Causa |
| --- | --- | --- |
| `invalid_connected_account` | 403 | El header `Vexor-Account` apunta a una cuenta sin conexión activa de la app, o la credencial no es de una app de marketplace. |
| `insufficient_scope` | 403 | El token OAuth de la app no tiene el scope `account:operate`. |
| `not_found` | 404 | No existe esa conexión en la app. |
