Guias de Desenvolvimento

Signing Sessions

Guias dos SDKs

Certificado Digital — DIGITAL_CERTIFICATE

Assinatura digital qualificada com certificado ICP-Brasil A1. Produz PDF assinado no padrão PAdES.


O que é

O perfil DIGITAL_CERTIFICATE adiciona assinatura digital com certificado ICP-Brasil A1 após o aceite do documento. O signatário clica "Aceitar", seleciona seu certificado (.pfx) e assina digitalmente. O resultado é um PDF assinado no padrão PAdES, verificável pelo Validador ITI e Adobe Acrobat.

Signatário clica "Aceitar" ──> Seleciona certificado ──> Assina localmente ──> COMPLETED

Requisitos

CampoObrigatórioNotas
nameSimNome completo
cpfSimCPF do signatário
userExternalIdSimID no seu sistema

Pré-requisito: Certificado ICP-Brasil A1 (arquivo .pfx) instalado no dispositivo do signatário.


Criar a sessão

Fluxo hospedado (recomendado)

A página hospedada gerencia a seleção do certificado e a assinatura local. Seu backend só cria e espera.

const pdfBase64 = readFileSync('contrato.pdf').toString('base64');

const session = await client.signingSessions.create({
  purpose: 'DOCUMENT_SIGNATURE',
  policy: { profile: 'DIGITAL_CERTIFICATE' },
  signer: {
    name: 'Ana Pereira',
    cpf: '98765432100',
    userExternalId: 'user-004',
  },
  document: { content: pdfBase64, filename: 'contrato.pdf' },
  returnUrl: 'https://app.example.com/done',
  locale: 'pt-BR',
  expiresInMinutes: 60,
});

console.log('Client Secret:', session.clientSecret);

const result = await client.signingSessions.waitForCompletion(session.sessionId);
console.log('Status:', result.status);       // COMPLETED
console.log('Evidence ID:', result.evidenceId);
session = client.signing_sessions.create(CreateSigningSessionRequest(
    purpose='DOCUMENT_SIGNATURE',
    policy=Policy(profile='DIGITAL_CERTIFICATE'),
    signer=Signer(name='Ana Pereira', cpf='98765432100', user_external_id='user-004'),
    document=InlineDocument(content=pdf_base64, filename='contrato.pdf'),
    return_url='https://app.example.com/done',
    locale='pt-BR',
    expires_in_minutes=60,
))

print('Client Secret:', session.client_secret)

result = client.signing_sessions.wait_for_completion(session.session_id)
print('Status:', result.status)       # COMPLETED
print('Evidence ID:', result.evidence_id)
session, err := client.SigningSessions.Create(ctx, &signdocs.CreateSigningSessionRequest{
    Purpose:          signdocs.PurposeDocumentSignature,
    Policy:           signdocs.Policy{Profile: signdocs.PolicyProfileDigitalCertificate},
    Signer:           signdocs.Signer{Name: "Ana Pereira", CPF: "98765432100", UserExternalID: "user-004"},
    Document:         &signdocs.DocumentInline{Content: pdfBase64, Filename: "contrato.pdf"},
    ReturnURL:        "https://app.example.com/done",
    Locale:           "pt-BR",
    ExpiresInMinutes: 60,
})
if err != nil { log.Fatal(err) }

fmt.Println("Client Secret:", session.ClientSecret)

result, err := client.SigningSessions.WaitForCompletion(ctx, session.SessionID)
if err != nil { log.Fatal(err) }
fmt.Println("Status:", result.Status)       // COMPLETED
fmt.Println("Evidence ID:", result.EvidenceID)
String pdfBase64 = Base64.getEncoder().encodeToString(Files.readAllBytes(Path.of("contrato.pdf")));

CreateSigningSessionRequest request = new CreateSigningSessionRequest();
request.purpose = "DOCUMENT_SIGNATURE";
request.policy = new Policy("DIGITAL_CERTIFICATE");
request.signer = new Signer("Ana Pereira", "user-004");
request.signer.cpf = "98765432100";
request.document = new CreateSigningSessionRequest.InlineDocument(pdfBase64, "contrato.pdf");
request.returnUrl = "https://app.example.com/done";
request.locale = "pt-BR";
request.expiresInMinutes = 60;

SigningSession session = client.signingSessions().create(request);
System.out.println("Client Secret: " + session.clientSecret);

SigningSessionStatusResponse result = client.signingSessions().waitForCompletion(session.sessionId);
System.out.println("Status: " + result.status);       // COMPLETED
System.out.println("Evidence ID: " + result.evidenceId);
$pdfBase64 = base64_encode(file_get_contents('contrato.pdf'));

$session = $client->signingSessions->create(new CreateSigningSessionRequest(
    purpose: 'DOCUMENT_SIGNATURE',
    policy: new Policy(profile: 'DIGITAL_CERTIFICATE'),
    signer: new Signer(name: 'Ana Pereira', cpf: '98765432100', userExternalId: 'user-004'),
    document: ['content' => $pdfBase64, 'filename' => 'contrato.pdf'],
    returnUrl: 'https://app.example.com/done',
    locale: 'pt-BR',
    expiresInMinutes: 60,
));

echo "Client Secret: " . $session->clientSecret . "\n";

$result = $client->signingSessions->waitForCompletion($session->sessionId);
echo "Status: " . $result->status . "\n";       // COMPLETED
echo "Evidence ID: " . $result->evidenceId . "\n";
var pdfBase64 = Convert.ToBase64String(await File.ReadAllBytesAsync("contrato.pdf"));

var session = await client.SigningSessions.CreateAsync(new CreateSigningSessionRequest
{
    Purpose = "DOCUMENT_SIGNATURE",
    Policy = new Policy { Profile = "DIGITAL_CERTIFICATE" },
    Signer = new Signer { Name = "Ana Pereira", Cpf = "98765432100", UserExternalId = "user-004" },
    Document = new InlineDocument { Content = pdfBase64, Filename = "contrato.pdf" },
    ReturnUrl = "https://app.example.com/done",
    Locale = "pt-BR",
    ExpiresInMinutes = 60,
});

Console.WriteLine($"Client Secret: {session.ClientSecret}");

var result = await client.SigningSessions.WaitForCompletionAsync(session.SessionId);
Console.WriteLine($"Status: {result.Status}");       // COMPLETED
Console.WriteLine($"Evidence ID: {result.EvidenceId}");

Experiência do signatário

A página hospedada mostra o PDF, o signatário clica "Aceitar", a interface solicita a seleção do certificado A1, o protocolo de assinatura em duas fases é executado (prepare → sign → complete), e o PDF assinado é gerado.


Metadados da assinatura digital

Você pode opcionalmente passar metadados de assinatura digital no campo digitalSignature:

digitalSignature: {
  reason: 'Concordo com os termos deste contrato',
  location: 'São Paulo, SP',
  contactInfo: 'ana@example.com',
},

Detalhes técnicos


← Biometria + OTP  |  Próximo: Biometria SERPRO →

Voltar para Visão Geral