Saltar al contenido principal
Agrega firmas electrónicas legalmente vinculantes a cualquier org de Salesforce usando Flow, Apex o Agentforce. Envía solicitudes de firma a partir de una actualización de registro, incrusta la firma en Lightning y enruta los eventos de webhook de vuelta a los registros de Salesforce. Esta guía cubre tres caminos de integración:
  1. Flow con External Services — Sin código. Registra la especificación OpenAPI de Firma una vez y luego invoca Create and send signing request desde cualquier Flow. Ideal para administradores.
  2. Apex con Named Credentials — Con código. Llama a Firma directamente desde clases Apex, Flow Actions o controladores LWC. Ideal para desarrolladores que quieren control total.
  3. Acción de Agentforce — Expón Firma como una Action en un agente de Agentforce para que pueda enviar solicitudes de firma en respuesta a un prompt de usuario o a un disparador.
Los tres caminos comparten la misma Named Credential, así que configúrala primero.

Requisitos previos

  • Una cuenta de Firma con una clave API
  • Una org de Salesforce (edición Enterprise, Unlimited o Developer) con permiso para crear Named Credentials y External Services
  • Al menos una plantilla de Firma con campos de firma configurados
Firma usa la clave API en bruto como el valor del header Authorization. No la prefijes con Bearer. Esto difiere de muchas otras APIs.

Paso 0: Guardar la clave API de Firma como una Named Credential

Las Named Credentials son el patrón seguro de Salesforce para guardar URLs de endpoints y headers de autenticación. El resto de las secciones de esta guía la referencian.
  1. En Setup, busca Named Credentials y abre la página
  2. En External Credentials, haz clic en New:
    • Label: Firma
    • Name: Firma
    • Authentication Protocol: Custom
  3. Entra a la nueva External Credential, baja hasta Principals y haz clic en New:
    • Parameter Name: Default
    • Sequence Number: 1
    • Identity Type: Named Principal
    • Authentication Parameters: agrega un parámetro
      • Name: ApiKey
      • Value: tu clave API de Firma
  4. Baja hasta Custom Headers y agrega uno:
    • Name: Authorization
    • Value: {!$Credential.Firma.ApiKey}
  5. De vuelta en Named Credentials, haz clic en New:
    • Label: Firma API
    • Name: Firma_API
    • URL: https://api.firma.dev/functions/v1/signing-request-api
    • External Credential: Firma
    • Allowed Namespaces: deja el valor predeterminado
  6. Guarda
Nunca escribas la clave API directamente en Apex, Flow o un Custom Setting. Siempre referénciala a través de la Named Credential para que permanezca cifrada en reposo y la rotación solo requiera editar un registro.

Camino 1: Flow con External Services

El camino sin código. Importas la especificación OpenAPI de Firma una vez y las acciones quedan disponibles como pasos invocables en cualquier Flow.

Paso 1: Registrar Firma como un External Service

  1. En Setup, busca External Services y haz clic en Add an External Service
  2. Elige From API Specification y luego Save and Next
  3. Configura:
    • External Service Name: Firma
    • Select a Named Credential: Firma_API
    • Service Schema: Upload from Local o pega el JSON
  4. Pega la especificación OpenAPI de Firma desde https://docs.firma.dev/api-reference/v01.26.00/openapi-v01.26.00.json
  5. Haz clic en Save and Next
  6. Selecciona las operaciones que quieres disponibles en Flow. Opciones comunes:
    • POST /signing-requests/create-and-send
    • POST /signing-requests
    • POST /signing-requests/{id}/send
    • GET /signing-requests/{id}
    • GET /templates
  7. Haz clic en Save and Next y luego en Finish
Consulta el changelog de la API de Firma para conocer la URL más reciente de la especificación. Salesforce guarda en caché la especificación en el momento del registro, así que vuelve a registrar el External Service cada vez que quieras nuevos endpoints.

Paso 2: Construir el Flow

  1. En Setup, abre Flows y crea un nuevo Flow (Record-Triggered es lo más común)
  2. Elige el objeto disparador (Opportunity, Contract, Quote o un objeto personalizado) y la condición que debe enviar una solicitud de firma (por ejemplo, StageName es igual a Closed Won)
  3. Agrega un elemento Action
  4. Busca Firma y elige Create and send signing request
  5. Mapea las entradas:
    • template_id: un valor de Custom Metadata, un campo del registro o un ID de plantilla fijo
    • recipients: construye una colección de registros de destinatarios. Los campos obligatorios son first_name y email. Los campos opcionales incluyen last_name, designation (por defecto Signer), order, company, title, phone_number y campos de dirección. La forma más fácil es un elemento Assignment que construya la colección a partir de los campos de contacto del registro disparador
  6. Guarda y activa
