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

Referencia de API

Referencia general de la API de vexorpay: base URL, autenticación, formato, paginación, idempotencia, rate limit y errores.

Base URL

https://api.vexorpay.com/api/v1

Autenticación

Todos los endpoints requieren tu clave de API, enviada en el header Authorization:

Authorization: Bearer vxp_live_tu_clave

Aprende más en Autenticación.

Conexiones OAuth: las apps conectadas pueden autenticarse con un token OAuth (vxo_at_…) en vez de una API key. En ese caso la conexión fija el modo (sandbox o producción) y cada endpoint exige un scope: si la conexión no lo tiene, la API responde 403 insufficient_scope. Ver vexorpay MCP.

Formato de respuesta

  • Los recursos (links, ventas, suscripciones) se devuelven como objeto plano (p. ej. GET /api/v1/payment-links/{id} o GET /api/v1/orders/{id}).
  • Los listados se devuelven en un envoltorio con paginación:
{
  "data": [ { "...": "recurso" } ],
  "has_more": false,
  "total_count": 12,
  "url": "/v1/orders?limit=10"
}

Paginación

Los listados usan paginación por cursor:

ParámetroDescripción
limitCantidad por página (default 10, mínimo 1, máximo 100).
starting_afterID del último elemento de la página anterior; devuelve los siguientes.
ending_beforeID del primer elemento de la página anterior; devuelve los anteriores.

limit tiene que ser un entero entre 1 y 100: con 0, -5, 101, 2.5 o un valor no numérico la API responde 400 validation_error. En la respuesta, la url de paginación refleja el limit efectivo de esa página.

Modo sandbox

El modo lo define la API key, no el request: las claves vxp_live_... operan sobre producción y las vxp_test_... sobre datos de prueba. No existe un parámetro sandbox en los requests. Cada host solo acepta claves de su modo y una clave en el host equivocado responde 403 livemode_mismatch. Ver Modo sandbox.

Suscripción a vexorpay

Usar vexorpay en producción requiere la suscripción a vexorpay (USD 9 por mes con impuestos incluidos, con 30 días de prueba gratis al empezar). Si la suscripción de tu cuenta no está en prueba ni al día, todas las operaciones de la API y del MCP responden 402 subscription_required. Empieza la prueba o renueva la suscripción desde el dashboard. En el modo sandbox no se exige.

Idempotencia

Los POST que crean recursos aceptan el header Idempotency-Key. Si repites la misma clave con el mismo body, no se crea nada nuevo: se devuelve el recurso original (replay 200). Con la misma clave y un body distinto, recibes un error idempotency_conflict (409).

Lo aceptan la creación de links (POST /api/v1/payment-links), los reembolsos (POST /api/v1/orders/{id}/refund) y los retiros (POST /api/v1/payouts). Recomendado: usar una clave por operación (p. ej. el UUID del pedido) para no duplicar un reembolso o un retiro si el request se repite. El checkout (POST /api/v1/payment-links/{id}/checkout) no es idempotente: cada llamada crea una sesión de checkout nueva.

Cada clave se conserva 24 horas: pasado ese plazo se descarta y una clave repetida vuelve a ejecutar la operación (se crea un recurso nuevo). Si el recurso original ya no existe (p. ej. fue eliminado dentro de esas 24 horas), el replay responde 404 not_found.

Rate limit

La API tiene un límite de 100 requests por minuto por clave. Cada respuesta incluye los headers X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (también en los errores 401 y 429). Al superarlo recibes 429 Too Many Requests con Retry-After y X-RateLimit-Remaining: 0. Todas las respuestas traen además X-Request-Id (id único para cruzar con soporte) y Cache-Control: no-store.

Errores

Los errores usan el formato:

{
  "error": "invalid_amount",
  "message": "The minimum amount per charge is USD 4.",
  "detail": { "resetInSeconds": 42 }
}

detail es opcional y siempre un objeto (p. ej. resetInSeconds en un 429 o reason en un 409 polar_not_ready). Nunca contiene mensajes crudos de errores internos: esos se registran del lado del servidor.

Compatibilidad: los campos desconocidos que mandes en un body se ignoran (no validan) y no se devuelven en la respuesta. La única excepción son las keys desconocidas dentro de un plan de un link recurrente (prices[]): ahí responden 400 validation_error para que un typo no pase en silencio. Del otro lado, la API puede agregar campos nuevos a las respuestas en cualquier momento: trata los campos que no conozcas como opcionales.

