Skip to Content
ConceptosSesiones
View as Markdown

Sesiones

Una CheckoutSession es con lo que interactúa el comprador: un objeto con límite de tiempo, de un solo uso, que posee la URL del checkout alojado. Es la más liviana de las tres entidades centrales. La mayor parte de tu lógica trabaja con Órdenes y los Payment Intents (ver abajo).

El modelo de datos de tres entidades

CheckoutSession ← 1:1 → Order ← 1:N → PaymentIntent (comprador) (catálogo) (cada intento de pago)
EntidadPropósitoVida útil
CheckoutSessionDe cara al comprador: tiene session_key, checkout_url, TTLMinutos (por defecto 30)
OrderEstado de tu catálogo: line items, totales, reembolsosRegistro permanente
PaymentIntentUn intento de pago en una cadena/activoHoras; liquida o expira

Creas una sesión y una orden juntas (vía POST /b2b/v1/checkout-sessions/quick). Cada vez que el comprador elige un activo en la página de checkout, se abre un PaymentIntent fresco contra la cadena correcta. Si cambian de activo a mitad de checkout, el intent anterior va a EXPIRED y empieza uno nuevo.

Identificador

Una sesión se identifica por su session_key:

cst_G-SO92J7HNWkwMHEHjD4oO1Z

URL-safe, unos 24 caracteres tras el prefijo. La página de checkout alojada es https://checkout.infraio.xyz/<session_key>: trata la session key como una credencial bearer para ese único checkout.

Ciclo de vida — CheckoutSession

EstadoSignifica
ACTIVESesión creada y abierta. La URL del checkout es usable.
COMPLETEDUn PaymentIntent de esta sesión liquidó. La Order ahora es PAID (o PARTIAL_PAID si pagaron de menos).
EXPIREDexpires_at pasó sin liquidación. Cualquier Order abierta se cancela.
CANCELEDCancelación explícita: o el comprador pulsó “cancelar” o tú llamaste al endpoint de cancelación.

Los tres estados terminales son mutuamente excluyentes y finales. Se puede crear una nueva CheckoutSession contra la misma Order si quieres reintentar (p. ej., tras un pago insuficiente).

TTL

  • Por defecto: 30 minutos (configurable vía el campo expires_in al crear, en segundos).
  • Límites: No se aplica mínimo ni máximo. Elige un valor que coincida con la ventana de decisión esperada de tu comprador: menos de 60 segundos arriesga que compradores legítimos se queden sin tiempo, y una sesión que permanece abierta más de 7 días casi con certeza está abandonada.
  • Por defecto por comerciante: Puedes fijar un valor por defecto en el dashboard, pero solo POST /b2b/v1/checkout-sessions (dos pasos) lo honra. POST /b2b/v1/checkout-sessions/quick usa 30 minutos cuando se omite expires_in, independientemente del ajuste del dashboard. Para usar un valor por defecto distinto con /quick, envía expires_in en cada llamada.
  • Aplicación: Una sesión cuyo expires_at ha pasado se trata como EXPIRED aunque su estado aún no se haya actualizado, así que no dependas del valor del estado en el momento exacto de la expiración.

Pago insuficiente

Si un comprador envía menos que el importe de la sesión, el PaymentIntent aún liquida por el importe parcial y la Order transiciona a PARTIAL_PAID. La CheckoutSession se mueve a COMPLETED (un PaymentIntent liquidado), así que ya no es reutilizable.

Para aceptar el déficit como pago completo, la orden puede resolverse a PAID. Ver Conceptos → Órdenes (resolver no está disponible a través de la API; para seguir en self-serve, cobra el remanente en su lugar). Para cobrar el remanente, crea una nueva CheckoutSession contra la misma Order con el importe residual.

Sobrepago

Si el comprador envía más que el importe de la sesión (raro pero ocurre con transferencias manuales), InfraIO Pay detecta el sobrepago en 24 horas y te notifica. No se reembolsa automáticamente. Emite el reembolso vía la API de reembolso o el dashboard.

Pagos con activo equivocado

La dirección de depósito por pedido (CREATE2) se genera para una sesión, una red y un activo. Si un comprador envía un activo distinto a la dirección, el pago no se reconoce y el PaymentIntent permanece abierto hasta que la sesión expira. Soporte puede ayudar a recuperar los fondos, pero no es automático. Indica a los compradores que envíen el activo exacto mostrado en la página de checkout.

En TRON, Solana y TON no hay dirección de depósito, así que esto aplica solo a las redes EVM: el comprador paga directamente a tu wallet. Ver Redes de pago directo a la wallet.

Idempotencia al crear

POST /b2b/v1/checkout-sessions/quick acepta un campo idempotency_key en el body de la petición (nota: campo del body, no cabecera HTTP). Genera un UUID si no tienes una clave natural.

La clave deduplica la Order, no la CheckoutSession. En un reintento con la misma clave, /quick devuelve la orden original (order_id es estable) pero emite una CheckoutSession fresca: una nueva session_key y checkout_url cada vez. Eso es intencional: una Order puede respaldar varios intentos de checkout (ver Órdenes), así que un /quick reintentado entrega al comprador una sesión limpia sin duplicar la orden.

Dos comportamientos a tener en cuenta:

  • El body no se hashea ni compara. Reutilizar una clave con un body distinto no devuelve 409: el servidor devuelve silenciosamente la orden ya almacenada bajo esa clave e ignora el nuevo body. Así que trata un idempotency_key como un token de un solo uso para una sola orden lógica; nunca lo recicles entre distintos carritos.
  • Solo la Order se deduplica, no la sesión. Si necesitas la misma URL de checkout de vuelta, persiste session_key / checkout_url de la primera respuesta: llamar a /quick de nuevo no devolverá la antigua. Para enumerar cada sesión emitida contra una orden, usa GET /b2b/v1/checkout-sessions/by-order/:order_id.

Endpoints de la API

MétodoRutaNotas
POST/b2b/v1/checkout-sessions/quickCrea order + session en una llamada
POST/b2b/v1/checkout-sessionsCrea sesión contra una orden existente
GET/b2b/v1/checkout-sessions/by-order/:order_idLista todas las sesiones de una orden (para historial de reintentos)

Consulta el Inicio rápido para el body completo de la petición de creación y la firma.

Qué sigue