E-Signature
O Building Block E-Signature fornece funcionalidades completas para assinatura eletrônica de documentos, com suporte a múltiplos provedores.
Visão Geral
O E-Signature é um módulo tenant-scoped, ou seja, requer um token com organizationId. Ele é responsável por:
- Provider Configs - Configuração de provedores de assinatura eletrônica
- Signature Requests - Criação e gerenciamento de requisições de assinatura
- Templates - Suporte a templates de documentos (via provedor)
- Webhooks - Recebimento de eventos de status do provedor
Base URL
https://e-signature.stg.catalisa.app
Recursos
| Recurso | Descrição |
|---|---|
| Provider Configs | Configuração de provedores de assinatura |
| Signature Requests | Gerenciamento de requisições de assinatura |
Permissões
| Permissão | Descrição |
|---|---|
ESIGNATURE_CREATE | Criar requisições de assinatura |
ESIGNATURE_READ | Listar e visualizar requisições |
ESIGNATURE_DELETE | Excluir requisições de assinatura |
ESIGNATURE_ADMIN | Gerenciar configurações de provedor |
Provedores Suportados
| Provedor | Descrição | Status |
|---|---|---|
OPENSIGN | OpenSign - solução open source | Suportado |
DOCUSIGN | DocuSign - líder de mercado | Planejado |
ADOBESIGN | Adobe Sign - integração Adobe | Planejado |
ZAPSIGN | ZapSign - solução brasileira | Planejado |
OpenSign
O OpenSign é uma solução open source de assinatura eletrônica que pode ser:
- Self-hosted: Instalada em sua própria infraestrutura
- Cloud: Utilizada como SaaS através do OpenSign Cloud
Para instâncias self-hosted, nosso provider utiliza diretamente a API REST do Parse Server, permitindo integração completa sem necessidade de API tokens pagos. Consulte a documentação de Provider Configs para detalhes de configuração.
Status da Requisição
| Status | Descrição |
|---|---|
DRAFT | Rascunho - ainda não enviada |
SENT | Enviada para os signatários |
VIEWED | Visualizada por pelo menos um signatário |
PARTIALLY_SIGNED | Assinada parcialmente |
COMPLETED | Todas as assinaturas concluídas |
DECLINED | Recusada por um signatário |
EXPIRED | Prazo expirado |
CANCELLED | Cancelada pelo criador |
Status do Signatário
| Status | Descrição |
|---|---|
PENDING | Aguardando envio |
SENT | E-mail enviado |
VIEWED | Documento visualizado |
SIGNED | Assinatura concluída |
DECLINED | Recusou assinar |
Fluxo de Assinatura
O fluxo típico de assinatura eletrônica segue estas etapas:
Etapas
1. Configurar provedor (uma vez)
- Criar uma configuração de provedor com credenciais
- Testar a conexão
- Definir como provedor padrão
2. Criar requisição de assinatura
- Enviar documento (base64 ou referência do File Storage)
- Definir signatários (nome, e-mail, ordem)
- Opcionalmente, posicionar widgets de assinatura
3. Acompanhar status
- Requisição criada no provedor
- E-mails enviados aos signatários
- Cada signatário acessa o link e assina
4. Download do documento assinado
- Após todas as assinaturas, documento disponível para download
- Certificado de assinatura incluído
Sequência
Atores: Cliente, API, Provedor (ex: OpenSign)
Passo 1 - Configurar:
- Cliente → API:
POST /api/v1/esignature/provider-configs- API criptografa credenciais
- API salva configuração
- API retorna
{ id, providerType, isDefault }
Passo 2 - Criar requisição:
- Cliente → API:
POST /api/v1/esignature/requests- API valida documento e signatários
- API → Provedor: Cria envelope/requisição
- Provedor retorna IDs externos
- API salva mapeamento
- API retorna
{ id, status: 'SENT', viewUrl }
Passo 3 - Signatários assinam:
- Provedor → Signatário: E-mail com link
- Signatário → Provedor: Acessa e assina
- Provedor → API: Webhook com evento
- API atualiza status
- API publica evento no Redis
Passo 4 - Download:
- Cliente → API:
GET /api/v1/esignature/requests/:id/download- API → Provedor: Solicita URL do documento
- API retorna
{ downloadUrl, expiresAt }
Eventos
O E-Signature publica os seguintes eventos via Redis Pub/Sub, disponíveis para integração com o Webhooks Engine:
Eventos de Requisição
| Evento | Descrição |
|---|---|
esignature.request.created | Nova requisição criada |
esignature.request.viewed | Requisição visualizada |
esignature.request.signed | Requisição assinada (parcial ou total) |
esignature.request.completed | Todas as assinaturas concluídas |
esignature.request.declined | Requisição recusada |
esignature.request.cancelled | Requisição cancelada |
Eventos de Signatário
| Evento | Descrição |
|---|---|
esignature.signer.viewed | Signatário visualizou o documento |
esignature.signer.signed | Signatário assinou |
esignature.signer.declined | Signatário recusou |
Payload dos Eventos
{
"organizationId": "550e8400-e29b-41d4-a716-446655440000",
"requestId": "550e8400-e29b-41d4-a716-446655440001",
"signerId": "550e8400-e29b-41d4-a716-446655440002",
"status": "COMPLETED",
"metadata": {
"businessId": "contract-123",
"completedAt": "2024-01-15T14:30:00Z"
}
}
Exemplo Rápido
Fluxo completo para enviar um documento para assinatura:
// 1. Configurar provedor (apenas uma vez)
const configResponse = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/provider-configs', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'esignature-provider-config',
attributes: {
name: 'OpenSign Produção',
providerType: 'OPENSIGN',
credentials: {
apiKey: 'sua-api-key-aqui',
},
isDefault: true,
isActive: true,
},
},
}),
});
const { data: config } = await configResponse.json();
console.log(`Provedor configurado: ${config.id}`);
// 2. Testar conexão
const testResponse = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/provider-configs/${config.id}/test`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
},
});
const testResult = await testResponse.json();
if (testResult.success) {
console.log('Conexão OK!');
}
// 3. Criar requisição de assinatura
const signatureResponse = await fetch('https://e-signature.stg.catalisa.app/api/v1/esignature/requests', {
method: 'POST',
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
data: {
type: 'signature-request',
attributes: {
title: 'Contrato de Prestação de Serviços',
message: 'Por favor, assine o contrato até sexta-feira.',
expiresInDays: 7,
businessId: 'contract-2024-001',
fileBase64: 'JVBERi0xLjQKJeLjz9...', // PDF em base64
fileName: 'contrato.pdf',
signers: [
{ name: 'João Silva', email: 'joao@empresa.com', order: 1 },
{ name: 'Maria Santos', email: 'maria@cliente.com', order: 2 },
],
widgets: [
{ type: 'signature', page: 1, x: 100, y: 700, signerId: 'signer-1' },
{ type: 'signature', page: 1, x: 400, y: 700, signerId: 'signer-2' },
{ type: 'date', page: 1, x: 100, y: 650, label: 'Data' },
],
},
},
}),
});
const { data: request } = await signatureResponse.json();
console.log(`Requisição criada: ${request.id}`);
console.log(`Status: ${request.attributes.status}`);
console.log(`URL de visualização: ${request.attributes.viewUrl}`);
// 4. Listar signatários e seus status
const detailsResponse = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${request.id}`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { data: details } = await detailsResponse.json();
details.relationships.signers.data.forEach(signer => {
console.log(`${signer.attributes.name}: ${signer.attributes.status}`);
if (signer.attributes.signingUrl) {
console.log(` URL de assinatura: ${signer.attributes.signingUrl}`);
}
});
// 5. Após todas as assinaturas, baixar documento
if (details.attributes.status === 'COMPLETED') {
const downloadResponse = await fetch(`https://e-signature.stg.catalisa.app/api/v1/esignature/requests/${request.id}/download`, {
headers: {
'Authorization': `Bearer ${token}`,
},
});
const { downloadUrl, expiresAt } = await downloadResponse.json();
console.log(`URL do documento assinado: ${downloadUrl}`);
console.log(`URL expira em: ${expiresAt}`);
}
Widgets de Assinatura
Widgets são elementos posicionados no documento para coleta de informações:
| Tipo | Descrição | Uso |
|---|---|---|
signature | Campo de assinatura | Assinatura do signatário |
text | Campo de texto | Texto livre |
date | Campo de data | Data (preenchida automaticamente ou manual) |
checkbox | Caixa de seleção | Aceite de termos |
Posicionamento
{
"type": "signature",
"signerId": "signer-1",
"page": 1,
"x": 100,
"y": 700,
"width": 200,
"height": 50,
"required": true
}
As coordenadas x e y são em pontos (1/72 polegada), começando do canto inferior esquerdo da página. Para um documento A4, a largura é ~595 pontos e a altura ~842 pontos.
Webhooks
O E-Signature recebe webhooks do provedor para atualização de status em tempo real.
Endpoint de Webhook
POST /api/v1/esignature/webhooks/:configId
Este endpoint é público (não requer autenticação) e deve ser configurado no provedor de assinatura.
Configuração no Provedor
Ao configurar o webhook no provedor, use a URL:
https://e-signature.stg.catalisa.app/api/v1/esignature/webhooks/{configId}
Onde {configId} é o ID da configuração do provedor retornado ao criar a config.
O E-Signature verifica a autenticidade dos webhooks usando a assinatura fornecida pelo provedor. Certifique-se de configurar corretamente as chaves de webhook no provedor.