No tenés que usar nuestras landings. Armá tu página donde quieras (Claude Code, tu Vercel, Framer, tu propio React) y enchufale el checkout de contraentrega de Oktopus — o escribí el HTML y subilo a Oktopus, que lo hostea con el checkout ya cableado. En los cuatro casos la orden entra igual que una landing nativa: anti-fraude de precio + push a Dropi + confirmación por WhatsApp.
Nivel 1 — Widget (cero backend)
Pegás el snippet que devuelve okto_checkout_key_create y listo:
<div id="oktopus-checkout"></div>
<script src="https://www.oktopus.lat/embed/oktopus-checkout.js"></script>
<script>
Oktopus.checkout({
publishableKey: 'okto_live_pub_...',
productId: 'UUID-DEL-PRODUCTO',
country: 'CO',
unitPrice: 89900,
productName: 'Mi Producto',
mount: '#oktopus-checkout',
})
</script>Nivel 2 — Headless (tu formulario + nuestra API)
Tu form, tu diseño; la orden entra por POST /api/orders/create con tu publishable key en el header x-okto-api-key (o Authorization: Bearer okto_live_pub_...). Los campos van en español:
curl -X POST https://www.oktopus.lat/api/orders/create \
-H "Content-Type: application/json" \
-H "x-okto-api-key: okto_live_pub_..." \
-d '{
"product_id": "UUID-DEL-PRODUCTO",
"store_id": "UUID-DE-LA-TIENDA",
"nombre": "Juan Pérez",
"telefono": "3001234567",
"departamento": "Cundinamarca",
"ciudad": "Bogotá",
"direccion": "Calle 123 #45-67",
"barrio": "Chapinero",
"quantity": 1,
"unit_price": 89900,
"total_price": 89900
}'Respuesta: 201 { success: true, data: { id, order_number, status: "pending", ... } }. El precio se valida server-side contra el producto (anti-fraude); una key okto_test_pub_... crea la orden sin empujarla a Dropi.
Campos por país
departamento + ciudad + direccion son la base en todos los países. Además:
| País | Campos extra |
|---|---|
| CO / PY | barrio (opcional) |
| MX | colonia + codigo_postal |
| EC | colonia (barrio/sector) + calle_secundaria + color_casa + referencia |
| PE / CR / PA | distrito |
| AR | codigo_postal (opcional) |
Poblá el campo ciudad desde GET /api/geo/cities?country=XX — son las ciudades que Dropi acepta. En PY, MX, CO, PA y EC el server canonicaliza la ciudad contra el catálogo de Dropi al crear la orden, así el push a la transportadora nunca rebota por un nombre de ciudad escrito distinto.
Nivel 3 — Eject (llevate la landing a código)
¿Te gusta una landing generada en Oktopus pero querés hostearla vos? okto_landing_eject te la exporta a HTML + React editable para tu propio Vercel. El checkout sigue cobrando por el riel de Oktopus.
Nivel 4 — Subila a Oktopus (hosting nuestro)
Para cuando querés tu diseño pero no querés hosting, dominio ni deploy: tu agente escribe la página como un solo archivo HTML y la sube con okto_landing_upload_html. Oktopus la sanitiza, le cablea el checkout COD y la publica en https://<slug>.mipedido.lat.
okto_landing_upload_html({
product_id: "UUID-DEL-PRODUCTO",
html: "<!doctype html>…", // un solo archivo, CSS en <style>
name: "Faja Reductora — premium", // opcional
packs: [ // opcional; price = precio TOTAL del pack
{ name: "1 unidad", quantity: 1, price: 89900, compare_price: 129900 },
{ name: "Pack 2", quantity: 2, price: 159900, popular: true }
]
})
// → { ok, landing_id, slug, status: "draft", preview_url, removed, warnings, packs, notes }Qué pasa después: la landing queda en draft con un preview_url firmado (vence en 24 h). El agente la mira a 390px, corrige y re-sube con replace_landing_id (misma landing, mismo slug). Cuando está lista, okto_landing_publish({ landing_id }) la deploya; okto_landing_get devuelve public_url cuando está live.
Qué pone Oktopus por vos, antes de </body>: el formateador de precios ([data-price] → moneda de la tienda), el checkout (oktopus-checkout.js + Oktopus.checkout({ landingPageId, packs, … })) y, al publicar, el Meta Pixel de la tienda. El checkout dispara InitiateCheckout y Purchase; la CAPI server-side deduplica por eventID.
Reglas resumidas (el contrato completo, con qué se quita y qué se rechaza, está en okto_page_playbook → subir_html_a_oktopus):
| Regla | Si no |
|---|---|
Un solo HTML completo (<!doctype>, <html lang>, viewport, <body>) |
Sin <html>/<body> se rechaza |
CSS en <style>; fuentes de Google Fonts, jsdelivr o cdnjs por <link> |
Otros <link> se quitan |
Imágenes por URL https (banco de okto_product_images_get), nunca base64 |
Aviso; si pesa de más, se rechaza |
<div id="oktopus-checkout"></div> en la sección de compra, CTAs a #oktopus-checkout |
Se agrega una sección genérica al final |
Precios con data-price="NUMERO" que coincidan con producto/packs |
Aviso; el servidor cobra lo suyo igual |
| Sin pixel ni trackers propios, sin el snippet del widget | Se quitan |
<script> inline y onclick sí; <script src> solo desde www.oktopus.lat, cdn.jsdelivr.net, cdnjs.cloudflare.com |
Se quitan |
Sin fetch/XHR, sin <iframe>/<object>/<embed>, sin redirecciones, sin inputs de contraseña o tarjeta |
CSP bloquea / se quitan / se rechaza |
| Máximo 512 KB; mobile-first a 390px | Se rechaza / no se valida: mirá el preview |
Pago anticipado con Confío (solo Colombia)
Si la tienda tiene Confíopagos conectado, la página muestra dos botones: "Pedir · pago contra entrega" y "Pagar ahora · X% de descuento" (el descuento se configura por tienda, 10 % por defecto, y lo aplica el servidor al cobrar). Cuando el pago entra, el pedido va a Dropi sin recaudo. En las plantillas de Oktopus sale solo. En tu HTML subido, poné el segundo botón así y Oktopus lo activa (u oculta) al publicar:
<a class="btn-secondary okto-prepaid-only" href="#oktopus-checkout" data-okto-pay="confio">
Pagar ahora con descuento · <span data-price-prepaid="89900"></span>
</a>okto_confio_status te dice si la tienda puede (país, conexión, descuento); okto_confio_settings cambia el descuento o activa solo-prepago; okto_landing_confio_toggle apaga el botón en una landing puntual. Todo se aplica al republicar.
No hay modo test para pedidos desde una landing publicada: toda orden es real. Verificá con un pedido con tus propios datos y cancelalo con okto_order_update_status. Para probar solo el riel sin la página, okto_order_create_cod({ test_mode: true }).
La clave: tu agente lo hace solo
Con el MCP conectado, el agente acuña la llave y te arma el snippet sin que entres al dashboard:
"Acuñá una publishable key para midominio.com y dame el snippet del checkout para el producto X."
(Internamente llama okto_checkout_key_create({ domains, product_id }).) Y okto_page_playbook le da al agente la receta de una página COD que convierte: estructura, gatillos mentales y pixel/CAPI con los datos reales de tu cuenta — y el contrato subir_html_a_oktopus para el nivel 4.
La conversión Purchase la dispara Oktopus server-side (CAPI) también para órdenes de páginas externas — tu pixel de Meta sigue midiendo aunque la página no viva en Oktopus.