Cuando se dispara el trigger, Salesforce llama a Firma a través de la Named Credential y Firma envía el documento al firmante.

Camino 2: Apex con Named Credentials

Para desarrolladores que quieren control total, llama a Firma directamente desde Apex. Usa la Named Credential como base del endpoint para que la clave API permanezca cifrada.
public with sharing class FirmaService {

    private static final String FIRMA_BASE = 'callout:Firma_API';

    public class Recipient {
        public String first_name;
        public String last_name;
        public String email;
        public String designation;
        public Integer order;
    }

    public static String createAndSend(String templateId, Recipient signer) {
        signer.designation = 'Signer';
        signer.order = 1;

        Map<String, Object> body = new Map<String, Object>{
            'template_id' => templateId,
            'recipients' => new List<Recipient>{ signer }
        };

        HttpRequest req = new HttpRequest();
        req.setEndpoint(FIRMA_BASE + '/signing-requests/create-and-send');
        req.setMethod('POST');
        req.setHeader('Content-Type', 'application/json');
        req.setBody(JSON.serialize(body));

        Http http = new Http();
        HttpResponse res = http.send(req);

        if (res.getStatusCode() >= 300) {
            throw new CalloutException('Firma error: ' + res.getBody());
        }

        Map<String, Object> data =
            (Map<String, Object>) JSON.deserializeUntyped(res.getBody());
        return (String) data.get('id');
    }
}
El prefijo callout:Firma_API le indica a Salesforce que use la Named Credential, la cual inyecta el header Authorization automáticamente. Ninguna clave API aparece en el código, en los logs ni en la inspección de solicitudes serializadas.
El endpoint create-and-send crea la solicitud de firma y la envía por correo a los destinatarios en una sola llamada. Si necesitas un paso de revisión controlado por Apex, usa POST /signing-requests para crear un borrador y luego POST /signing-requests/{id}/send por separado.
Expón el método Apex como una Invocable Action para que Flow pueda llamarlo:
public with sharing class FirmaInvocable {

    public class Input {
        @InvocableVariable(required=true) public String templateId;
        @InvocableVariable(required=true) public String firstName;
        @InvocableVariable(required=true) public String lastName;
        @InvocableVariable(required=true) public String email;
    }

    public class Output {
        @InvocableVariable public String signingRequestId;
    }

    @InvocableMethod(label='Send Firma signing request')
    public static List<Output> send(List<Input> inputs) {
        List<Output> results = new List<Output>();
        for (Input i : inputs) {
            FirmaService.Recipient r = new FirmaService.Recipient();
            r.first_name = i.firstName;
            r.last_name = i.lastName;
            r.email = i.email;
            String id = FirmaService.createAndSend(i.templateId, r);
            Output o = new Output();
            o.signingRequestId = id;
            results.add(o);
        }
        return results;
    }
}

Camino 3: Acción de Agentforce

Para permitir que un agente de Agentforce envíe solicitudes de firma en respuesta a un prompt (“envía el NDA estándar a alice@example.com”), envuelve una de las opciones anteriores como una Agent Action.
  1. En Setup, abre Agentforce Builder y elige el agente que quieres extender
  2. Abre el Topic correspondiente (por ejemplo, Contract Lifecycle)
  3. Haz clic en New Action y elige Flow o Apex
    • Flow: elige un screen Flow o un Flow autolanzado que envuelva la acción Firma.Create and send signing request de External Services
    • Apex: elige el método FirmaInvocable.send
  4. Define las entradas que el agente recopilará de la conversación: plantilla, nombre del firmante, correo del firmante
  5. Agrega la acción al Topic y publica
Usa el prompt de confirmación de Agentforce antes de cualquier acción de envío para que el agente lea en voz alta el nombre de la plantilla y los datos del firmante antes de activar Firma. Las solicitudes de firma salientes llegan a terceros; un paso de confirmación vale el turno extra.

Integración de webhooks: reaccionar cuando se firman documentos

Recibe webhooks de Firma en Salesforce exponiendo un endpoint Apex REST, y luego actualiza el registro de origen (Opportunity, Contract, objeto personalizado) cuando la solicitud de firma se completa.

Paso 1: Crear el endpoint Apex REST

