Checkout por compra
Genera un pago único (charge) y un checkout de Stripe por cada pedido.
Genera un cobro único por pedido sobre un link existente y te devuelve un checkoutUrl de Stripe listo para redirigir al cliente.
Es el caso de uso "link reutilizable que se paga N veces": cada llamada crea un cobro (charge) identificable, con referencia propia. Así cada compra de tu tienda tiene su propio charge, su propio webhook y su propio comprobante.
En un link one_time genera un cobro nuevo (charge) por cada llamada y devuelve checkoutUrl. En un link recurring crea directamente un Checkout Session de suscripción para un plan (mirá abajo): sin pasar por el selector de planes de la página pública url (/p/{slug}). Ver Suscripciones.
Request
POST /api/v1/payment-links/{id}/checkout
Headers
| Header | Valor |
|---|---|
Authorization | Bearer vxp_u_tu_clave |
Content-Type | application/json |
Idempotency-Key | opcional — una clave por pedido para evitar cobros duplicados |
Body
| Campo | Tipo | Requerido | Descripción |
|---|---|---|---|
reference | string | no | Referencia del pedido (p. ej. ORD-1001). Solo aplica a links one_time: si se repite la misma referencia mientras el cobro siga pending, se reutiliza ESE cobro. |
customer_email | string | no | Email del comprador (pre-relleno del checkout). |
metadata | object | no | Pares clave/valor libres del pedido. |
sandbox | boolean | no | Genera el cobro en modo de prueba (sandbox: true). Debe coincidir con el modo del link: un checkout sandbox solo funciona sobre un link sandbox. El cobro se ve en el dashboard de sandbox. |
price_id | string | no | Solo para links recurring: id del plan (prices[].id) al que se suscribe el comprador. Ausente = plan default (isDefault o el primero). |
Ejemplo
curl https://api.vexorpay.com/api/v1/payment-links/66f1c1e2c8a4b0d1f2e3a4b5/checkout \
-X POST \
-H "Authorization: Bearer vxp_u_tu_clave" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 8f14e45f-ceea-486d-9b5a-3f2e4b8b0d7c" \
-d '{
"reference": "ORD-1001",
"customer_email": "cliente@mail.com",
"metadata": { "userId": "u_42" }
}'Respuesta exitosa
200 OK
{
"charge": {
"id": "67f1c1e2c8a4b0d1f2e3a4b5",
"paymentLinkId": "66f1c1e2c8a4b0d1f2e3a4b5",
"reference": "ORD-1001",
"amountCents": 1900,
"currency": "usd",
"status": "pending",
"sandbox": false,
"platformFeeCents": 100,
"stripeFeeCents": null,
"netCents": null,
"customerEmail": "cliente@mail.com",
"metadata": { "userId": "u_42" },
"paidAt": null,
"createdAt": "2026-01-02T12:03:00.000Z",
"refundedCents": null,
"recoveredCents": null,
"disputeStatus": null,
"disputeOutcome": null
},
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_...",
"expiresAt": "2026-01-03T12:03:00.000Z"
}Redirigí al cliente a checkoutUrl. La sesión expira a las 24 h (expiresAt). Cuando el pago se confirma, el cobro pasa a paid, se genera el comprobante y se dispara el webhook payment.completed.
Si repetís la misma reference mientras el cobro siga pending, se reutiliza ese mismo cobro y su URL (idempotencia natural por referencia).
Links recurrentes: checkout directo a un plan
POST /api/v1/payment-links/{id}/checkout en un link recurring crea una suscripción al plan indicado con price_id (o el default si se omite) y devuelve el checkoutUrl de Stripe sin crear un charge.
curl https://api.vexorpay.com/api/v1/payment-links/66f1c1e2c8a4b0d1f2e3a4b5/checkout \
-X POST \
-H "Authorization: Bearer vxp_u_tu_clave" \
-H "Content-Type: application/json" \
-d '{ "price_id": "66f1c1e2c8a4b0d1f2e3a4c1" }'No aplica Idempotency-Key en links recurrentes (cada llamada crea una sesión nueva).
{
"price_id": "66f1c1e2c8a4b0d1f2e3a4c1",
"price": {
"id": "66f1c1e2c8a4b0d1f2e3a4c1",
"stripePriceId": "price_1P...",
"amountCents": 900,
"currency": "usd",
"interval": "month",
"intervalCount": 1,
"trialPeriodDays": null,
"description": "Mensual",
"isDefault": true
},
"checkoutUrl": "https://checkout.stripe.com/c/pay/cs_test_...",
"expiresAt": "2026-01-03T12:03:00.000Z"
}El webhook subscription.created/invoice.paid transfiere cada ciclo al creador el neto exacto (ver Suscripciones).
Errores
| Error | HTTP | Causa |
|---|---|---|
link_not_found | 404 | No existe ese link de pago (o es de otro modo sandbox). |
payment_link_inactive | 400 | El link no está activo. |
invalid_amount | 400 | El link one_time no cobra un monto válido (menor a USD 4). |
price_not_found | 404 | price_id no existe o no pertenece a ese link recurrente. |
prices_required | 400 | El link recurrente no tiene planes. |
account_not_ready | 400 | La cuenta Express no completó la verificación. |
idempotency_conflict | 409 | La Idempotency-Key ya se usó con un body distinto (solo links one_time). |