ForSign.Sdk
2.0.3
See the version list below for details.
dotnet add package ForSign.Sdk --version 2.0.3
NuGet\Install-Package ForSign.Sdk -Version 2.0.3
<PackageReference Include="ForSign.Sdk" Version="2.0.3" />
<PackageVersion Include="ForSign.Sdk" Version="2.0.3" />
<PackageReference Include="ForSign.Sdk" />
paket add ForSign.Sdk --version 2.0.3
#r "nuget: ForSign.Sdk, 2.0.3"
#:package ForSign.Sdk@2.0.3
#addin nuget:?package=ForSign.Sdk&version=2.0.3
#tool nuget:?package=ForSign.Sdk&version=2.0.3
Documentação Completa do SDK ForSign para .NET
🚀 Introdução
Bem-vindo à documentação oficial do SDK ForSign para .NET! Este SDK oferece integração simples e completa com a plataforma ForSign de assinaturas eletrônicas digitais.
Principais Funcionalidades
- Múltiplos Tipos de Assinatura: Clique, desenho, texto, escolha do usuário e carimbo automático
- Posicionamento Flexível: Use coordenadas fixas ou tags dinâmicas no PDF
- Segurança Avançada: Duplo fator de autenticação por e-mail e selfie
- Workflows Personalizáveis: Ordem de assinatura, assinatura presencial, finalização manual/automática
- Formulários Dinâmicos: Campos de texto, seleção e checkbox com validação
- Anexos Avançados: Controle de tipos de arquivo, quantidade e métodos de captura
- Gerenciamento Completo: CRUD de operações, anexos e configurações
- Múltiplos Idiomas: Português, Inglês e Espanhol
- Templates e Grupos: Reutilize configurações e organize operações
- Observers: Adicione participantes que apenas monitoram
📋 Índice
- Configuração Inicial
- Upload de Documentos
- Criação de Operações
- Tipos de Posicionamento
- Tipos de Assinatura
- Autenticação (2FA)
- Formulários Dinâmicos
- Anexos
- Gerenciamento de Operações
- Download de Documentos
- Configurações Avançadas
- Exemplos Completos
- Referência Rápida
🔧 Configuração Inicial
Requisitos
- .NET Framework 4.5+ ou .NET Core/Standard 2.0+
- .NET 5, 6, 7 ou 8
- API Key da ForSign (obtenha no painel de desenvolvedor)
Instalação via NuGet
dotnet add package ForSign.Sdk
Ou
Install-Package ForSign.Sdk
Configuração Básica
using ForSign.Sdk;
// 1. Criar cliente
var client = new ForSignClient();
// 2. Configurar credencial
const string API_KEY = "SUA_API_KEY_AQUI";
var credential = new ApiKeyCredential(API_KEY);
client.SetCredential(credential);
// 3. Autenticar (recomendado)
try
{
await client.AuthenticateAsync();
Console.WriteLine("Autenticação bem-sucedida!");
}
catch (Exception ex)
{
Console.WriteLine($"Erro: {ex.Message}");
return;
}
⚠️ Segurança: Nunca exponha sua API Key em código front-end ou repositórios públicos. Use variáveis de ambiente ou cofres de segredos.
📤 Upload de Documentos
A ForSign aceita apenas arquivos PDF com tamanho máximo de 10 MB.
Método 1: Upload de Arquivo Local
var fileRequest = UploadFileRequest.AddFileFromPath("/caminho/completo/documento.pdf");
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
Método 2: Upload de URL
var fileRequest = await UploadFileRequest.AddFileFromUrlAsync(
"https://exemplo.com/documento.pdf",
"documento.pdf"
);
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
Método 3: Upload de Bytes
byte[] pdfBytes = File.ReadAllBytes("documento.pdf");
var fileRequest = await UploadFileRequest.AddFileFromBytesAsync(pdfBytes, "documento.pdf");
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
Método 4: Upload de Base64
string base64Content = "JVBERi0xLjQKJ..."; // Base64 do PDF
var fileRequest = await UploadFileRequest.AddFileFromBase64Async("documento.pdf", base64Content);
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
Método 5: Upload de Stream
using var memoryStream = new MemoryStream(pdfBytes);
var fileRequest = await UploadFileRequest.AddFileFromStreamAsync(memoryStream, "documento.pdf");
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
🏗️ Criação de Operações
Use o OperationRequestBuilder para construir operações de forma fluente:
var operation = OperationRequestBuilder
.InitializeWithName("Título da Operação")
.SetExpirationDate(DateTime.Now.AddDays(30))
.WithExternalId("MEU-ID-123")
.SetSignersOrderRequirement(true)
.SetInPersonSigning(false)
.SetLanguage(Language.Portuguese)
.SetDisplayCover(true)
.EnableMemberActionNotifications(true)
.WithOptionalMessage("Mensagem aos signatários")
.WithRedirectUrl("https://seusite.com/sucesso/{operationId}")
.AddSigner(signer1)
.AddSigner(signer2)
.AddObserver("Nome", "email@exemplo.com")
.AddToGroup(groupId)
.SetManualFinish(true)
.Build();
var response = await client.CreateOperationAsync(operation);
// Obter URLs de assinatura
foreach (var member in response.Members)
{
Console.WriteLine($"{member.Name}: {member.SignUrl}");
}
📍 Tipos de Posicionamento
Opção 1: Assinaturas com Tags (Dinâmico) ⭐ RECOMENDADO
Tags permitem posicionamento dinâmico baseado em marcadores no PDF.
Preparar o PDF
Adicione marcadores no formato {{nome_da_tag}} no seu PDF:
┌────────────────────────────────────┐
│ CONTRATO │
│ │
│ Assinatura: {{assinatura_cliente}}│
│ Rubrica: {{rubrica_cliente}} │
└────────────────────────────────────┘
Configurar no SDK
var signer = new Signer
{
Name = "João Silva",
Email = "joao@exemplo.com",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice)
};
// Assinatura por tag
var signatureTag = new TagPosition(fileInfo, "assinatura_cliente");
signer.SetTagSignaturePosition(signatureTag);
// Rubrica por tag (opcional)
var rubricTag = new TagPosition(fileInfo, "rubrica_cliente");
signer.SetTagRubricPosition(rubricTag);
Regras para nomes de tags:
- ✅ Use apenas:
a-z,A-Z,0-9,-,_ - ❌ Não use: espaços, pontos, caracteres especiais
- Formato no PDF:
{{nome_da_tag}} - Regex de validação:
^[a-zA-Z0-9_-]+$
Quando usar tags:
- ✅ Documentos gerados dinamicamente
- ✅ PDFs com conteúdo variável
- ✅ Contratos onde layout pode mudar
- ✅ Múltiplas assinaturas em páginas diferentes
Opção 2: Assinaturas com Coordenadas (Fixo)
Para posicionamento preciso em templates com layout fixo:
var signer = new Signer
{
Name = "Maria Souza",
Email = "maria@exemplo.com",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice)
};
// Formato: (arquivo, página, X%, Y%)
signer.AddSignatureInPosition(fileInfo, 1, "50%", "80%");
signer.AddSignatureInPosition(fileInfo, 2, "50%", "20%");
// Rubricas
signer.AddRubricInPosition(fileInfo, 1, "10%", "90%");
signer.AddRubricInPosition(fileInfo, 2, "10%", "90%");
Sistema de coordenadas:
- X:
0%(esquerda) a100%(direita) - Y:
0%(topo) a100%(fundo) - Sempre use formato percentual:
"50%","80%"
Quando usar coordenadas:
- ✅ Templates de formulários fixos
- ✅ PDFs sempre com mesmo layout
- ✅ Controle pixel-perfect da posição
- ✅ Documentos de página única
✍️ Tipos de Assinatura
1. Assinatura Padrão (Escolha do Usuário)
signer.SignatureType = new DefaultSignatureType(SignatureType.UserChoice);
// Usuário pode escolher entre desenhar, clicar ou digitar
Opções disponíveis:
SignatureType.UserChoice- Usuário escolhe o métodoSignatureType.Click- Assinatura com um cliqueSignatureType.Draw- Desenhar a assinaturaSignatureType.Text- Digitar o nome
2. Certificado Digital (ICP-Brasil)
signer.SignatureType = new CertificateSignatureType();
Assinatura com certificado digital ICP-Brasil. Oferece o mais alto nível de validade jurídica no Brasil, equivalente à assinatura física.
Características:
- ✅ Validade jurídica máxima (equiparada à assinatura manuscrita)
- ✅ Conformidade com ICP-Brasil
- ✅ Não-repúdio garantido
- ✅ Ideal para contratos de alto valor
Quando usar:
- Contratos que exigem validade jurídica máxima
- Transações financeiras e imobiliárias
- Documentos que serão apresentados em cartórios ou órgãos públicos
- Operações que exigem conformidade regulatória
3. Certificado em Nuvem
signer.SignatureType = new CloudCertificateSignatureType();
Assinatura com certificado digital armazenado na nuvem. Combina a segurança do certificado digital com a conveniência de acesso remoto.
Características:
- ✅ Validade jurídica equivalente ao certificado físico
- ✅ Acesso de qualquer dispositivo
- ✅ Não requer token físico ou cartão
- ✅ Processo de assinatura simplificado
Quando usar:
- Assinaturas remotas com validade jurídica
- Equipes distribuídas geograficamente
- Alto volume de assinaturas
- Processos digitais end-to-end
🔐 Autenticação Dois Fatores (2FA)
Opção 1: Email
signer.DoubleAuthenticationMethod = new EmailDoubleAuthentication("email@exemplo.com");
Um código de segurança será enviado para o email antes da assinatura.
Opção 2: Selfie
signer.DoubleAuthenticationMethod = new SelfieDoubleAuthentication();
O signatário precisará tirar uma selfie para verificação de identidade.
Fluxo do 2FA:
- Signatário acessa URL de assinatura
- Sistema solicita código/selfie
- Após validação, libera assinatura
📝 Formulários Dinâmicos
Campo de Texto
var textField = TextFormField.WithName("Nome Completo")
.WithInstructions("Digite seu nome completo")
.IsRequired()
.WithMaxLength(100)
.WithTextFormat(FrontTypeFormField.Text)
.WithSize(2.5f, 25f) // altura, largura em %
.OnPosition(new FormFieldPosition(fileInfo, 1, "30%", "40%"))
.WithValue("Valor Padrão");
signer.AddFormField(textField);
Formatos de texto disponíveis:
FrontTypeFormField.Text- Texto livreFrontTypeFormField.Number- Apenas númerosFrontTypeFormField.Email- EmailFrontTypeFormField.Phone- TelefoneFrontTypeFormField.Date- Data (DD/MM/YYYY)FrontTypeFormField.DateUs- Data (MM/DD/YYYY)
Campo de Checkbox
var checkbox = CheckboxFormField.WithName("Aceito Termos")
.WithInstructions("Marque se aceita")
.IsRequired()
.WithOptions(new List<string> { "Aceito", "Não aceito" })
.WithSize(2.5f, 25f)
.OnPosition(new FormFieldPosition(fileInfo, 1, "20%", "30%"))
.WithValue("Aceito");
signer.AddFormField(checkbox);
Campo de Seleção (Dropdown)
var selectField = SelectFormField.WithName("Estado")
.WithInstructions("Selecione seu estado")
.IsRequired()
.WithOptions(new List<string> { "SP", "RJ", "MG", "RS" })
.WithSize(2.5f, 25f)
.OnPosition(new FormFieldPosition(fileInfo, 1, "40%", "50%"))
.WithValue("SP");
signer.AddFormField(selectField);
Título e Descrição do Formulário
signer.FormTitle = "Dados Cadastrais";
signer.FormDescription = "Preencha as informações abaixo para prosseguir";
📎 Anexos
Solicitar Anexos
var attachment = new Attachment(
"RG ou CNH",
"Envie foto do documento de identidade",
isRequired: true
);
// Tipos de arquivo permitidos
attachment.PermitFileType(AttachmentFileType.PNG);
attachment.PermitFileType(AttachmentFileType.JPEG);
attachment.PermitFileType(AttachmentFileType.JPG);
attachment.PermitFileType(AttachmentFileType.PDF);
attachment.PermitFileType(AttachmentFileType.DOC);
attachment.PermitFileType(AttachmentFileType.DOCX);
// Métodos de captura/envio
attachment.PermitAttachmentByInput(InputAttachmentType.CameraSideBack);
attachment.PermitAttachmentByInput(InputAttachmentType.CameraSideFront);
attachment.PermitAttachmentByInput(InputAttachmentType.UploadFile);
// Limitar quantidade de arquivos
attachment.MaxFilesAllowed = 2;
signer.RequestAttachment(attachment);
Tipos de input disponíveis:
InputAttachmentType.CameraSideBack- Câmera traseiraInputAttachmentType.CameraSideFront- Câmera frontal (selfie)InputAttachmentType.UploadFile- Upload de arquivo
Listar Anexos de um Membro
long memberId = 12345;
var attachments = await client.GetMemberAttachmentsAsync(memberId);
foreach (var att in attachments)
{
Console.WriteLine($"Anexo: {att.Name} - Enviado: {att.IsUploaded}");
}
Aprovar Anexos
long memberId = 12345;
var attachmentIds = new List<long> { 67890, 98765 };
await client.ApproveAttachmentsAsync(memberId, attachmentIds);
Rejeitar Anexos
long memberId = 12345;
var rejectedList = new List<RejectedAttachment>
{
new RejectedAttachment { Id = 67890, Reason = "Documento ilegível" },
new RejectedAttachment { Id = 98765, Reason = "Formato inválido" }
};
await client.RejectAttachmentsAsync(memberId, rejectedList);
Baixar Anexo
long attachmentId = 67890;
var download = await client.DownloadAttachmentAsync(attachmentId);
// Salvar arquivo
File.WriteAllBytes(download.FileName, download.Content);
Console.WriteLine($"ContentType: {download.ContentType}");
🔧 Gerenciamento de Operações
Finalizar Operação Manualmente
long operationId = 12345;
await client.CompleteOperationAsync(operationId);
Console.WriteLine("Operação finalizada!");
Nota: Todos os signatários obrigatórios devem ter assinado antes.
Cancelar Operação
long operationId = 12345;
await client.CancelOperationAsync(operationId, "Cancelamento solicitado pelo cliente");
Configurar Finalização Automática
long operationId = 12345;
DateTime endDate = DateTime.Now.AddDays(7);
await client.SetOperationAutomaticCompletionAsync(operationId, endDate);
Nota: A data deve ser pelo menos 1 hora no futuro.
Configurar Finalização Manual
long operationId = 12345;
await client.SetOperationManualCompletionAsync(operationId);
Isso altera uma operação de finalização automática para manual.
📥 Download de Documentos
Download do ZIP da Operação
long operationId = 12345;
var zipResponse = await client.DownloadOperationZipAsync(operationId);
O ZIP contém:
- Documento(s) assinado(s)
- Trilha de auditoria (audit trail)
- Anexos enviados pelos signatários
- Formulários preenchidos (CSV)
Forma 1: Converter Base64 Manualmente
byte[] zipBytes = Convert.FromBase64String(zipResponse.Base64File);
File.WriteAllBytes("operacao.zip", zipBytes);
Forma 2: Usar Método de Extensão (RECOMENDADO)
byte[] zipBytes = zipResponse.GetZipBytes();
File.WriteAllBytes("operacao.zip", zipBytes);
Forma 3: Salvar Diretamente em Arquivo
zipResponse.SaveToFile("/caminho/completo/arquivo.zip");
Forma 4: Salvar em Diretório (Nome Automático)
string savedPath = zipResponse.SaveToDirectory("/caminho/diretorio");
Console.WriteLine($"Arquivo salvo em: {savedPath}");
⚙️ Configurações Avançadas
1. Idioma da Interface
.SetLanguage(Language.Portuguese)
// Opções: Portuguese, English, Spanish
Define o idioma da interface de assinatura e notificações.
2. Exibir/Ocultar Capa Inicial
.SetDisplayCover(true) // ou false
A capa mostra informações da operação antes de iniciar.
3. Ordem de Assinatura
.SetSignersOrderRequirement(true)
true= signatários devem assinar na ordem adicionadafalse= podem assinar em qualquer ordem
4. Assinatura Presencial
.SetInPersonSigning(true)
true= todos assinam no mesmo dispositivo simultaneamentefalse= assinam remotamente
5. URL de Redirecionamento
.WithRedirectUrl("https://seusite.com/sucesso/{operationId}/{externalId}")
Parâmetros dinâmicos:
{operationId}- Substituído pelo ID da operação{externalId}- Substituído pelo ID externo (se definido)
Segurança: Sempre use HTTPS.
6. ID Externo
.WithExternalId("SEU-CODIGO-123")
Útil para correlacionar com seu sistema interno.
7. Adicionar a Grupos
.AddToGroup(groupId)
// ou adicionar a múltiplos grupos
.AddToGroups(new List<long> { group1, group2, group3 })
Organize operações em grupos para melhor gestão.
8. Adicionar Observadores
.AddObserver("Nome do Monitor", "monitor@empresa.com")
Observadores recebem notificações mas não precisam assinar.
9. Notificações de Ações dos Membros
.EnableMemberActionNotifications(true)
Receba notificações quando signatários:
- Visualizam o documento
- Completam assinatura
- Rejeitam documento
- Enviam formulários
10. Mensagem Opcional
.WithOptionalMessage("Por favor, revise e assine até o dia 30/01.")
Mensagem personalizada exibida aos signatários.
11. Finalização Manual
.SetManualFinish(true)
true= você deve chamarCompleteOperationAsync()para finalizarfalse= finaliza automaticamente quando todos assinarem
12. Data de Expiração
.SetExpirationDate(DateTime.Now.AddDays(30))
Após essa data, a operação expira se não for finalizada.
13. Metadados Personalizados
.AddMetadata("chave", "valor")
.AddMetadata("departamento", "vendas")
.AddMetadata("contrato_tipo", "locacao")
Adicione dados customizados à operação.
📚 Exemplos Completos
Exemplo 1: Contrato Simples com Tags
using ForSign.Sdk;
var client = new ForSignClient();
client.SetCredential(new ApiKeyCredential("SUA_API_KEY"));
await client.AuthenticateAsync();
// Upload do documento que contém {{assinatura_cliente}}
var fileRequest = await UploadFileRequest.AddFileFromUrlAsync(
"https://exemplo.com/contrato-tags.pdf",
"contrato.pdf"
);
var upload = await client.UploadFileAsync(fileRequest);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
// Configurar signatário com tag
var signer = new Signer
{
Name = "João Cliente",
Email = "joao@cliente.com",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice),
DoubleAuthenticationMethod = new EmailDoubleAuthentication("joao@cliente.com")
};
var signTag = new TagPosition(fileInfo, "assinatura_cliente");
signer.SetTagSignaturePosition(signTag);
// Criar operação
var operation = OperationRequestBuilder
.InitializeWithName("Contrato de Serviços - João")
.SetLanguage(Language.Portuguese)
.SetExpirationDate(DateTime.Now.AddDays(15))
.AddSigner(signer)
.Build();
var response = await client.CreateOperationAsync(operation);
Console.WriteLine($"URL: {response.Members[0].SignUrl}");
Exemplo 2: Workflow Completo com Formulários e Anexos
var client = new ForSignClient();
client.SetCredential(new ApiKeyCredential("SUA_API_KEY"));
await client.AuthenticateAsync();
// Upload
var upload = await client.UploadFileAsync(
await UploadFileRequest.AddFileFromUrlAsync(
"https://exemplo.com/cadastro.pdf",
"cadastro.pdf"
)
);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
// Signatário com tudo
var signer = new Signer
{
Name = "Maria Silva",
Email = "maria@exemplo.com",
Phone = "11987654321",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice),
DoubleAuthenticationMethod = new SelfieDoubleAuthentication(),
FormTitle = "Dados Pessoais",
FormDescription = "Preencha suas informações"
};
// Assinatura
signer.AddSignatureInPosition(fileInfo, 1, "50%", "80%");
// Formulário - CPF
var cpfField = TextFormField.WithName("CPF")
.IsRequired()
.WithMaxLength(14)
.WithTextFormat(FrontTypeFormField.Number)
.OnPosition(new FormFieldPosition(fileInfo, 1, "30%", "40%"));
signer.AddFormField(cpfField);
// Formulário - Estado
var estadoField = SelectFormField.WithName("Estado")
.IsRequired()
.WithOptions(new List<string> { "SP", "RJ", "MG" })
.OnPosition(new FormFieldPosition(fileInfo, 1, "30%", "50%"));
signer.AddFormField(estadoField);
// Anexo - RG
var rg = new Attachment("RG", "Envie foto do RG", true);
rg.PermitFileType(AttachmentFileType.JPEG);
rg.PermitFileType(AttachmentFileType.PNG);
rg.PermitAttachmentByInput(InputAttachmentType.UploadFile);
signer.RequestAttachment(rg);
// Criar operação
var operation = OperationRequestBuilder
.InitializeWithName("Cadastro Completo - Maria")
.SetExpirationDate(DateTime.Now.AddDays(7))
.WithRedirectUrl("https://meusite.com/sucesso/{operationId}")
.SetLanguage(Language.Portuguese)
.AddSigner(signer)
.Build();
var response = await client.CreateOperationAsync(operation);
// Aguardar assinatura e anexos...
// Depois, baixar documentos
await Task.Delay(TimeSpan.FromMinutes(5)); // Simulando espera
var zip = await client.DownloadOperationZipAsync(response.Id);
zip.SaveToDirectory("./downloads");
Exemplo 3: Assinatura com Certificado Digital
var client = new ForSignClient();
client.SetCredential(new ApiKeyCredential("SUA_API_KEY"));
await client.AuthenticateAsync();
var upload = await client.UploadFileAsync(
await UploadFileRequest.AddFileFromUrlAsync(
"https://exemplo.com/contrato-alto-valor.pdf",
"contrato.pdf"
)
);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
// Assinatura com Certificado Digital ICP-Brasil
var signerCertificado = new Signer
{
Name = "Dr. Ricardo Oliveira",
Email = "ricardo@oliveira.com",
SignatureType = new CertificateSignatureType(), // ← Certificado Digital
DoubleAuthenticationMethod = new EmailDoubleAuthentication("ricardo@oliveira.com")
};
signerCertificado.AddSignatureInPosition(fileInfo, 1, "50%", "70%");
// Assinatura com Certificado em Nuvem
var signerNuvem = new Signer
{
Name = "Ana Paula Santos",
Email = "ana@santos.com",
SignatureType = new CloudCertificateSignatureType(), // ← Certificado Nuvem
};
signerNuvem.AddSignatureInPosition(fileInfo, 1, "50%", "85%");
// Criar operação
var operation = OperationRequestBuilder
.InitializeWithName("Contrato com Certificado Digital")
.SetExpirationDate(DateTime.Now.AddDays(30))
.AddSigner(signerCertificado)
.AddSigner(signerNuvem)
.Build();
var response = await client.CreateOperationAsync(operation);
foreach (var member in response.Members)
{
Console.WriteLine($"{member.Name}: {member.SignUrl}");
}
Exemplo 4: Múltiplos Signatários com Ordem
var client = new ForSignClient();
client.SetCredential(new ApiKeyCredential("SUA_API_KEY"));
await client.AuthenticateAsync();
var upload = await client.UploadFileAsync(
await UploadFileRequest.AddFileFromUrlAsync(
"https://exemplo.com/contrato.pdf",
"contrato.pdf"
)
);
var fileInfo = new FileInformation(upload.Data.Id, upload.Data.FileName);
// Primeiro signatário: Empresa
var empresa = new Signer
{
Name = "Empresa XYZ Ltda",
Email = "contato@empresa.com",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice)
};
empresa.AddSignatureInPosition(fileInfo, 1, "30%", "80%");
// Segundo signatário: Cliente
var cliente = new Signer
{
Name = "João Silva",
Email = "joao@silva.com",
SignatureType = new DefaultSignatureType(SignatureType.UserChoice),
DoubleAuthenticationMethod = new EmailDoubleAuthentication("joao@silva.com")
};
cliente.AddSignatureInPosition(fileInfo, 1, "70%", "80%");
// Operação com ordem de assinatura
var operation = OperationRequestBuilder
.InitializeWithName("Contrato Bilateral")
.SetSignersOrderRequirement(true) // Empresa assina primeiro
.SetExpirationDate(DateTime.Now.AddDays(30))
.AddSigner(empresa)
.AddSigner(cliente)
.Build();
var response = await client.CreateOperationAsync(operation);
foreach (var member in response.Members)
{
Console.WriteLine($"{member.Name}: {member.SignUrl}");
}
🚨 Tratamento de Erros
try
{
var response = await client.CreateOperationAsync(operation);
}
catch (ForSignApiException ex)
{
Console.WriteLine($"Erro da API ForSign: {ex.Message}");
Console.WriteLine($"Status Code: {ex.StatusCode}");
// Detalhes adicionais
if (ex.ErrorResponse?.Messages != null)
{
foreach (var msg in ex.ErrorResponse.Messages)
{
Console.WriteLine($" {msg.Key}: {msg.Value}");
}
}
}
catch (Exception ex)
{
Console.WriteLine($"Erro inesperado: {ex.Message}");
}
Códigos de status comuns:
400 Bad Request- Dados inválidos401 Unauthorized- API Key inválida402 Payment Required- Créditos insuficientes403 Forbidden- Sem permissão404 Not Found- Operação não encontrada500 Internal Server Error- Erro no servidor
📋 Referência Rápida
Tipos de Assinatura
SignatureType.UserChoice- Usuário escolheSignatureType.Click- CliqueSignatureType.Draw- DesenhoSignatureType.Text- TextoCertificateSignatureType- Certificado Digital (ICP-Brasil)CloudCertificateSignatureType- Certificado em Nuvem
Tipos de Formulário
TextFormField- Campo de textoSelectFormField- Lista de seleçãoCheckboxFormField- Checkbox
Formatos de Campo de Texto
FrontTypeFormField.Text- Texto livreFrontTypeFormField.Number- NúmeroFrontTypeFormField.Email- EmailFrontTypeFormField.Phone- TelefoneFrontTypeFormField.Date- Data (DD/MM/YYYY)FrontTypeFormField.DateUs- Data (MM/DD/YYYY)
Tipos de Arquivo para Anexos
AttachmentFileType.PNGAttachmentFileType.JPEGAttachmentFileType.JPGAttachmentFileType.PDFAttachmentFileType.DOCAttachmentFileType.DOCX
Métodos de Input de Anexos
InputAttachmentType.CameraSideBack- Câmera traseiraInputAttachmentType.CameraSideFront- Câmera frontalInputAttachmentType.UploadFile- Upload
Idiomas
Language.Portuguese- Português (pt-BR)Language.English- Inglês (en)Language.Spanish- Espanhol (es)
Canais de Notificação
NotificationChannel.Email- E-mailNotificationChannel.None- Sem notificação
Canais de Autenticação
AuthenticationChannel.Email- E-mailAuthenticationChannel.Selfie- Selfie
⚠️ Regras e Limitações
Arquivos
- Formato: Apenas PDF
- Tamanho: Máximo 10 MB
Tags
- Formato:
{{nome_da_tag}} - Caracteres permitidos:
a-z,A-Z,0-9,-,_ - Não use: espaços, pontos, caracteres especiais
Coordenadas
- Formato: Sempre percentual (
"50%","80%") - X: 0% (esquerda) a 100% (direita)
- Y: 0% (topo) a 100% (fundo)
URLs de Redirecionamento
- Devem começar com
http://ouhttps:// - Parâmetros dinâmicos:
{operationId},{externalId} - Recomendado: sempre use HTTPS
🔐 Boas Práticas
Segurança
- Nunca exponha API Key em código front-end
- Use variáveis de ambiente ou cofres de segredos
- Sempre use HTTPS para redirect URLs
- Habilite 2FA para operações importantes
Performance
- Reutilize a mesma instância de
ForSignClient - O SDK gerencia cache de token automaticamente
- Use upload por URL quando possível (evita tráfego)
Confiabilidade
- Configure webhooks para atualizações em tempo real
- Sempre trate exceções
ForSignApiException - Use
ExternalIdpara correlação com seu sistema - Configure data de expiração adequada
UX
- Configure mensagens personalizadas
- Use redirect URLs para melhor experiência
- Escolha idioma adequado ao público
- Forneça instruções claras em formulários
🌐 Webhooks
A forma mais eficiente de monitorar operações é através de Webhooks.
Como funciona:
- Configure uma URL no painel de desenvolvedor
- ForSign enviará POST para essa URL em eventos importantes
- Sua aplicação recebe notificações em tempo real
Eventos comuns:
- Operação criada
- Signatário visualizou documento
- Signatário assinou
- Operação finalizada
- Operação cancelada
- Anexo enviado
Isso elimina necessidade de polling (consultar status repetidamente).
📞 Suporte
- Documentação da API: https://api.forsign.digital/docs
- Email: suporte@forsign.digital
- Issues: GitHub Issues
- Painel: Acesse o painel de desenvolvedor para obter API Key
📝 Changelog
v2.1.3 (2025-12-18)
- ✨ NOVO: Suporte para assinaturas com tags
- ✨ NOVO: Métodos de extensão para
OperationZipResponse - ✨ NOVO: Suporte para rubricas com tags
- 🐛 FIX: Correção de processamento de tags
- 📚 DOCS: Documentação completamente atualizada
v2.0.0
- Versão inicial pública do SDK
📄 Licença
Este projeto está licenciado sob a MIT License.
<p align="center"> <strong>Desenvolvido com ❤️ pela equipe ForSign</strong><br> <a href="https://forsign.digital">forsign.digital</a> </p>
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net5.0 is compatible. net5.0-windows was computed. net6.0 is compatible. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 is compatible. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
| .NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 is compatible. netcoreapp3.1 was computed. |
| .NET Standard | netstandard2.0 is compatible. netstandard2.1 was computed. |
| .NET Framework | net45 is compatible. net451 is compatible. net452 is compatible. net46 is compatible. net461 is compatible. net462 is compatible. net463 was computed. net47 is compatible. net471 was computed. net472 is compatible. net48 is compatible. net481 is compatible. |
| MonoAndroid | monoandroid was computed. |
| MonoMac | monomac was computed. |
| MonoTouch | monotouch was computed. |
| Tizen | tizen40 was computed. tizen60 was computed. |
| Xamarin.iOS | xamarinios was computed. |
| Xamarin.Mac | xamarinmac was computed. |
| Xamarin.TVOS | xamarintvos was computed. |
| Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETCoreApp 3.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
-
.NETFramework 4.5
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.5.1
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.5.2
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.6
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.6.1
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.6.2
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.7
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.7.2
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.8
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETFramework 4.8.1
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 6.35.0)
- System.Net.Http (>= 4.3.4)
-
.NETStandard 2.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
-
net5.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
-
net6.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
-
net7.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
-
net8.0
- Newtonsoft.Json (>= 13.0.3)
- System.IdentityModel.Tokens.Jwt (>= 7.2.0)
- System.Runtime.Caching (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 2.0.6 | 89 | 12/29/2025 |
| 2.0.5 | 172 | 12/23/2025 |
| 2.0.4 | 269 | 12/18/2025 |
| 2.0.3 | 267 | 12/18/2025 |
| 2.0.2 | 277 | 9/19/2025 |
| 2.0.1 | 253 | 9/19/2025 |
| 2.0.0 | 248 | 9/19/2025 |
| 1.0.6 | 304 | 2/2/2024 |
| 1.0.5 | 191 | 1/26/2024 |
| 1.0.4 | 164 | 1/26/2024 |
| 1.0.3 | 178 | 1/19/2024 |
| 1.0.2 | 171 | 1/19/2024 |
| 1.0.1 | 174 | 1/18/2024 |
| 0.1.4 | 174 | 1/26/2024 |
Version 2.0.3 brings major updates to signature types and comprehensive documentation:
**New Signature Types:**
- Certificate: Digital certificate signature (ICP-Brasil compliant) for maximum legal validity
- CloudCertificate: Cloud-based digital certificate for convenient remote signing
**Documentation:**
- Complete overhaul of SDK documentation (1,000+ lines)
- Added 4 complete end-to-end examples
- Comprehensive coverage of all SDK features including tags, certificates, forms, attachments, and advanced configurations
- Updated Quick Reference guide
- Added detailed usage guides for all signature types
**Breaking Changes:**
- None - fully backward compatible
**Improvements:**
- Enhanced code documentation with XML comments
- Better organization of signature type classes
- Improved examples and use cases
For migration guide and full documentation, visit: https://github.com/forsign/sdk-dotnet