Saltar al contenido principal
Firma te permite agregar firmas electrónicas con validez legal a cualquier aplicación de Databutton. Usa el backend de Python integrado de Databutton para llamar a la API REST de Firma, gestionar plantillas, enviar solicitudes de firma y rastrear finalizaciones mediante webhooks. Esta guía recorre el flujo completo: almacenar tu clave API, enviar una solicitud de firma, conectarla a tu interfaz de React y manejar eventos de finalización.

Requisitos previos

  • Una cuenta de Firma con una clave API
  • Una cuenta de Databutton (la prueba gratuita funciona para desarrollo; se necesitan planes de pago para producción)
  • Al menos una plantilla de Firma con campos de firma configurados
Firma usa la clave API sin procesar como valor del header Authorization - no la antepongas con Bearer. Esto difiere de muchas otras APIs.

Paso 1: Almacena tu clave API como secreto

Databutton gestiona los secretos mediante un panel dedicado en el editor. Los valores se inyectan como variables de entorno en tus funciones backend en tiempo de ejecución.
  1. Abre tu app en el editor de Databutton
  2. Haz clic en Secrets en la barra lateral
  3. Haz clic en Add Secret
  4. Configura el nombre como FIRMA_API_KEY y pega tu clave API de Firma
  5. Guarda
El secreto ya está disponible como os.environ["FIRMA_API_KEY"] en cualquier función backend.
Nunca expongas tu clave API en código de frontend. Llama siempre a la API de Firma desde funciones backend, no directamente desde componentes de React.

Paso 2: Crea una función backend para enviar solicitudes de firma

En Databutton, las funciones backend son endpoints de FastAPI en Python. Crea un nuevo endpoint de API HTTP que llame al endpoint create-and-send de Firma:
# Backend HTTP API endpoint: send_signing_request
import os
import httpx
from fastapi import APIRouter
from fastapi.responses import JSONResponse
from pydantic import BaseModel

router = APIRouter()

FIRMA_API = "https://api.firma.dev/functions/v1/signing-request-api"


class SigningRequestBody(BaseModel):
    template_id: str
    signer_email: str
    signer_first_name: str
    signer_last_name: str


@router.post("/send-signing-request")
async def send_signing_request(body: SigningRequestBody):
    api_key = os.environ.get("FIRMA_API_KEY")
    if not api_key:
        return JSONResponse(content={"error": "FIRMA_API_KEY not configured"}, status_code=500)

    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{FIRMA_API}/signing-requests/create-and-send",
            headers={
                "Authorization": api_key,
                "Content-Type": "application/json",
            },
            json={
                "name": f"Contract for {body.signer_first_name} {body.signer_last_name}",
                "template_id": body.template_id,
                "recipients": [
                    {
                        "first_name": body.signer_first_name,
                        "last_name": body.signer_last_name,
                        "email": body.signer_email,
                        "designation": "Signer",
                        "order": 1,
                    }
                ],
            },
        )

    data = response.json()

    if response.status_code >= 400:
        return JSONResponse(content={"error": data}, status_code=response.status_code)

    return {
        "signing_request_id": data["id"],
        "first_signer": data.get("first_signer"),
        "status": "sent",
    }
El endpoint create-and-send crea la solicitud de firma y la envía a los destinatarios de forma atómica. Si necesitas revisar o modificar la solicitud antes de enviarla, usa POST /signing-requests para crear un borrador, y luego POST /signing-requests/{id}/send por separado.

Paso 3: Llama al backend desde tu interfaz de React

Las apps de Databutton usan React para el frontend. Llama a tu endpoint backend cuando el usuario envíe el formulario:
// pages/SendContract.tsx
import { useState } from "react";

export default function SendContract({ templateId }: { templateId: string }) {
  const [loading, setLoading] = useState(false);
  const [result, setResult] = useState<any>(null);

  async function handleSend() {
    setLoading(true);
    try {
      const res = await fetch("/api/send-signing-request", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          template_id: templateId,
          signer_email: "alice@example.com",
          signer_first_name: "Alice",
          signer_last_name: "Johnson",
        }),
      });
      const data = await res.json();
      setResult(data);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div>
      <button onClick={handleSend} disabled={loading}>
        {loading ? "Sending..." : "Send contract"}
      </button>
      {result && <pre>{JSON.stringify(result, null, 2)}</pre>}
    </div>
  );
}
También puedes pedirle al chat de IA de Databutton que conecte esto: “Cuando el usuario envíe el formulario del contrato, llama al endpoint backend send-signing-request con el ID de la plantilla, el correo del firmante, el nombre y el apellido tomados del formulario.” Databutton generará el formulario, el botón y la llamada fetch juntos.

Integración de webhooks

Para rastrear cuándo se firman los documentos, agrega un endpoint backend de webhook y regístralo en el panel de Firma.
# Backend HTTP API endpoint: firma_webhook
from fastapi import APIRouter, Request

router = APIRouter()


@router.post("/webhooks/firma")
async def firma_webhook(request: Request):
    payload = await request.json()
    event_type = payload.get("type")
    data = payload.get("data", {})

    if event_type == "signing_request.completed":
        signing_request_id = data["signing_request"]["id"]

        # Update your database, send a notification, or trigger
        # the next step in your workflow
        print(f"Signing request {signing_request_id} completed")

    if event_type == "signing_request.recipient.signed":
        recipient_email = data.get("recipient", {}).get("email")
        print(f"{recipient_email} signed the document")

    return {"received": True}
Luego registra el webhook:
  1. Despliega tu app de Databutton para que el endpoint sea accesible públicamente
  2. En el panel de Firma, en Configuración → Webhooks, agrega un webhook que apunte a https://<your-app-domain>/api/webhooks/firma
  3. Selecciona los eventos que quieres recibir. Consulta la guía de webhooks para ver todos los tipos de eventos y la verificación de firmas
Para uso en producción, verifica siempre la firma del webhook usando tu secret de firma de webhook de Firma. Consulta la guía de webhooks para detalles de implementación.

Firma incrustada

Para apps donde los firmantes completan documentos dentro de tu interfaz en lugar de saltar al correo electrónico, Firma ofrece una experiencia de firma incrustable. La respuesta de create-and-send incluye un first_signer.id (el signing_request_user_id) y un first_signer.signing_link ya listo. Renderízalo en un iframe:
// components/EmbeddedSigning.tsx
export function EmbeddedSigning({
  signingRequestUserId,
}: {
  signingRequestUserId: string;
}) {
  return (
    <iframe
      src={`https://app.firma.dev/signing/${signingRequestUserId}`}
      style={{ width: "100%", height: "900px", border: 0 }}
      allow="camera; microphone; clipboard-write"
      title="Document Signing"
    />
  );
}
Consulta la guía de firma incrustada para las instrucciones de configuración completas, incluidas las mejores prácticas de seguridad.

Extra: conexión MCP para construcción asistida por IA

Firma ofrece un servidor Docs MCP que el chat de IA de Databutton puede usar como contexto. Una vez conectado, la IA hace referencia a la documentación de Firma mientras genera código, de modo que usa endpoints, nombres de campos y patrones precisos. Esto es una ayuda en tiempo de construcción y no afecta tu app desplegada.

Próximos pasos