Solución de problemas
Errores frecuentes al integrar Headless Checkout o Elements, y cómo resolverlos.
CORS y orígenes
Síntoma: Failed to fetch, checkout_origin_not_allowed, respuesta vacía en Network.
Causas:
- El
Origindel navegador no está en la allowlist de la clave publicable. - Usás
pk_live_desdehttp://localhost(solo permitido conpk_test_). - El
returnUrltiene un origen distinto al de la pestaña que creó la sesión.
Solución:
- Dashboard → Organización → Headless Checkout → agregá el origen exacto (
https://www.tusitio.com). - En local, usá
pk_test_yhttp://localhost:3000(o el puerto que corresponda). - Verificá que
returnUrlcomparta origen con la página de checkout.
OTP
Síntoma: checkout_buyer_not_verified, compra rechazada tras confirmar carrito.
Causas:
- No se llamó a
verifyOtpantes decreatePurchase. - Teléfono fuera de formato E.164 (
+54911...). - Rate limit por IP o clave (
429).
Solución:
- Flujo:
sendOtp→ usuario ingresa código →verifyOtp→ recién entonces checkout. - Normalizá el teléfono a E.164 en tu UI.
- En demo, el código
123456siempre es válido.
Quote mismatch (checkout_price_mismatch)
checkout_price_mismatch)Síntoma: Error 409 al crear la compra.
Causas:
expectedTotalno coincide con el recálculo del servidor (stock, promo o precio cambió).- Carrito desactualizado respecto a la última cotización.
- Descuento expiró o no aplica al carrito actual.
Solución:
- Siempre enviá
expectedTotalde la última respuesta de/v1/checkout/quote. - Re-cotizá antes de comprar si pasó tiempo o el usuario volvió a la pestaña.
- Mostrá el nuevo total al usuario y pedí confirmación explícita.
nextAction inesperado
nextAction inesperadoSíntoma: UI vacía tras pagar, o widget del PSP no aparece.
Causas:
- No montaste el SDK según
nextAction.type(stripe_elements,fintoc_widget, etc.). - CSP bloquea scripts o frames del proveedor (ver guía 17).
- Redirección (
redirect) interrumpida antes de volver areturnUrl.
Solución:
- Inspeccioná
payment.nextActionogetPaymentStatus().nextAction. - Seguí la tabla de la guía Estados y nextAction.
- Relajá CSP en report-only para detectar bloqueos.
Idempotencia
Síntoma: checkout_idempotency_conflict, compras duplicadas, o reintentos fallidos.
Causas:
- Misma
idempotencyKeycon body distinto. - Reintento con clave nueva cuando la compra original ya se creó.
Solución:
- Generá
idempotencyKeyuna vez por intento de compra (crypto.randomUUID()). - Reutilizá la misma clave en reintentos de red con el mismo payload.
- El controller genera claves automáticamente si no pasás una; en UI custom, guardá la clave hasta recibir respuesta definitiva.
Elements no renderiza
Síntoma: <tickean-checkout> vacío o sin estilos.
Causas:
- No importaste
@tickean/checkout-elements(define los custom elements). - Dependencia no instalada o versión incorrecta.
- SSR: los Web Components solo corren en el cliente.
Solución:
import "@tickean/checkout-elements"(o el wrapper de@tickean/react-checkout) antes de usar los tags.- Confirmá que la dependencia está instalada:
npm ls @tickean/checkout-elements. - En Next.js, marcá la página con
"use client"o cargá Elements condynamic(..., { ssr: false }).
?resume= no rehidrata el wizard
?resume= no rehidrata el wizardSíntoma: Abrís el link del mail de abandono y el checkout arranca vacío / en entradas.
Causas:
- Elements < 0.2.22 o checkout-js < 0.2.11.
- Código expirado, ya canjeado, o de otra organización.
- Origin del sitio no allowlisteado / publishable key incorrecta.
- La página del link no monta
<tickean-checkout>(returnUrl distinta).
Solución:
- Actualizá a
[email protected]+[email protected]. - Confirmá Network →
POST /v1/checkout/recovery/exchange(200). - La
return_urldel shortcode debe ser la página donde vive el embed. - Ver Reanudar sesión.
Modo demo
Para desarrollo sin backend, activá demo: true en el client o el atributo demo en Web Components. Acepta OTP 123456 y simula transferencias sin credenciales reales.
Updated 11 days ago
