Documentación · P4D

Modo Desarrollador

Cómo conectar P4D con tu propio backend para alimentar el catálogo de un agente desde una API externa y recibir las órdenes que el agente genera en tu sistema.

¿Para quién es esto?

El modo Desarrollador está pensado para integradores que ya tienen un sistema propio (e-commerce, ERP, base de productos) y quieren que el agente de P4D lea desde ahí en lugar de cargar productos a mano.

Hoy hay dos features:

  • Catálogo custom por API — el agente ejecuta código JS que vos escribís para traer productos desde tu API cada vez que un usuario pregunta.
  • Webhook de órdenes — cuando el agente genera una orden, P4D hace POST a la URL que vos configures con todo el detalle.
Ubicación en la app: Sidebar Ventas → Catálogo → tab Desarrollador.
Vista completa del tab Desarrollador con el switch arriba, el editor de código y la card del webhook abajo
Overview del modo Desarrollador.

Webhook de órdenes

Cuando el agente completa una orden, P4D hace POST al endpoint que vos configures con el detalle completo. Sirve para inyectar la orden en tu sistema (e-commerce, ERP, base interna).

La card Webhook de órdenes aparece abajo del catálogo dentro del tab Desarrollador.

Card del webhook con URL, secret enmascarado y botones
Card del webhook de órdenes.

Configurar

  1. Pegá la URL pública de tu endpoint (HTTPS) en el campo URL del webhook.
  2. Click Guardar. P4D genera automáticamente un secret aleatorio (244 bits de entropía).
  3. Se abre un modal con el secret en plano — copialo ahora, no se vuelve a mostrar.
  4. Pegalo en una variable de entorno de tu backend (ej. P4D_WEBHOOK_SECRET).
  5. Activá el toggle Inactivo → Activo para que P4D empiece a disparar el webhook.

Payload

P4D manda POST con Content-Type: application/json y este body:

{
  "id": "uuid de la orden",
  "bot_id": "uuid del agente",
  "customer": {
    "name": "Nombre del cliente",
    "phone": "+5491100000000",
    "email": "cliente@ejemplo.com"
  },
  "items": [
    {
      "product_id": "id que devolviste en el catálogo",
      "product_name": "Nombre del producto",
      "quantity": 1,
      "price": 1000
    }
  ],
  "total": 1000,
  "status": "pending",
  "created_at": "2026-06-02T18:00:00.000Z"
}

El payload del botón Probar es idéntico pero con un campo extra "test": true y todos los IDs en cero, para que puedas diferenciar mocks de órdenes reales en tu backend.

Verificación del secret

En cada POST P4D manda el header x-nodo-webhook-secret con el valor que copiaste al crear el webhook. Tu backend solo tiene que comparar ese header con la variable de entorno donde lo guardaste.

Ejemplo en Node.js / Express

app.post("/webhooks/p4d-orders", express.json(), (req, res) => {
  if (req.headers["x-nodo-webhook-secret"] !== process.env.P4D_WEBHOOK_SECRET) {
    return res.status(401).send("Unauthorized");
  }
  const order = req.body;
  // ... procesar la orden ...
  res.status(200).send("ok");
});

Ejemplo en Python / FastAPI

from fastapi import FastAPI, Header, HTTPException, Request
import os

app = FastAPI()

@app.post("/webhooks/p4d-orders")
async def handle(req: Request, x_nodo_webhook_secret: str = Header(None)):
    if x_nodo_webhook_secret != os.environ["P4D_WEBHOOK_SECRET"]:
        raise HTTPException(status_code=401)
    order = await req.json()
    # ... procesar ...
    return {"ok": True}
Por qué este formato: el secret es un shared token, no hace falta verificar firmas HMAC. Una comparación de string contra una env var alcanza. Bajo overhead, fácil de implementar.

Probar

Click Probar dispara un POST a tu URL con un payload mock (cliente "Cliente de prueba", item demo, total $1000). Te muestra:

  • Status HTTP que devolvió tu endpoint.
  • Tiempo de respuesta en ms.
  • Body de respuesta (los primeros 2KB) si lo querés inspeccionar.
Recomendación: dejá tu endpoint respondiendo HTTP 200 con cualquier body corto. Si necesitás procesamiento largo, encolá la orden y respondé 200 enseguida — P4D da hasta 10s de timeout.

Historial de intentos

Al final de la card hay un desplegable Últimos intentos que muestra los últimos 10 POSTs hechos a tu URL, separando los de prueba (test) de los reales (live):

  • Fecha y hora.
  • Estado (OK / Error).
  • Código HTTP recibido.
  • Tiempo de respuesta.
Tabla Últimos intentos con varias filas
Historial de los últimos intentos de entrega.

Rotar el secret

Si perdés el secret o sospechás que se filtró, click Rotar en la sección Secret. Se genera uno nuevo, se muestra una vez, y el anterior queda inválido inmediatamente. Acordate de actualizar la env var de tu backend.

Errores comunes

"Servicio no configurado" o errores 401/500 desde Validar / Test

Problema del lado de P4D, no del código tuyo. Contactá a soporte si persiste.

"INVALID_OUTPUT" en Test run

Tu código no devolvió un array, o algún item no tiene id / nombre / precio. Mirá la descripción del error que apunta al campo problemático y al "Valor devuelto" para ver el raw.

Webhook devuelve 401/403 desde tu backend

Tu endpoint está rechazando el secret. Verificá:

  • Que la env var del backend tenga el valor exacto que copiaste del modal (sin espacios).
  • Que estés leyendo el header case-insensitive. Algunos frameworks normalizan a x-nodo-webhook-secret (todo minúsculas).
  • Si rotaste el secret, que la env var nueva esté deployada.

El agente dice que no hay productos pero la API tiene

  • El switch Fuente activa está en Manual, no en Desarrollador.
  • Tu código devuelve [] para esa query. Probalo en Test run con ese mismo texto.
  • El timeout de 10s te está cortando — agregá log("paso 1") para ver cuándo se queda.

FAQ

¿Puedo usar npm install <algo> dentro del sandbox?

No. El sandbox no tiene require ni import — solo las globals expuestas. Si necesitás una librería específica, encapsulala del lado de tu API y consumila vía fetch.

¿Puedo cachear el access_token de OAuth entre invocaciones?

No en runtime (cada invocación es un Isolate nuevo). Sí podés cachearlo del lado de tu API y pedirlo con un endpoint propio que el sandbox consulte. Es la forma estándar de manejar OAuth con webhooks/serverless.

¿Cuánto tarda una consulta del agente al catálogo?

Típicamente 50-150ms del lado de P4D + lo que tarde tu API. Si tu API es la mayor parte del tiempo, optimizala vos.

¿Qué pasa si mi API está caída cuando el agente consulta?

Tu código tira excepción, P4D devuelve un error genérico, y el agente le contesta al usuario algo tipo "No pudimos consultar el catálogo en este momento". Los detalles quedan en los logs internos para diagnóstico.

¿Hay reintentos del webhook de órdenes?

Hoy no — un solo intento, sin retry, con 10s de timeout. Si tu endpoint está caído, la orden queda registrada en P4D pero no llega a tu backend. Si necesitás retries con backoff, lo agregamos en una próxima iteración.

¿Puedo recibir webhooks de otros eventos (ej. lead nuevo, mensaje)?

Por ahora solo órdenes. Si te interesa otro evento, escribinos.