cauril/Docs

Checkout embebido

Cobrá dentro de tu sitio con un drop-in. Tu server crea la sesión; el drop-in la cobra en el browser. Los datos de tarjeta van directo al PSP, nunca pasan por tu server ni por Cauril (PCI SAQ-A).

La integración tiene dos pasos: tu backend crea una sesión con tu sk_ y recibe un client_secret; tu frontend monta el drop-in con ese client_secret. El drop-in elige el PSP, dibuja el campo de pago seguro del proveedor, maneja 3DS y, si un PSP rechaza, reintenta en otro, todo normalizado.

  1. Creá la sesión (server)

    Desde tu backend, con tu API key. Requiere Idempotency-Key (reintentar no crea dos sesiones).

    BASH
    curl https://api.cauril.com/v1/checkout/sessions \
      -H "Authorization: Bearer sk_test_..." \
      -H "Idempotency-Key: $(uuidgen)" \
      -H "Content-Type: application/json" \
      -d '{
        "amount": 5000,
        "currency": "USD",
        "success_url": "https://tuapp.com/gracias",
        "cancel_url": "https://tuapp.com/carrito"
      }'

    La respuesta trae el client_secret (una sola vez) y el objeto ui que el drop-in usa para montar el campo del PSP:

    JSON
    {
      "object": "checkout.session",
      "id": "cs_01J...",
      "status": "open",
      "client_secret": "cs_01J..._secret_aGVsbG8",
      "ui": { "provider": "stripe", "publishable_key": "pk_test_...", "methods": ["card"] },
      "amount": 5000,
      "currency": "USD",
      "expires_at": "2026-06-01T12:30:00Z"
    }
  2. Montá el drop-in (browser)

    Pasá el client_secret al browser (nunca tu sk_), agregá un contenedor y montá el drop-in.

    HTML
    <div id="cauril-checkout"></div>
    <script src="https://js.cauril.com/v1/checkout.js"></script>
    <script>
      const checkout = Cauril.checkout({
        clientSecret: "cs_01J..._secret_aGVsbG8", // del paso 1
      });
    
      checkout.on("completed", ({ payment_status }) => {
        // UX: mandá al comprador a la página de éxito.
        // El cobro REAL se confirma por webhook (ver abajo).
        window.location.assign("/gracias");
      });
      checkout.on("failed", ({ code, message }) => {
        console.error(code, message);
      });
    
      checkout.mount("#cauril-checkout");
    </script>
    ¿Usás un bundler? El mismo drop-in es un módulo: import { Cauril } from "@cauril/checkout-js". La API es idéntica.
  3. Confirmá el cobro (webhook)

    El evento completed del browser es para la UX: si el comprador cierra la pestaña, no llega. La verdad del cobro es el webhook payment.succeeded (la sesión solo pasa a completed cuando Cauril recibe el webhook entrante del PSP). Cumplí pedidos contra el webhook, no contra el evento del browser.

Confirmá siempre el pago en tu backend vía webhook (payment.succeeded) antes de entregar el producto. El resultado en el browser puede perderse o falsificarse.

Redirección automática

Si no querés manejar el evento, pasá onComplete: "redirect" y el drop-in lleva al comprador a success_url (o a cancel_url) por vos:

JS
Cauril.checkout({ clientSecret, onComplete: "redirect" }).mount("#cauril-checkout");

Eventos

Suscribite con checkout.on(evento, handler). Devuelve una función para desuscribirte. Los códigos siempre vienen normalizados, nunca strings crudos del PSP.

EventoCuándoPayload
readyEl drop-in cargó y mostró el campo de pago.{ session }
method_selectedEl comprador eligió un método.{ method }
processingEl cobro está en curso.
requires_actionHace falta una acción (ej. 3DS).{ next_action }
completedLa sesión se completó.{ payment_status }
failedEl pago fue rechazado.{ code, message }
expiredLa sesión expiró sin pagar.
errorError al montar o de red.{ code, message }

Estilo

Ajustá la apariencia con un subconjunto controlado (sin CSS arbitrario, por seguridad): theme (light/dark), accent (color del botón), radius (0–24 px) y font (system/serif/mono).

JS
Cauril.checkout({
  clientSecret,
  appearance: { theme: "light", accent: "#0a7cff", radius: 8 },
}).mount("#cauril-checkout");
El drop-in solo monta desde los orígenes permitidos de tu organización (configurables en el dashboard). Un origen no listado es rechazado. Detalle de campos y respuestas en la referencia de API.