vexorpayDocs
vexorpayDocs
APIDocumentación de vexorpayPrimeros pasosVenta de producto digitalImpuestos y Merchant of Record

Core API

Referencia de APICrear link de pago únicoCrear link de pago recurrenteListar y obtener linksSuscripcionesCheckout por compraVentas de PolarClientesDisputasSaldoRetirosEventos de reconciliaciónCuentas conectadas (marketplace)Webhooks salientesAutenticación

Recursos

vexorpay MCPEspecificación OpenAPIMigrar desde el SDK `vexor`PostmanComunidadModo sandbox

Listar y obtener links

Consulta, actualiza y cancela los links de pago de tu cuenta con filtros y paginación.

Los links eliminados nunca aparecen en los listados.

Listar

GET /api/v1/payment-links

Parámetros

ParámetroDescripción
statusFiltro: active, canceled o archived. Sin filtro se excluyen solo los eliminados.
typeFiltro: one_time o recurring. Sin filtro devuelve ambos.
limitCantidad por página (default 10, máximo 100).
starting_after / ending_beforeCursor de paginación por id.

Ejemplo

curl "https://api.vexorpay.com/api/v1/payment-links?status=active&type=one_time&limit=10" \
  -H "Authorization: Bearer vxp_live_tu_clave"

Respuesta exitosa

200 OK

{
  "data": [
    {
      "id": "66f1c1e2c8a4b0d1f2e3a4b5",
      "amountCents": 1900,
      "currency": "usd",
      "title": "Ebook UX en 30 días",
      "description": null,
      "image": "https://.../product/66f1c1e2c8a4b0d1f2e3a4c9",
      "reference": "CATALOGO-UX",
      "metadata": null,
      "status": "active",
      "slug": "a1b2c3d4e5",
      "sandbox": false,
      "type": "one_time",
      "checkoutUrl": "https://buy.polar.sh/polar_cl_...",
      "url": "https://www.vexorpay.com/p/a1b2c3d4e5",
      "createdAt": "2026-01-02T12:00:00.000Z",
      "updatedAt": "2026-01-02T12:00:00.000Z"
    }
  ],
  "has_more": false,
  "total_count": 1,
  "url": "/v1/payment-links?limit=10"
}

En un link recurring el amountCents es 0 (el precio lo definen los planes) y se agrega el array prices:

{
  "id": "66f1c1e2c8a4b0d1f2e3a4b7",
  "amountCents": 0,
  "currency": "usd",
  "type": "recurring",
  "prices": [
    {
      "id": "66f1c1e2c8a4b0d1f2e3a4c1",
      "amountCents": 900,
      "currency": "usd",
      "interval": "month",
      "intervalCount": 1,
      "trialPeriodDays": 7,
      "description": "Plan mensual",
      "isDefault": true
    }
  ]
}

Obtener un link

GET /api/v1/payment-links/{id}

El entorno lo define la API key: una clave vxp_test_... opera sobre links de prueba.

curl https://api.vexorpay.com/api/v1/payment-links/66f1c1e2c8a4b0d1f2e3a4b5 \
  -H "Authorization: Bearer vxp_live_tu_clave"

Devuelve el link completo de tu cuenta o 404 link_not_found si no existe. checkoutUrl es el checkout de Polar del link.

