Reanudar sesión
Las sesiones de checkout son cortas y están vinculadas al origen. Hay dos formas de retomar una compra:
- Persistencia en el navegador (
sessionStorage) — misma pestaña / dispositivo. - Recovery por link (
?resume=) — mail/SMS cuando el comprador abandona tras OTP + carrito (ideal para embeds WordPress / Elements).
Recovery por link (abandono)
Cuándo se programa
Tickean agenda recovery cuando la sesión headless tiene:
- comprador OTP-verificado, y
- carrito con ítems (o una purchase en curso).
Se refresca en cada quote / verifyOtp / createPurchase. Se cancela al completar el pago.
Link de vuelta
El mail/SMS incluye un link a la returnUrl de la sesión (en WordPress, la página del shortcode):
https://tusitio.com/checkout/?resume=ABC123
Si no hay returnUrl, se usa el builder de URL del ecommerce Tickean.
Qué hace Elements
Con checkout-js ≥ 0.2.11 y elements ≥ 0.2.22:
- Al montar
<tickean-checkout>, lee?resume=de la URL. - Llama
POST /v1/checkout/recovery/exchangecon la publishable key + origin. - Rehidrata carrito, descuento, buyer verificado, purchase/
nextActionsi aplica. - Salta al paso del wizard correspondiente (datos, pago, transferencia, etc.).
- Quita
resumede la URL conhistory.replaceStatesi el exchange fue exitoso.
No hace falta configurar el shortcode: ya envía return-url = página actual.
Controller / headless
import { createCheckoutController } from "@tickean/checkout-js";
const controller = createCheckoutController({
publishableKey: "pk_test_...",
eventSlug: "demo-festival",
returnUrl: "https://tusitio.com/checkout/",
resumeCode: new URLSearchParams(location.search).get("resume") || undefined,
});
await controller.ready;O vía cliente bajo nivel:
const recovered = await tickean.exchangeRecovery({ code: "ABC123" });
// { sessionToken, event, cart, buyer, purchase, nextAction, suggestedStep, ... }API
POST /v1/checkout/recovery/exchange
Headers:
Authorization: Bearer pk_…Originautorizado
Body:
{ "code": "ABC123" }Respuesta (resumen): sessionToken, event, cart, discountCode, buyer, buyerVerified, purchase, payment, nextAction, shoppingCartReference, phase, suggestedStep.
GET /v1/checkout/session
Recupera la sesión activa y su fase actual. Requiere:
- Encabezado
Authorization: Bearer pk_test_...(clave publicable) - Encabezado
X-Tickean-Session: <sessionToken> - Encabezado
Originautorizado
const session = await tickean.getSession();
// { sessionId, phase, buyerVerified, purchaseId?, event?, ... }Si el token expiró o fue revocado, la API responde 401 y el controller crea una sesión nueva.
Persistencia en el navegador
CheckoutController puede guardar estado no sensible en sessionStorage:
| Campo | Descripción |
|---|---|
sessionToken | Token opaco de la sesión |
eventSlug | Evento vinculado |
cart | Ítems seleccionados |
discountCode | Código aplicado |
phase | Fase al cerrar la pestaña |
buyerVerified | Si el OTP ya se completó |
purchaseId | Compra en curso (si existe) |
No se persiste PII (teléfono, email, datos de tarjeta) ni secretos de PSP.
import { createCheckoutController, createSessionStoragePersistence } from "@tickean/checkout-js";
const controller = createCheckoutController({
publishableKey: "pk_test_...",
eventSlug: "demo-festival",
persistence: createSessionStoragePersistence(),
});En React, TickeanProvider desactiva persistencia por defecto (persistence: false). El drop-in Elements en WordPress también usa persistence: false: el resume por mail/SMS reemplaza esa necesidad entre dispositivos.
Flujo de reanudación (sessionStorage)
- Al inicializar, el controller intenta reusar un
sessionTokenguardado congetSession(). - Si la reanudación falla, crea una sesión nueva.
- Rehidrata carrito, descuento y flag
buyerVerifieddesde almacenamiento local.
Durante requires_action
requires_actionSi el comprador cierra la pestaña mientras espera confirmación de pago (3DS, transferencia, widget Fintoc):
- Al volver, el controller reanuda la sesión con
getSession()(o con?resume=si llegó por mail). - Consultá
getPaymentStatus()o usáwatchPayment()para obtener elnextActionactualizado. - Montá de nuevo el widget del PSP si
nextAction.typelo requiere.
const { watchPayment, nextAction } = usePayment();
useEffect(() => {
if (phase === "requires_action") {
watchPayment({ timeoutMs: 120_000 }).catch(console.error);
}
}, [phase]);Buenas prácticas
- Preferí
sessionStoragesobrelocalStoragepara tokens de sesión. - Invalidá persistencia al completar (
completed) o fallar (failed/expired). - No confíes en el estado del navegador para totales: siempre re-cotizá con
/v1/checkout/quotetras reanudar. - Asegurá que la
returnUrldel embed sea la página donde vive el checkout (WordPress lo hace por defecto).
Ver el recorrido visual: Flujo del wizard.
Updated 11 days ago
