formbasedocs
Ir a la appApp

Guías · API REST

Recibe y verifica el callback

Una solicitud con callbackUrl termina con un POST firmado a esa URL: las respuestas cuando el destinatario la envía, o el aviso de que expiró o se canceló. Esta guía ejecuta un receptor en tu máquina, comprueba la firma, e imprime las respuestas.

Last checked


Necesitas un token de API y un formulario publicado, como en Envía una solicitud con la API REST, y Node o Python en tu máquina. Qué lleva un callback, y cómo funcionan los reintentos, está en Callbacks y firma.

1. Copia el secreto de firma

formbase firma cada callback con el secreto de firma de solicitudes de tu espacio de trabajo. Abre OAuth y claves de API en la barra lateral del espacio de trabajo y busca la tarjeta Secreto de firma de solicitudes:

La tarjeta Secreto de firma de solicitudes: secreto del espacio de trabajo, enmascarado como rqs_ seguido de asteriscos, con botones para revelarlo, copiarlo y regenerarlo

Haz clic en el botón de copiar y guarda el secreto en una variable de entorno en la terminal donde se ejecutará tu receptor:

bash
export FORMBASE_SIGNING_SECRET='rqs_...'

2. Escribe el receptor

Guarda la función verify de Callbacks y firma junto a tu receptor: como verify.mjs para Node, ya que usa import, o como verify.py para Python. El receptor lee el cuerpo en bruto, comprueba la firma, y solo entonces analiza el JSON:

Calcula el hash del cuerpo exactamente como llegó. Analizarlo y volver a convertirlo en JSON cambia los bytes, y la firma deja de coincidir.

3. Ejecútalo y dale una URL pública

Arranca el receptor:

bash
node receiver.mjs      # or: python3 receiver.py

formbase solo llama a direcciones HTTPS públicas, así que localhost no sirve. Mientras pruebas, un túnel le da una a tu máquina.

El túnel rápido de Cloudflare

no necesita cuenta. Ejecútalo en una segunda terminal:

bash
cloudflared tunnel --url http://localhost:8787

Imprime una dirección como https://horn-cod-classics-arab.trycloudflare.com. ngrok y herramientas similares funcionan igual. En producción, usa la propia URL HTTPS de tu servidor en su lugar.

4. Envía una solicitud con una URL de callback

Crea una solicitud de prueba como en la guía anterior, y añade callbackUrl con la dirección del túnel. Usa tu propio ID de formulario:

bash
curl -X POST https://api.formbase.so/api/v1 \
  -H "Authorization: Bearer $FORMBASE_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "requests.create",
    "params": {
      "formId": "jx75hdx8vb5hy1x85gm17nqgkn8f674g",
      "recipient": { "email": "ada@acme.example", "name": "Ada Lovelace" },
      "prefill": { "company_name": "Analytical Engines Ltd" },
      "readonly": ["company_name"],
      "externalId": "supplier-2044",
      "idempotencyKey": "supplier-2044",
      "callbackUrl": "https://horn-cod-classics-arab.trycloudflare.com/formbase",
      "test": true
    }
  }'

Usa una idempotencyKey nueva: la misma clave con un cuerpo diferente se rechaza. Abre el url de la respuesta, responde el formulario, y envíalo.

5. Mira llegar el callback

Unos segundos después de enviar, el receptor imprime el tipo de evento, tu ID externo y las respuestas. El receptor de Node imprime:

text
request.completed supplier-2044 {"certificate_of_incorporation":[{"name":"certificate-of-incorporation.pdf","size":635,"type":"application/pdf","url":"https://api.formbase.so/api/storage/...",...}],"company_name":"Analytical Engines Ltd","contact_email":"ada@acme.example","do_you_accept_our_30_day_payment_terms":"yes","vat_number":"GB123456789"}

Para ver un rechazo, envía tú mismo cualquier POST al receptor, por ejemplo curl -X POST -d ‘’ http://localhost:8787. No tiene una firma válida, así que el receptor imprime rejected: bad signature y responde 401.

Antes de pasar a producción

  • Responde 2xx en 10 segundos. formbase marca el callback como entregado con cualquier 2xx. Un 5xx, un 408, un 429 o un tiempo de espera agotado se reintenta durante unas cuatro horas; cualquier otro 4xx, como el 401 de arriba, detiene los reintentos. Consulta Reintentos.

  • Ramifica según type.

    La misma URL también recibe request.expired y request.canceled, que no llevan respuestas.

  • Maneja cada evento una sola vez. Un reintento lleva el mismo id. Guarda los ids que ya manejaste y salta una repetición.

  • Comprueba test.

    Un callback de una solicitud de prueba lleva “test”: true. Quita test de requests.create para destinatarios reales.

Si tu receptor estuvo caído más tiempo del que duran los reintentos, las respuestas no se pierden. Léelas con requests.get, o envía el callback de nuevo con requests.replayCallback o desde la página de Solicitudes.

Siguiente