url es el link público para compartir: cada visita genera una referencia única para esa compra, que vuelve en reference de la venta, sus webhooks y /events. Si quieres usar tu propio id, agrega ?reference=<tu-id> (por ejemplo https://www.vexorpay.com/p/a1b2c3d4e5?reference=ORD-1001). Ver Identificar cada venta. Comparte url, no checkoutUrl: la referencia se reenvía a Polar desde url.

Métricas de un link

GET /api/v1/payment-links/{id}/stats

Las mismas métricas que ves en el detalle del link en el dashboard. Los montos van en centavos de USD y son netos: sin impuestos, sin la comisión de Polar y sin lo reembolsado. Se calculan sobre las ventas de Polar del link.

Link de pago único (type: "one_time"):

{
  "paymentLinkId": "68f1c1e2c8a4b0d1f2e3a4b5",
  "type": "one_time",
  "salesCount": 12,
  "grossCents": 66000,
  "netCents": 52740,
  "avgTicketCents": 4395,
  "customers": 11,
  "repeatCustomers": 1,
  "refunds": { "count": 1, "cents": 5000 },
  "disputes": { "count": 0, "cents": 0 },
  "topCountries": [{ "country": "US", "count": 5 }, { "country": "ES", "count": 3 }],
  "weekly": [{ "weekStart": "2026-10-20T00:00:00.000Z", "netCents": 8790, "count": 2 }]
}

Link recurrente (type: "recurring"):

{
  "paymentLinkId": "68f1c1e2c8a4b0d1f2e3a4b6",
  "type": "recurring",
  "activeSubscribers": 18,
  "mrrCents": 36000,
  "trialing": { "count": 3, "mrrCents": 6000 },
  "atRisk": { "count": 1, "mrrCents": 2000 },
  "newThisMonth": 4,
  "canceledThisMonth": 1,
  "churnRate": 0.056,
  "trialConversion": { "converted": 7, "total": 9 },
  "netThisMonthCents": 31200,
  "netTotalCents": 214500,
  "ltvCents": 9750,
  "monthly": [{ "month": "2026-10", "netCents": 31200 }]
}
  • salesCount, customers y avgTicketCents cuentan las ventas vigentes: las reembolsadas por completo van en refunds. netCents ya descuenta todos los reembolsos.
  • mrrCents cuenta sólo las suscripciones active: las que están en prueba van en trialing (MRR potencial) y las de pago fallido en atRisk.
  • churnRate = bajas del mes / suscriptores al empezar el mes (null sin base).
  • weekly trae las últimas 12 semanas y monthly los últimos 12 meses.

Si el link no existe (o es de otro modo, prueba/producción) responde 404 link_not_found.

Actualizar un link

PATCH /api/v1/payment-links/{id}

El cambio se aplica en Polar. Puedes cambiar title, description, image_file_id (null quita la foto), reference, amount (en dólares, sólo pago único) y, en cada plan de un link recurring, amount (0 = plan gratis), description y trial_period_days. El precio nuevo aplica a las compras nuevas: las suscripciones vigentes siguen con su precio. El checkoutUrl no cambia.

  • Cada plan va con su id y la lista de planes tiene que ser la misma. Agregar o quitar planes, cambiar interval/interval_count o editar un plan por asiento responde 400 polar_link_structure_change: crea un link nuevo. Sin prices, los planes quedan como están.
  • El type no se puede editar (400 validation_error). El amount no aplica a links recurrentes ni prices a links de pago único (validation_error).
  • status acepta active o archived: archived lo saca de venta en Polar, igual que DELETE. Otro valor (p. ej. canceled) responde 400 polar_field_not_supported. Un link archivado no se edita ni se reactiva (400 payment_link_inactive).
curl https://api.vexorpay.com/api/v1/payment-links/66f1c1e2c8a4b0d1f2e3a4b5 \
  -X PATCH \
  -H "Authorization: Bearer vxp_live_tu_clave" \
  -H "Content-Type: application/json" \
  -d '{
    "prices": [
      { "id": "66f1c1e2c8a4b0d1f2e3a4c1", "amount": 12, "interval": "month", "description": "Mensual" },
      { "id": "66f1c1e2c8a4b0d1f2e3a4c2", "amount": 120, "interval": "year", "trial_period_days": 7, "description": "Anual" }
    ]
  }'

Items de prices:

CampoTipoNecesarioNotas
idstringsíId del plan existente (debe pertenecer a este link).
amountnumbersíMonto por ciclo en dólares (mínimo USD 4, o 0 para un plan gratis de precio fijo). amount * 100 es el amountCents.
currencystringnoSolo usd (default).
intervalstringsíday, week, month o year.
interval_countnumbernoCada N intervalos (default 1).
trial_period_daysnumbernoTrial gratuito en días (1 a 90); ausente o null = sin trial.
descriptionstringnoLabel del plan ("Mensual", "Anual"...).
pricing_typestringnoflat (default) o per_seat.
per_seat_amountnumbernoPrecio por asiento en dólares (variante "base + extra").
min_seatsintegernoAsientos mínimos (default 1, máximo 1000).
max_seatsintegernoAsientos máximos.
seat_tiersarray | nullnoMatriz de tramos (up_to, unit_amount o flat_amount, en centavos); null la borra.
tiers_modestringnograduated o volume. Requiere seat_tiers.