@RestResource(urlMapping='/firma-webhook')
global with sharing class FirmaWebhook {

    @HttpPost
    global static void receive() {
        RestRequest req = RestContext.request;
        Map<String, Object> payload =
            (Map<String, Object>) JSON.deserializeUntyped(
                req.requestBody.toString()
            );

        String eventType = (String) payload.get('type');
        Map<String, Object> data =
            (Map<String, Object>) payload.get('data');

        if (eventType == 'signing_request.completed') {
            Map<String, Object> sr =
                (Map<String, Object>) data.get('signing_request');
            String signingRequestId = (String) sr.get('id');

            List<Opportunity> opps = [
                SELECT Id FROM Opportunity
                WHERE Firma_Signing_Request_Id__c = :signingRequestId
                LIMIT 1
            ];
            if (!opps.isEmpty()) {
                opps[0].StageName = 'Signed';
                update opps[0];
            }
        }

        RestContext.response.statusCode = 200;
    }
}

Paso 2: Verificar la firma del webhook

Firma firma cada payload de webhook con HMAC-SHA256. Verifica siempre la firma en producción para rechazar payloads falsificados. Tu webhook secret está disponible en Configuración > Webhooks en el panel de Firma.
private static Boolean verifySignature(
    String payload, String signatureHeader, String secret
) {
    Blob hmac = Crypto.generateMac(
        'HmacSHA256',
        Blob.valueOf(payload),
        Blob.valueOf(secret)
    );
    String expected = EncodingUtil.convertToHex(hmac);
    return expected.equalsIgnoreCase(signatureHeader);
}
Llama a esto al inicio del método receive() antes de procesar:
String signature = RestContext.request.headers.get('x-firma-signature');
String body = RestContext.request.requestBody.toString();
String secret = '{!$Credential.Firma_Webhook.Secret}'; // o un valor de Custom Metadata

if (!verifySignature(body, signature, secret)) {
    RestContext.response.statusCode = 401;
    return;
}

Paso 3: Exponer el endpoint públicamente

Las llamadas de webhook de Firma no están autenticadas como un usuario de Salesforce, así que expón el endpoint a través de un Experience Cloud Site. Crea un site (o usa uno existente) y luego otorga al perfil de guest user del site permiso para ejecutar la clase Apex FirmaWebhook. Consulta Salesforce: Allow Guest Users to Access Apex REST para conocer los pasos de configuración completos.

Paso 4: Registrar el webhook en Firma

  1. En el panel de Firma, ve a Configuración > Webhooks
  2. Agrega un nuevo webhook apuntando a https://<your-site-domain>/services/apexrest/firma-webhook
  3. Suscríbete a los eventos que te interesan (signing_request.completed, signing_request.recipient.declined, signing_request.expired)
Consulta la guía de webhooks para conocer todos los tipos de eventos y formas de payload.

Firma incrustada en Lightning

Si quieres que los firmantes completen documentos dentro de una página Lightning, usa un Lightning Web Component que incruste la interfaz de firma de Firma. Después de una llamada create-and-send exitosa, lee el ID del firmante de la respuesta y pásalo al LWC:
<template>
  <iframe
    src={signingUrl}
    style="width:100%;height:900px;border:0;"
    allow="camera;microphone;clipboard-write"
    title="Document Signing"
  ></iframe>
</template>
import { LightningElement, api } from 'lwc';

export default class FirmaSigning extends LightningElement {
  @api signingRequestUserId;

  get signingUrl() {
    return `https://app.firma.dev/signing/${this.signingRequestUserId}`;
  }
}
Agrega https://app.firma.dev a tus CSP Trusted Sites para que el iframe cargue. Consulta la guía de firma incrustada para conocer la configuración completa, incluidas las mejores prácticas de seguridad.

Para ISVs y partners de AppExchange: firma multi-org

Si estás construyendo una app de AppExchange que necesita firmas electrónicas para cada una de las orgs de tus clientes, usa Firma Customer Workspaces. Cada org de cliente obtiene su propio espacio de trabajo de Firma aislado con plantillas separadas, seguimiento de uso y registro de auditoría. Aprovisiona un espacio de trabajo por org en el momento de la instalación, guarda la clave API del espacio de trabajo en un Protected Custom Setting en esa org y referéncialo desde la Named Credential. Sin fuga de datos entre clientes.

Conexión MCP para construcción asistida por IA

Firma ofrece un servidor Docs MCP en https://docs.firma.dev/mcp. Conéctalo a Claude, Cursor o cualquier herramienta de IA compatible con MCP mientras escribes Apex o construyes Flows, y el asistente podrá responder preguntas precisas sobre la API a partir de la documentación de Firma. Esto es para la experiencia de construcción y no afecta tu integración desplegada.

Próximos pasos