errorHTTPCausa
unauthorized401Falta el header Authorization.
invalid_key401La API key es inválida o fue revocada.
insufficient_scope403La conexión (token de una app conectada) no tiene el permiso que exige este endpoint. detail.required_scope indica cuál hace falta.
livemode_mismatch403La clave y el host no coinciden en modo: diste una clave de prueba contra api.vexorpay.com (o una live contra api.sandbox.vexorpay.com).
invalid_connected_account403El header Vexor-Account apunta a una cuenta sin conexión activa de la app, o la credencial no es de una app de marketplace.
validation_error400Algún parámetro tiene un valor inválido.
invalid_request400El body es inválido o falta un dato requerido.
invalid_seats400seats fuera de los límites del plan, o seats en un plan de precio fijo.
invalid_amount400El monto no es válido o es menor a USD 4.
minimum_amount400El precio de un plan recurrente es menor a USD 4.
prices_required400Un link recurring necesita al menos un precio.
too_many_prices400Se superó el máximo de precios por link.
invalid_interval400El interval del precio no es day, week, month o year.
invalid_interval_count400El interval_count está fuera de rango.
invalid_pricing_type400pricing_type de un plan no es flat ni per_seat.
invalid_seat_tiers400La matriz seat_tiers de un plan es inválida.
invalid_tiers_mode400tiers_mode no es graduated ni volume, o viene sin seat_tiers.
invalid_trial400El trial_period_days está fuera de rango (1–90).
link_not_found404No existe ese link de pago.
subscription_not_found404No existe esa suscripción.
dispute_not_found404No existe esa disputa.
order_not_found404No existe esa venta de Polar.
customer_not_found404No existe ese cliente de Polar.
price_not_found404El price_id no es un plan de ese link (o de esa suscripción).
not_found404La Idempotency-Key apunta a un recurso que ya no existe.
dispute_not_respondable400La disputa ya está cerrada o no se puede aceptar.
account_not_connected400El creador no conectó Polar: no se pueden crear links de pago.
payment_link_inactive400El link de pago no está activo.
polar_test_key_not_supported400Una clave de prueba (vxp_test_) no puede crear links en producción.
whop_link_failed502El procesador de pagos no creó el link. Reintenta en unos minutos.
whop_reconnect_required409El procesador de pagos rechazó la operación por permisos de la cuenta de cobro: escríbenos desde soporte.
idempotency_conflict409La Idempotency-Key ya se usó con un body distinto.
polar_not_ready409La organización de Polar del creador todavía no puede cobrar (falta verificación en Polar). detail.reason explica el motivo.
polar_link_not_editable_yet409El link de Polar todavía se está creando (o su creación falló): reintenta en unos segundos.
polar_reconnect_required409La conexión con Polar es anterior al checkout por API: el creador tiene que volver a conectar Polar desde el dashboard.
polar_link_structure_change400En un link de Polar se cambian título, descripción, imagen, monto y nombre/monto/prueba de cada plan fijo. Agregar o quitar planes, cambiar intervalo o asientos exige un link nuevo.
polar_field_not_supported400El valor no aplica a un link de Polar (p. ej. status: "canceled": en Polar un link está activo o archivado).
polar_not_connected409El creador no tiene Polar conectado.
payout_account_not_ready409La cuenta de cobro de Polar del creador no está lista: hay que terminar de configurarla en Polar.
insufficient_balance400El saldo disponible de Polar no alcanza para un retiro (Polar descuenta sus comisiones de retiro).
payout_in_progress409Ya hay un retiro de Polar creándose para esa cuenta: reintenta en unos minutos.
polar_payout_failed502Polar no procesó el retiro o no respondió.
already_processed409El recurso ya fue eliminado o archivado (p. ej. un link archivado).
unsupported_plan400Un plan recurrente no se puede expresar en Polar (p. ej. una combinación de precio por asiento no soportada).
subscription_required402La suscripción a vexorpay de tu cuenta no está en prueba ni al día (solo en producción).
rate_limited429Superaste el límite de 100 requests por minuto.
polar_provisioning_failed500Polar rechazó la creación del link. No quedó nada publicado: reintentá.
polar_update_failed502Polar rechazó o no respondió la edición (link o suscripción). No se cambió nada: reintenta.
polar_archive_failed502Polar no archivó el link. Sigue activo en los dos lados: reintenta.
polar_checkout_failed502Polar no creó el checkout. Reintenta en unos minutos.
upstream_error500La operación falló de forma inesperada en Polar u otro proveedor externo. Reintenta más tarde.
unexpected_error500Error interno inesperado.

Endpoints

  • Crear link de pago único — POST /api/v1/payment-links
  • Crear link de pago recurrente — POST /api/v1/payment-links con type: "recurring"
  • Listar y gestionar links — GET /api/v1/payment-links, GET / PATCH / DELETE /api/v1/payment-links/{id}, GET /api/v1/payment-links/{id}/stats
  • Checkout por compra — POST /api/v1/payment-links/{id}/checkout
  • Ventas — GET /api/v1/orders, GET /api/v1/orders/{id}, POST /api/v1/orders/{id}/refund
  • Clientes — GET /api/v1/customers, GET /api/v1/customers/{id}
  • Disputas — GET /api/v1/disputes, GET /api/v1/disputes/{id}, POST /api/v1/disputes/{id}/accept
  • Suscripciones — GET /api/v1/subscriptions, GET /api/v1/subscriptions/{id}, PATCH /api/v1/subscriptions/{id}, POST /api/v1/subscriptions/{id}/cancel, POST /api/v1/subscriptions/{id}/portal
  • Saldo — GET /api/v1/balance
  • Retiros — GET / POST /api/v1/payouts, GET /api/v1/payouts/estimate
  • Eventos de reconciliación — GET /api/v1/events
  • Cuentas conectadas (marketplace) — Vexor-Account, GET /api/v1/connected-accounts, GET / DELETE /api/v1/connected-accounts/{id}
  • Webhooks salientes — configurar y verificar notificaciones
  • Autenticación — claves, rotación y seguridad
  • Modo sandbox — prueba tu integración sin mover dinero real

Impuestos y Merchant of Record

Qué es un Merchant of Record (MoR), en qué se diferencia de un procesador de pagos (PSP) y cómo Polar, el MoR de las ventas de vexorpay, calcula, recauda y remite el sales tax / VAT / GST. Con ejemplos con USD 100.

Crear link de pago único

Crea un link de pago único en dólares con la API de vexorpay.

On this page

Base URLAutenticaciónFormato de respuestaPaginaciónModo sandboxSuscripción a vexorpayIdempotenciaRate limitErroresEndpoints