Los campos de asientos son los mismos que en crear un link recurrente, pero en un link existente no se pueden cambiar (es un cambio de estructura).

Devuelve 200 con el link actualizado y sus prices.

El entorno de GET, PATCH y DELETE lo define la API key, no un parámetro del request.

Errores

ErrorHTTPCausa
validation_error400Intentaste cambiar type, mandaste prices en un link one_time, amount en un link recurring, id de un plan de otro link, un plan repetido, currency que no es USD o interval inválido.
invalid_amount400El nuevo amount es menor a USD 4.
minimum_amount400Algún plan con amount menor a USD 4.
invalid_pricing_type400pricing_type no es flat ni per_seat.
invalid_seat_tiers400Matriz seat_tiers inválida (no es lista, vacía, tramos pisos o de un plan de precio fijo).
invalid_tiers_mode400tiers_mode no es graduated ni volume, o se indicó sin seat_tiers.
invalid_interval_count400interval_count inválido (entero 1–12; year solo cada 1).
invalid_trial400trial_period_days fuera de 1–90.
prices_required400prices vacío o no es un array.
too_many_prices400Más de 5 planes.
payment_link_inactive400El link está archivado: no se edita ni se reactiva.
invalid_request400El body del PATCH está vacío.
polar_link_structure_change400Cambio de estructura (planes, intervalo o asientos). Crea un link nuevo.
polar_field_not_supported400status distinto de active o archived (p. ej. canceled, que no existe en Polar).
polar_link_not_editable_yet409El link de Polar todavía se está creando: reintenta en unos segundos.
polar_update_failed502Polar rechazó o no respondió el cambio. No se cambió nada.
link_not_found404No existe un link con ese id en tu cuenta (o es de otro modo).

Eliminar un link

DELETE /api/v1/payment-links/{id}

Alineado con la acción Eliminar del dashboard: saca el link de venta y nunca borra ventas ya realizadas.

curl -X DELETE https://api.vexorpay.com/api/v1/payment-links/66f1c1e2c8a4b0d1f2e3a4b5 \
  -H "Authorization: Bearer vxp_live_tu_clave"
SituaciónHTTPRespuesta
Link activo200El link con status: "archived": sus productos se archivan en Polar y su checkoutUrl deja de funcionar. Las suscripciones vigentes siguen cobrándose en Polar hasta que se cancelen.
Link ya deleted o archived409already_processed.
No existe, es de otro usuario o de otro modo404link_not_found.

Para que dejen de cobrarse las suscripciones de un link archivado, cancela cada una con POST /api/v1/subscriptions/{id}/cancel.

{
  "id": "66f1c1e2c8a4b0d1f2e3a4b5",
  "amountCents": 499,
  "currency": "usd",
  "title": "Pack de presets",
  "description": null,
  "image": null,
  "reference": null,
  "metadata": {},
  "status": "archived",
  "slug": "a1b2c3d4e5",
  "sandbox": false,
  "url": "https://www.vexorpay.com/p/a1b2c3d4e5",
  "type": "one_time",
  "createdAt": "2026-01-02T12:00:00.000Z",
  "updatedAt": "2026-02-02T09:30:00.000Z"
}

Errores:

ErrorHTTPCausa
already_processed409El link ya fue eliminado o archivado.
polar_archive_failed502Polar no archivó el link. Sigue activo en los dos lados: reintenta.
link_not_found404No existe un link con ese id en tu cuenta (o es de otro modo).

Crear link de pago recurrente

Crea planes por suscripción (pagos recurrentes) en dólares con la API de vexorpay.

Suscripciones

Lista, consulta, cancela y gestiona las suscripciones de tus links recurrentes.

On this page

ListarParámetrosEjemploRespuesta exitosaObtener un linkMétricas de un linkActualizar un linkErroresEliminar un link