SignDocs Brasil

Descrição

O SignDocs Brasil é o plugin oficial do WordPress para assinaturas eletrônicas com validade jurídica no Brasil. Incorpore fluxos de assinatura em qualquer página com um shortcode ou bloco Gutenberg, envie envelopes multi-signatário (sequenciais ou paralelos), verifique evidências assinadas direto no painel do WordPress e acompanhe tudo por um log de auditoria com exportação para CSV.

Construído sobre o SDK PHP oficial do SignDocs Brasil (signdocs-brasil/signdocs-brasil-php), o plugin aproveita cache de token OAuth compartilhado entre os workers do PHP-FPM, idempotência determinística, rotação de segredo de webhook com janela de tolerância e observabilidade via cabeçalhos de resposta RateLimit-* / Deprecation / Sunset.

O plugin é voltado ao mercado brasileiro (conformidade com a MP 2.200-2/2001, ICP-Brasil, NT65/ITI para o crédito consignado do INSS), mas funciona para qualquer fluxo de assinatura no mundo. A interface de assinatura é hospedada em sign.signdocs.com.br, isolada da sua instalação WordPress — assim, um site WordPress comprometido não consegue forjar assinaturas.

Por que SignDocs Brasil?

  • Conformidade brasileira — MP 2.200-2/2001, pacote de evidências PKCS#7/CMS, suporte a certificado ICP-Brasil A1/A3, fluxo NT65/ITI para crédito consignado do INSS
  • Sete políticas de verificação — CLICK_ONLY, CLICK_PLUS_OTP, BIOMETRIC, BIOMETRIC_PLUS_OTP, DIGITAL_CERTIFICATE, BIOMETRIC_SERPRO, BIOMETRIC_SERPRO_AUTO_FALLBACK
  • Envelopes multi-signatário — sequenciais (cada signatário aguarda o anterior) ou paralelos (todos assinam ao mesmo tempo), com download consolidado em .p7s ou PDF combinado ao final
  • Dois modos de autenticação — OAuth2 client_credentials (simples) ou Private Key JWT ES256 (para clientes regulados que não podem armazenar segredos compartilhados)
  • Integração WooCommerce — envia o link de assinatura por email automaticamente após a conclusão do pedido
  • Trilha de auditoria completa — toda chamada de API e toda entrega de webhook são registradas em uma tabela dedicada, com visão filtrável (WP_List_Table) e exportação para CSV
  • GDPR / LGPD — handlers de exportação e de eliminação de dados registrados no painel de privacidade do WordPress
  • Observabilidade — cabeçalhos RateLimit-* capturados para o widget do painel; avisos de descontinuação (RFC 8594 Deprecation / Sunset) aparecem como avisos no admin
  • Zero código — configure tudo pelo painel do WordPress

Funcionalidades

  • Shortcode [signdocs] e bloco Gutenberg para incorporar o botão de assinatura em qualquer página ou post
  • Custom post type signdocs_envelope para fluxos multi-signatário com repetidor de signatários
  • Página administrativa “Verificar Documento” — cole um ID de evidência ou de envelope e inspecione identidades dos signatários, CNPJ do tenant e downloads consolidados
  • Log de auditoria com filtros por nível, tipo de evento e intervalo de datas, além de exportação em CSV por streaming (via php://output, segura para exportações de vários GB)
  • Rotação de segredo de webhook com janela de tolerância de 7 dias — ambos os segredos (atual + anterior) são aceitos durante a rotação
  • Cobertura dos 17 tipos de evento de webhook, incluindo os eventos NT65 (STEP.PURPOSE_DISCLOSURE_SENT, TRANSACTION.DEADLINE_APPROACHING)
  • Capacidades personalizadas (signdocs_manage, signdocs_send, signdocs_verify, signdocs_view_logs) concedidas automaticamente a administrador / editor / autor
  • Comandos WP-CLI (wp signdocs health | send | status | webhook-test | log-tail) para automação via shell
  • Integração WooCommerce — aba de produto “Assinatura SignDocs”, email automático com o link de assinatura e notas de pedido após a conclusão
  • Popup, redirecionamento ou overlay — escolha o modo de incorporação que combina com o seu tema
  • Assinatura anônima opcional, com limitação de taxa (rate limiting)
  • Credenciais criptografadas com AES-256-CBC em wp_options
  • Receptor de webhook reforçado: trava de desvio de timestamp (≤300s), verificação HMAC-SHA256 com comparação em tempo constante, deduplicação contra replay via X-SignDocs-Webhook-Id
  • Cache de token OAuth compartilhado via transients do WordPress (WpTransientTokenCache implementa a TokenCacheInterface do SDK) — um único token reaproveitado por todos os workers do PHP-FPM
  • Chaves de idempotência determinísticas em toda chamada que cria recursos — retentativas via AJAX nunca criam sessões duplicadas
  • Observador de descontinuação (RFC 8594) que exibe um aviso no admin quando a API sinaliza a remoção de um endpoint
  • Traduzível: Inglês, Português (Brasil), Espanhol

Casos de uso

  • Escritórios de advocacia — procurações, contratos, termos e envelopes multi-parte
  • Imobiliárias — contratos de locação e de compra/venda assinados por inquilino, proprietário e fiador (envelope sequencial)
  • E-commerce — termos de serviço, contratos de fornecedor, NDAs pós-compra
  • RH e departamento pessoal — contratos de trabalho, termos de confidencialidade, documentação de onboarding
  • Educação — fichas de matrícula e autorização dos responsáveis (responsáveis + aluno em envelope paralelo)
  • SaaS — termos de uso e contratos de licença no onboarding
  • Crédito consignado do INSS (específico do Brasil) — fluxo NT65 com verificação biométrica SERPRO e notificação de averbação da finalidade
  • Bancos e instituições financeiras — o Private Key JWT permite assinar sem armazenar um segredo compartilhado no banco de dados

Como funciona

  1. Configure as credenciais da API SignDocs Brasil no painel do WordPress (Client ID + Secret, ou Chave Privada + Key ID)
  2. Adicione um shortcode, um bloco Gutenberg ou crie um envelope multi-signatário pelo admin
  3. O signatário clica em “Assinar Documento” e é redirecionado ao domínio seguro sign.signdocs.com.br (a assinatura nunca acontece dentro do seu site WordPress — isso isola a sua instalação de qualquer comprometimento)
  4. O signatário conclui o fluxo conforme a política configurada (aceite, OTP, biometria, certificado digital)
  5. Os webhooks atualizam o status no painel do WordPress em tempo real; o pacote de evidências .p7m fica disponível para download e verificação

Links

Uso

Shortcode

Adicione em qualquer página ou post:

[signdocs document_id="123" policy="CLICK_ONLY" button_text="Sign Contract"]

Com formulário de nome / email / CPF:

[signdocs document_id="123" show_form="true" policy="CLICK_PLUS_OTP"]

Atributos disponíveis:

  • document_id (obrigatório) — ID do anexo PDF na biblioteca de mídia
  • policy — uma de: CLICK_ONLY, CLICK_PLUS_OTP, BIOMETRIC, BIOMETRIC_PLUS_OTP, DIGITAL_CERTIFICATE, BIOMETRIC_SERPRO, BIOMETRIC_SERPRO_AUTO_FALLBACK
  • locale — idioma: pt-BR, en, es
  • mode — modo de incorporação: redirect (padrão), popup, overlay
  • button_text — rótulo do botão (padrão: “Assinar Documento”)
  • show_form"true" para exibir campos de nome / email / CPF / CNPJ
  • return_url — URL de redirecionamento após a assinatura
  • class — classe CSS adicional para o botão

Bloco Gutenberg

  1. No editor de blocos, clique em “+” para adicionar um bloco
  2. Pesquise por “SignDocs” ou “Assinatura”
  3. Selecione um PDF na barra lateral à direita
  4. Configure a política, o idioma e o modo
  5. Publique a página

Envelopes multi-signatário

Para contratos com mais de um signatário (por exemplo, proprietário + inquilino + fiador), use o menu Envelopes:

  1. Painel > Assinaturas > Envelopes > Adicionar Novo
  2. Selecione o modo de assinatura:
    • SEQUENTIAL — cada signatário assina em ordem; o próximo só recebe o link quando o anterior conclui
    • PARALLEL — todos os signatários podem assinar simultaneamente, em qualquer ordem
  3. Adicione os signatários (nome + email + CPF ou CNPJ + política opcional por signatário)
  4. Anexe o PDF e publique
  5. Cada signatário recebe um email com o link individual; o admin vê o status do envelope atualizar conforme cada assinatura é concluída
  6. Após todos assinarem, um PDF combinado e carimbado (ou um .p7s consolidado, para documentos não-PDF) fica disponível para download

Os eventos de webhook STEP.STARTED, STEP.COMPLETED e STEP.FAILED são registrados por signatário no log de cada envelope.

WooCommerce

  1. Edite um produto e abra a aba “Assinatura SignDocs”
  2. Marque “Requer assinatura” e selecione o PDF
  3. Configure a política de verificação
  4. Quando um pedido é concluído, o link de assinatura é enviado por email ao cliente automaticamente
  5. Após a assinatura, uma nota é adicionada ao pedido com o ID de evidência

O CPF ou CNPJ do cliente deve estar presente no pedido. O plugin lê as chaves de meta padrão _billing_cpf / _billing_cnpj usadas pela extensão Brazilian Market on WooCommerce. Se nenhum estiver presente, o plugin adiciona uma nota ao pedido explicando o requisito e não cria a sessão.

Verificação de documentos

A página Assinaturas > Verificar (requer a capacidade signdocs_verify):

  1. Cole um evidence_id (assinatura única) ou um envelope_id (multi-signatário)
  2. O plugin chama GET /v1/verify/{id} ou GET /v1/verify/envelope/{id} e exibe:
    • Identidades de cada signatário (nome, CPF/CNPJ)
    • CNPJ do tenant
    • Horários de cada etapa
    • O perfil de política aplicado
    • Links de download: pacote de evidências (.p7m), PDF assinado, .p7s consolidado (envelopes), PDF combinado (envelopes)
  3. Use os arquivos de evidência em validadores externos (Validador ITI, Adobe Acrobat) para confirmação independente

Log de auditoria

A página Assinaturas > Log de Auditoria (requer a capacidade signdocs_view_logs):

  • Visão WP_List_Table sobre {prefix}signdocs_log
  • Filtros: nível (debug / info / warning / error), tipo de evento, intervalo de datas
  • Exportação em CSV via admin-post.php (streaming em blocos, segura para exportações de vários GB)
  • Retenção automática de 30 dias pela tarefa cron diária signdocs_prune_logs
  • Toda chamada de API, entrega de webhook e aviso de descontinuação é registrada com contexto em JSON

WP-CLI

Para operações via shell (úteis para automação, CI/CD e diagnóstico):

wp signdocs health

— verifica a conectividade com a API no ambiente configurado

wp signdocs send --document=42 --email=alice@example.com --cpf=12345678901 --policy=CLICK_PLUS_OTP

— cria uma sessão de assinatura a partir de um anexo do WordPress e imprime o ID e a URL da sessão

wp signdocs status <sessionId>

— consulta o status de uma sessão pelo ID

wp signdocs webhook-test <webhookId>

— envia uma entrega de teste para um webhook registrado

wp signdocs log-tail --level=warning --limit=20

— mostra as últimas N entradas do log de auditoria filtradas por nível

Rotação do segredo de webhook

  1. Em Configurações > SignDocs Brasil, clique em “Rotacionar Segredo”
  2. O plugin solicita um novo segredo à API; o segredo anterior passa a ser o “segredo anterior”, com uma janela de tolerância de 7 dias
  3. Durante a janela, o endpoint /wp-json/signdocs/v1/webhook aceita ambos os segredos — entregas em trânsito não são rejeitadas
  4. Após 7 dias, a tarefa cron diária signdocs_expire_prev_secret remove o segredo antigo
  5. O status da rotação fica visível no admin (com contagem regressiva)

Para desenvolvedores

Hooks disponíveis:

Ciclo de vida da sessão:

  • signdocs_session_created — Sessão criada (via API, não necessariamente via WordPress)
  • signdocs_signing_completed — Assinatura concluída com sucesso
  • signdocs_signing_cancelled — Assinatura cancelada pelo integrador ou pelo signatário
  • signdocs_signing_expired — Sessão expirada sem conclusão
  • signdocs_signing_failed — Assinatura falhou (erro irrecuperável)
  • signdocs_transaction_fallback — Fallback acionado (ex.: SERPRO indisponível)

Por etapa (para envelopes e fluxos personalizados):

  • signdocs_step_started — Etapa iniciada (OTP enviado, captura biométrica etc.)
  • signdocs_step_completed — Etapa concluída
  • signdocs_step_failed — Etapa falhou
  • signdocs_purpose_disclosure_sent — (NT65) Notificação de averbação da finalidade entregue ao beneficiário
  • signdocs_deadline_approaching — (NT65) ≤2 dias úteis antes do prazo de envio ao INSS

Tenant / API:

  • signdocs_quota_warning — Uso do tenant cruzou um limite (80 / 90 / 100%)
  • signdocs_api_deprecation_notice — A API sinalizou um endpoint descontinuado

WooCommerce:

  • signdocs_wc_signing_completed — Assinatura de um pedido WooCommerce concluída

Cada ação recebe $post_id (do CPT signdocs_signing ou signdocs_envelope) e $payload (o array bruto do webhook) como argumentos, exceto signdocs_quota_warning e signdocs_api_deprecation_notice, que recebem apenas o payload.

Capacidades:

  • signdocs_manage — Configurar credenciais, webhook e identidade visual; gerenciar envelopes de outros usuários
  • signdocs_send — Criar sessões e envelopes
  • signdocs_verify — Usar a página de Verificação e inspecionar evidências
  • signdocs_view_logs — Acessar o log de auditoria e exportar CSV

Use current_user_can('signdocs_send') no lugar de manage_options / edit_posts ao adicionar funcionalidades personalizadas.

SDK PHP:

O cliente do SDK já configurado (com credenciais criptografadas e cache de token compartilhado) está disponível via:

$client = Signdocs_Client_Factory::get(); // SignDocsBrasil\Api\SignDocsBrasilClient or null

Consulte a documentação do SDK PHP para a superfície completa (transactions, envelopes, verification, users, documentGroups, webhooks etc.).

Serviços externos

Este plugin se conecta à plataforma SignDocs Brasil — operada pela mesma empresa que publica o plugin — para criar, entregar e verificar assinaturas eletrônicas. O plugin não funciona sem enviar dados a esses endpoints, porque a assinatura em si acontece nos servidores do SignDocs (o site WordPress apenas orquestra a requisição e armazena a referência do resultado).

API SignDocs Brasil (api.signdocs.com.br / api-hml.signdocs.com.br)

Usada para criar sessões de assinatura, registrar webhooks, verificar evidências assinadas e gerenciar envelopes multi-signatário. O plugin se autentica com as credenciais de API que você informa no painel do WordPress (OAuth2 client_credentials ou, alternativamente, Private Key JWT quando configurado).

  • Quais dados são enviados, a cada criação de sessão: o conteúdo do documento PDF (codificado em base64), o nome do signatário, o email do signatário, o CPF ou CNPJ do signatário (um deles é exigido pela API), a política de verificação selecionada (ex.: CLICK_ONLY, BIOMETRIC), a preferência de idioma, uma URL de retorno opcional e campos de metadados que identificam a URL do site WordPress e a origem (shortcode, AJAX, WP-CLI, WooCommerce, envelope).
  • Quando: sempre que uma sessão de assinatura é criada. Isso ocorre no envio via AJAX do shortcode, no wp signdocs send da WP-CLI, na conclusão de pedido WooCommerce quando o produto está configurado para assinatura, e em toda criação de envelope / adição de novo signatário.
  • Outras chamadas de API que não enviam dados do documento: registro de webhook, consulta de status (GET /v1/signing-sessions/{id}), verificação de evidência (GET /v1/verify/{evidenceId}), status de envelope. Estas enviam apenas o identificador correspondente que você fornece (ID da sessão, ID de evidência, ID do envelope).
  • Autenticação: toda chamada de API é autenticada com um token Bearer de curta duração obtido no endpoint OAuth2 no mesmo domínio (POST {baseUrl}/oauth2/token). O plugin envia o seu Client ID e o Client Secret ou uma asserção JWT assinada (quando o modo Private Key JWT está configurado) a esse endpoint na primeira chamada e novamente quando o token em cache expira (tipicamente uma vez por hora, por ambiente); o token de acesso é armazenado em um transient do WordPress e reaproveitado em todas as chamadas seguintes. Nenhum dado do signatário é enviado ao endpoint de token.
  • Troca de ambiente: o plugin usa api-hml.signdocs.com.br (HML / sandbox) por padrão e api.signdocs.com.br somente quando o administrador troca explicitamente o ambiente para “Produção” na página de configurações.
  • Fornecido por SignDocs Brasil. Termos de Uso. Política de Privacidade.

SDK de navegador SignDocs Brasil (cdn.signdocs.com.br / cdn-hml.signdocs.com.br)

Um arquivo JavaScript (signdocs-brasil.js) carregado do CDN do SignDocs que abre o popup, o redirecionamento ou o overlay de assinatura quando o signatário clica no botão “Assinar Documento” renderizado pelo shortcode ou bloco Gutenberg.

  • Quais dados são enviados: nada diretamente por este carregamento de script — é uma requisição de recurso estático, igual à de qualquer outro arquivo JavaScript de um CDN de terceiros. Nenhuma informação pessoal é transmitida pela requisição ao CDN em si; o script é idêntico, byte a byte, para todos os sites que o carregam.
  • Quando: a cada visualização de página no front-end que renderiza o shortcode [signdocs] ou o bloco Gutenberg do SignDocs (o script é enfileirado condicionalmente — páginas sem o bloco não o carregam).
  • O ambiente do CDN (HML vs. produção) segue a mesma opção signdocs_environment da API.
  • Fornecido por SignDocs Brasil. Termos de Uso. Política de Privacidade.

Interface de assinatura SignDocs Brasil (sign.signdocs.com.br)

Após o signatário clicar em “Assinar Documento”, ele é levado à página segura de assinatura em sign.signdocs.com.br — e não a uma página hospedada pelo seu site WordPress. O fluxo de assinatura (OTP, captura biométrica, seleção de certificado digital, confirmação por aceite) é executado inteiramente nesse domínio. Esse isolamento é intencional: mesmo que o seu site WordPress fosse comprometido, um atacante não conseguiria forjar assinaturas, porque os fatores de autenticação são coletados em uma origem separada, sob controle do SignDocs Brasil.

  • Quais dados são enviados: o signatário interage diretamente com esse domínio para concluir o fluxo de assinatura. Os dados trocados ali (códigos OTP, fotos biométricas, seleção de certificado) não passam pelo seu site WordPress. O seu plugin recebe de volta apenas o resultado, via o webhook descrito acima.
  • Quando: quando o signatário clica no botão de assinatura renderizado pelo plugin e o SDK de navegador abre a superfície de assinatura (popup / redirecionamento / overlay).
  • Fornecido por SignDocs Brasil. Termos de Uso. Política de Privacidade.

Blocos

Este plugin disponibiliza 1 bloco.

  • SignDocs Assinatura Botão de assinatura eletrônica via SignDocs Brasil.

Instalação

Instalação automática

  1. No painel do WordPress, vá em Plugins > Adicionar Novo
  2. Pesquise por “SignDocs Brasil”
  3. Clique em “Instalar” e depois em “Ativar”

Instalação manual

  1. Faça upload da pasta signdocs-brasil para /wp-content/plugins/ (ou use Plugins > Enviar Plugin com o ZIP da release)
  2. Ative o plugin em Plugins > Plugins Instalados

Na ativação, o plugin:

  • Cria a tabela {prefix}signdocs_log para o log de auditoria
  • Registra os custom post types signdocs_signing e signdocs_envelope
  • Concede as capacidades personalizadas (signdocs_manage, signdocs_send, signdocs_verify, signdocs_view_logs) a administrador / editor / autor
  • Agenda as tarefas cron diárias de limpeza do log e de expiração do segredo rotacionado

Configuração

  1. Abra Configurações > SignDocs Brasil
  2. Escolha o método de autenticação:
    • Client Secret (padrão) — Client ID + Client Secret obtidos em app.signdocs.com.br
    • Private Key JWT (ES256) — chave privada em PEM + Key ID; a chave pública é registrada separadamente no SignDocs. Preferido por clientes regulados que não podem armazenar um segredo compartilhado no banco de dados
  3. Clique em “Testar Conexão”
  4. Selecione o ambiente: HML (sandbox para testes) ou Produção
  5. Configure os padrões de assinatura (política, idioma, modo, cor da marca, logotipo)
  6. Clique em “Registrar Webhook” — o plugin chama o endpoint da API, recebe o segredo HMAC e o armazena criptografado
  7. (Opcional) Configure signdocs_trusted_proxies com faixas CIDR confiáveis se o seu site estiver atrás de CloudFront, Cloudflare ou um proxy nginx, para que o rate limiter da assinatura anônima e o log de auditoria enxerguem o IP real do cliente

Perguntas frequentes

Preciso de uma conta SignDocs Brasil?

Sim. Crie sua conta gratuita para obter credenciais de API. O plano gratuito inclui documentos de teste no ambiente HML (sandbox).

As assinaturas têm validade jurídica?

Sim. As assinaturas eletrônicas do SignDocs Brasil cumprem a Medida Provisória 2.200-2/2001 e geram pacotes de evidência criptográficos (PKCS#7/CMS) com trilha de auditoria completa. Para documentos de alto valor ou quando a ICP-Brasil é exigida, use a política DIGITAL_CERTIFICATE com o certificado A1 ou A3 do signatário.

Onde a assinatura realmente acontece?

No domínio seguro sign.signdocs.com.br, não dentro do seu site WordPress. O plugin cria a sessão pela API no lado do servidor (as credenciais nunca chegam ao navegador), entrega ao navegador uma URL + clientSecret e recebe um webhook ao concluir. Isso significa que, mesmo se o seu site WordPress fosse comprometido, um atacante não conseguiria forjar assinaturas — o fluxo de autenticação (OTP, biometria, certificado) ocorre em um domínio totalmente separado, sob controle do SignDocs.

Como funcionam os envelopes multi-signatário?

Cada envelope tem N signatários. Modo SEQUENTIAL: o próximo signatário só recebe o link após o anterior concluir (útil para fluxos hierárquicos como procuração testemunha tabelião). Modo PARALLEL: todos podem assinar simultaneamente (útil para NDAs multi-parte, contratos de sociedade). O painel do envelope mostra o status de cada signatário em tempo real conforme chegam os webhooks STEP.*. Após o último signatário, um PDF combinado (ou um .p7s consolidado, para não-PDFs) fica disponível na página de Verificação.

Posso usar sem armazenar um segredo compartilhado?

Sim. Na aba de autenticação das configurações, escolha Private Key JWT (ES256). Você gera um par de chaves ECDSA P-256 localmente, registra apenas a chave pública no SignDocs (pelo painel app.signdocs.com.br) e o plugin armazena somente a chave privada em PEM (criptografada com AES-256-CBC). A cada chamada de API, o plugin assina um JWT de curta duração com a chave privada — nenhum segredo compartilhado no banco de dados. Esse modo é exigido por alguns clientes regulados (bancos, fintechs).

O que o log de auditoria captura?

Toda chamada de API que o plugin faz (método, caminho, status, duração, limite de taxa restante), toda entrega de webhook recebida (ID, tipo, signatário, correspondência), todo aviso de descontinuação emitido pela API (RFC 8594 Deprecation / Sunset) e toda operação administrativa (criar sessão, rotacionar segredo etc.). Retenção de 30 dias; limpeza por cron diário. Exportável para CSV para um SIEM externo.

E quanto à LGPD / GDPR?

O plugin registra handlers em wp_privacy_personal_data_exporters e wp_privacy_personal_data_erasers:

  • Exportador — retorna todas as sessões associadas ao email do titular dos dados (nome, emails, ID da sessão, ID de evidência, status, horários)
  • Eliminador — anonimiza o nome e o email do signatário para [redacted-<hash8>], mas preserva o ID de evidência, o ID da transação, o ID da sessão e os horários. Motivo: a legislação de assinatura eletrônica exige a retenção das evidências pelo prazo legal, mesmo após uma solicitação de eliminação. A identidade é anonimizada localmente; o pacote de evidências no servidor permanece íntegro para futuras auditorias legais.

O plugin funciona sem o WooCommerce?

Sim. A integração com o WooCommerce é opcional e só é carregada quando o WooCommerce está ativo. O shortcode, o bloco Gutenberg, os envelopes, a página de Verificação, o log de auditoria e a WP-CLI funcionam de forma independente.

Posso testar sem custos?

Sim. Defina o ambiente como “HML (Sandbox)” nas configurações. Dados de teste, OTP simulado (000000 ou 123456 são sempre aceitos), biometria mockada, sem cobranças.

Qual o tamanho máximo do PDF?

O plugin aceita PDFs de até 15 MB. Para arquivos maiores, aumente upload_max_filesize e memory_limit no PHP e garanta que o seu tenant esteja configurado para documentos grandes no SignDocs.

Funciona com qualquer tema WordPress?

Sim. O plugin usa estilos mínimos e respeita a hierarquia CSS do seu tema. O botão pode ser personalizado por uma classe CSS ou pela configuração de cor da marca.

Os dados do signatário são seguros?

Sim. As credenciais da API são criptografadas no banco de dados (AES-256-CBC, com chave derivada do wp_salt). Os tokens OAuth ficam em transients (nunca em options permanentes). Os segredos de webhook são criptografados. A chave privada do JWT (quando usada) também é criptografada. A verificação HMAC do webhook é feita em tempo constante (pelo SDK). A deduplicação de webhook por trava em transient previne ataques de replay.

Posso personalizar o visual da página de assinatura?

Sim. Configure a cor da marca e o logotipo nas configurações do plugin. A página hospedada em sign.signdocs.com.br exibirá a sua identidade visual. Para personalizações mais profundas, fale com o suporte — temas em nível corporativo estão disponíveis no plano Enterprise.

Funciona atrás de CloudFront / Cloudflare / proxy nginx?

Sim. Defina signdocs_trusted_proxies com uma lista de faixas CIDR confiáveis (ex.: 10.0.0.0/8, 172.16.0.0/12). O plugin usa X-Forwarded-For apenas quando o REMOTE_ADDR está em uma faixa confiável, evitando spoofing de IP no rate limiter e no log de auditoria.

O plugin está disponível em português?

Sim. Todos os textos da interface são traduzíveis (text domain signdocs-brasil) e o plugin inclui traduções em Português do Brasil (pt_BR) e Espanhol (es_ES). O WordPress carrega automaticamente o pacote de idioma correto conforme a configuração de localidade do seu site.

Avaliações

Não há avaliações para este plugin.

Colaboradores e desenvolvedores

“SignDocs Brasil” é um programa de código aberto. As seguintes pessoas contribuíram para este plugin.

Colaboradores

Registro de alterações

1.3.7

WP.org reviewer feedback, round 2 (review ID signdocs-brasil/signdocsbrasil/8May26/T2 15May26/4.0).

  • New == External services == section documenting every external endpoint the plugin contacts: the SignDocs API (api.signdocs.com.br / api-hml.signdocs.com.br), the OAuth2 token endpoint at the same base URL, the browser SDK CDN (cdn.signdocs.com.br / cdn-hml.signdocs.com.br), and the signing UI (sign.signdocs.com.br). Each subsection states what data is sent, when, and links to Terms of Use and Privacy Policy.
  • Trusted-proxy IP resolver hardened. ClientIp::resolve() previously returned $_SERVER['REMOTE_ADDR'] verbatim when no trusted-proxy chain matched, propagating malformed values into the rate-limit transient key and audit log. Both return paths now gate on filter_var(..., FILTER_VALIDATE_IP); invalid values become empty strings. The anonymous-signing AJAX rate limiter now routes through ClientIp::resolve() instead of reading $_SERVER['REMOTE_ADDR'] directly.
  • Allow-list validation on user-supplied policy / locale. Signdocs_Ajax::create_session and Signdocs_WooCommerce::save_product_meta previously accepted any sanitize_text_field-cleaned string for the policy and locale fields, then forwarded it to the API. Both call sites now compare against the canonical lists (Signdocs_Settings::get_policy_options() for policy, ['pt-BR', 'en', 'es'] for locale) and fall back to the configured plugin default when the submitted value isn’t recognized. Avoids 4xx round-trips against the SignDocs API for deprecated profile names.
  • is_email() validation on signer email. sanitize_email() strips invalid characters but doesn’t reject a value that fails to parse as an email. Added an is_email() check next to the existing required-field validation in Signdocs_Ajax::create_session.
  • wp_unslash() on remaining admin reads. The Verify-page POST handler (VerifyPage::render) now unslashes $_POST['kind'] before comparing, matching the WP coding standard the reviewer’s AI expects.
  • esc_html on exception messages reaching the frontend in four call sites: Signdocs_Ajax::create_session (AJAX error response), Signdocs_Settings::ajax_test_connection and ::ajax_register_webhook (settings-page AJAX), and Signdocs_WooCommerce::create_signing_for_order (order note). Exception text from upstream APIs can contain quotes or angle brackets that would break a frontend handler that does innerHTML = response.message.

1.3.6

WP.org reviewer feedback, round 1 (received 2026-05-05, ~9h after submission).

  • Description rephrased. The short description previously read “the most complete WordPress plugin for legally-binding electronic signatures in Brazil.” That’s a comparative marketing claim, which the WP.org Plugin Guidelines disallow (Guideline 11). Replaced with “the official WordPress plugin for legally-binding electronic signatures in Brazil” — factual (this is the first-party plugin published by SignDocs Brasil), non-comparative.
  • Webhook REST route now uses a proper permission_callback. Previously the route registered with permission_callback => '__return_true' and verified the HMAC signature inside the request handler. While that behaved correctly (signed-out requests were rejected), the WP REST introspection layer reported the endpoint as “publicly accessible,” which the reviewer flagged. New Signdocs_Webhook::authorize() performs HMAC verification at the permission-check phase and returns WP_Error with a precise HTTP status (401 for invalid signatures, 500 for server-side misconfiguration). The handler is now responsible only for body parsing and event dispatch. No change to the wire contract — third-party callers (the SignDocs Brasil API server) see identical request / response behavior.

1.3.5

WP.org submission auto-scanner fix.

  • Differentiated Plugin URI from Author URI. Both headers in signdocs-brasil.php were https://signdocs.com.br, which the WP.org submission auto-scanner rejects (the two URIs must be distinct or one omitted; per WP.org policy a Plugin URI is a page about this specific plugin and an Author URI is a page about the author). Plugin URI now points to the canonical GitHub repository (https://github.com/signdocsbrasil/signdocs-brasil-wordpress); Author URI remains the company site (https://signdocs.com.br). Once the plugin is approved on WP.org we may switch Plugin URI to the wordpress.org/plugins/signdocs-brasil/ page.

1.3.4

Plugin Check (PCP) hardening pass for WP.org submission. No runtime behavior changes — every fix in this release is either annotation, defensive cleanup, or removal of a benign-but-noisy header.

  • Dropped Domain Path: /languages header — the plugin doesn’t ship .pot / .mo files yet (translations are loaded via WP.org’s automatic language packs once approved), and the empty languages/ folder doesn’t exist in the distribution zip. PCP rightly flagged the header as pointing to a non-existent path.
  • wp_unslash() + explicit sanitization on every $_POST / $_SERVER read — added across class-signdocs-ajax.php and class-signdocs-woocommerce.php. The values were already being passed through sanitize_text_field() / absint() / sanitize_email() / esc_url_raw(), but wp_unslash() is the WPCS-canonical pattern and reviewers expect it.
  • Documented phpcs:ignore annotations on the custom-table queries. AuditQuery, Logger, webhook controller, and uninstall.php all touch {$wpdb->prefix}signdocs_log (or $wpdb->postmeta for the webhook lookup). PCP’s WordPress.DB.DirectDatabaseQuery.* is unavoidable for plugins with their own tables — every annotation now states the table being touched and why core’s caching/query API doesn’t apply.
  • AuditQuery dynamic-prepare pattern documented inline. WordPress.DB.PreparedSQL.InterpolatedNotPrepared and PreparedSQLPlaceholders.* warnings on AuditQuery::count() / select() are PCP false positives — the {$where} fragment is built only from Filters allow-listed columns and the {$orderBy} / {$order} are validated against ALLOWED_ORDER_COLUMNS and validatedOrder(). Annotated explicitly so future readers (and reviewers) don’t have to re-discover this.
  • wp_enqueue_script for the CDN-hosted browser SDK now passes a version arg instead of null (includes/class-signdocs-shortcode.php:140). The CDN already serves immutable v1-pinned bundles, but a version argument silences PCP’s EnqueuedResourceParameters.MissingVersion and keeps the dev-tools network panel readable.

Plugin Check status after this release: 0 ERRORs, ~30 WARNINGs (down from 79; remaining warnings are documented false positives — webhook HMAC-vs-nonce, server-side hooks, plugin-specific custom-table queries, and the local-vs-global naming heuristic).

1.3.3

Cleanup pass after the v1.3.2 acceptance run.

  • wp signdocs webhook-test actually works. The SDK’s typed WebhookTestResponse model expects {deliveryId, status, statusCode} but the API returns {webhookId, testDelivery: {httpStatus, success, timestamp}}, so the typed call returned all-empty fields. CLI now bypasses the typed wrapper and reads the raw response, printing the real HTTP status + delivery timestamp. SDK fix tracked separately; the CLI unblocks operators today.
  • Dispatcher: dropped dead SIGNING_SESSION.* branches. The OpenAPI spec lists these but the server never emits them — the lifecycle is communicated entirely through the corresponding TRANSACTION.* events. Same cleanup applied to the legacy webhook controller in includes/. No behavior change; just removes confusion for anyone reading the dispatch table.
  • Audit log writes on success, not just on warnings. A webhook.completed info row now lands in signdocs_log for every TRANSACTION.COMPLETED, capturing transaction ID, evidence ID, and the matched CPT post ID. Brings the table in line with the readme’s “every API call recorded” claim.
  • WP-CLI webhook-test and log-tail now register with their dashed names as documented in the class header (previously the _ form silently took precedence).

1.3.2

Two production-acceptance fixes uncovered while running the v1.3.1 release against real HML webhooks and the verify admin UI.

  • Webhook dedup keyed off the wrong identifierX-SignDocs-Webhook-Id carries the subscription ID (wh_*), not a per-delivery ID. The previous dedup transient used that header as the key, so the first delivery for a subscription poisoned the cache for the full 7-day TTL and every subsequent webhook (including TRANSACTION.COMPLETED) returned 200/deduped without ever reaching the dispatcher. CPT records stayed stuck in PENDING. Now keys off the body’s top-level id (the actual delivery ID, del_*).
  • Custom capabilities resolved to do_not_allow — the envelope CPT’s 'capabilities' map remapped read_post/edit_post to signdocs_verify/signdocs_send/signdocs_manage, which registered them in WordPress’s $post_type_meta_caps table as meta caps. Core’s map_meta_cap() then short-circuited them to do_not_allow whenever called without a post argument — so even an administrator got HTTP 403 on the Verify admin page. Switched the envelope CPT to a custom capability_type and translate the generated CPT-cap names to the four primitive signdocs_* caps via Capabilities::mapMetaCap.
  • Verified end-to-end against HML: full create sign TRANSACTION.COMPLETED webhook CPT updated to COMPLETED with evidenceId verification->verify($evidenceId) returns the signed evidence record (CPF, policy, completion timestamp).

1.3.1

WP.org submission readiness — Plugin Check (PCP) baseline + canonical English readme + complete CPF/CNPJ collection.

  • Plugin Check: 0 ERRORs — fixed 12 PCP error-level findings: 4× missing defined('ABSPATH') guards in src/Admin/{VerifyPage,AuditTable}.php, src/Cpt/EnvelopeCpt.php, src/Webhook/Controller.php; 3× missing translators: comments on __() calls with placeholders in WooCommerce integration; 2× output escape gaps in WooCommerce email body; 1× output escape gap on the CPT status badge (now via wp_kses_post()); strip_tags() wp_strip_all_tags() in the unit-test fallback path of Filters; documented fopen / fwrite / fclose in AuditExport as a streaming-CSV pattern with file-scoped phpcs:ignore.
  • Canonical readme rewritten in English. WP.org policy 2025-07-28 requires the description, short description, and FAQ to be in English. The old Portuguese sections move to the standard i18n flow — pt_BR site visitors will see the localized strings via WordPress.org’s automatic translation pack delivery once the plugin is approved.
  • Removed load_plugin_textdomain() — discouraged since WordPress 4.6 for plugins on WP.org. WordPress core auto-loads the right language pack from the plugin slug.
  • CPF / CNPJ collection at every entry point — the SignDocs API requires signer.cpf or signer.cnpj at session-create time. Added to: shortcode form (when show_form="true"), AJAX handler validation, frontend JS payload, wp signdocs send --cpf= / --cnpj= flags, WooCommerce integration (reads _billing_cpf / _billing_cnpj from order meta — works with the standard “Brazilian Market on WooCommerce” extension), envelope service per-signer.
  • wp signdocs send outputs the full shareable URL — previously printed only the base session URL, which is not directly usable. Now appends ?cs=<clientSecret> (URL-encoded) so the printed link can be opened directly to start signing.
  • wp signdocs status now requires --client-secret — documented the embed-token authentication contract. Full implementation deferred to a follow-up release.
  • Acceptance test against real HML: WP 6.9.x + MariaDB 11 in podman, plugin installed from the v1.3.1 zip, real HML credentials. Confirmed: signingSessions->create returns a valid sessionId + clientSecret + url; envelopes->create returns a valid envelopeId (PARALLEL, 2 signers); WP-CLI validates CPF/CNPJ inputs correctly; capabilities install on activation; plugin co-active with WooCommerce 10.7.

1.3.0

Alignment with PHP SDK 1.4.0 + complete English readme.

  • PHP SDK upgraded to ^1.4 — SDK 1.4.0 fixed a model-shape divergence in CreateSigningSessionRequest / CreateEnvelopeRequest that had existed since 1.0.0: the correct field names accepted by the API are purpose, policy, signer, document, returnUrl, cancelUrl, metadata, locale, expiresInMinutes, appearance. Plugin call sites (CLI + AJAX) were updated.
  • CPF / CNPJ collection at every entry point — the API requires signer.cpf or signer.cnpj at session creation. The shortcode form now exposes CPF + CNPJ fields when show_form="true"; the AJAX handler validates them; wp signdocs send accepts --cpf / --cnpj; the WooCommerce integration reads _billing_cpf / _billing_cnpj from the order (Brazilian Market on WooCommerce extension keys); the envelope service propagates per-signer CPF.
  • Readme rewritten in English — per WP.org policy from 2025-07-28, the canonical readme description must be in English. Portuguese localization is loaded automatically from the bundled .po / .mo translation files for pt_BR sites.
  • Plugin Check (PCP) errors fixed — direct file access guards (defined('ABSPATH')) added to 4 source files; missing translators: comments added to 3 __() calls with placeholders; output escaping tightened in WooCommerce email and CPT badge rendering; strip_tags() swapped for wp_strip_all_tags() in non-test paths.
  • “Tested up to” updated to WordPress 6.9 (the version used in the automated pen test).

1.2.3

Security sniff cleanup — zero phpcs:ignore comments in source.

  • Consolidated exceptions — the 7 remaining WPCS findings that can’t be fixed through refactor (MySQL doesn’t allow identifier placeholders; custom tables can’t use WP_Query; admin audit logs shouldn’t be cached; list-table pagination doesn’t nonce in WP convention) are now declared as file-scoped exclusions in phpcs.xml.dist with written rationale for each. Zero line-level phpcs:ignore comments remain in src/.
  • EventRouter::queryByMeta refactored — dropped the direct $wpdb->postmeta lookup in favor of get_posts(['meta_query' => …, 'fields' => 'ids']). Slightly safer (adds post-type filter), eliminates two DirectDatabaseQuery warnings without suppression.
  • Filters::fromRequest signature tightened — no longer falls back to $_REQUEST when called without arguments; callers must pass the request array explicitly. Moves the superglobal read-site up to the admin page, where CSRF/capability context is clear.
  • Net result: zero security-category PHPCS findings, zero phpcs:ignore suppressions, and every exception documented in one auditable file.

1.2.2

Security audit + refactor.

  • AuditQuery refactor — all raw SQL extracted into src/Admin/AuditQuery.php. New src/Admin/Filters.php value object enforces validation at its constructor, so by the time AuditQuery sees a value it’s already allow-list-checked. AuditTable, AuditExport, and SigndocsCommand::log_tail are now thin consumers with zero raw SQL.
  • SQL-injection fuzz test suitetests/Unit/AuditQueryFuzzTest.php runs 24 SQL-injection payloads across every filter field (level, event_type, from, to, orderby, order) and asserts that every payload is either rejected by the allow-list or survives only via %s placeholders — never into a SQL literal. 47 total unit tests / 552 assertions, all green.
  • Black-box pen testtests/pen_test.sh exercises a running WordPress 6.9.x + MariaDB 11 stack (podman pod). Tests SQLi across audit filters + CSV export, webhook HMAC bypass attempts (no-sig, wrong-sig, stale-ts, garbage-ts, valid-sig, replay-dedup), CSRF on admin-post.php, and subscriber-role authorization against the audit log. All checks passed — runtime behavior matches the phpcs:ignore justifications.

1.2.1

WP.org submission-readiness pass.

  • phpcbf auto-fixed ~3,300 cosmetic WPCS findings; remaining ~370 are pure style (snake_case / Yoda) and annotated as advisory in CI.
  • Audited and annotated the 26 security-adjacent PHPCS findings (nonce verification, prepared SQL) — all verified as safe with justifying phpcs:ignore comments.
  • Added .wordpress-org/ asset bundle: icon-256, icon-128, and auto-generated branded banner-1544×500 / banner-772×250 (designer should replace banners before public launch).
  • Added .github/workflows/wp-org-deploy.yml10up/action-wordpress-plugin-deploy on tag push, gated by the DEPLOY_TO_WPORG repo variable so it’s a no-op until WP.org approves.
  • Added DEPLOY.md runbook for the WP.org submission and release flow.

1.2.0

Enterprise feature parity with the external API.

  • Envelopes multi-signatário — new signdocs_envelope CPT (parent of signdocs_signing), EnvelopeService wrapping the SDK’s envelope resource, deterministic idempotency keys on create. Sequential and parallel signing flows.
  • Verification admin UI — “Verificar” submenu under SignDocs, accepts an evidence ID or envelope ID and renders signer identities, tenant CNPJ, consolidated downloads (.p7s or combined PDF). Uses SDK 1.3.0’s verifyEnvelope.
  • Private Key JWT auth — alternative to client_secret. Store a PEM-encoded ES256 private key + key ID; ClientFactory branches on signdocs_auth_method. Preferred by regulated customers who can’t store shared secrets at rest.
  • Audit log UIWP_List_Table over wp_signdocs_log with filters (level, event type, date range) and CSV export, gated by signdocs_view_logs. CSV streams from php://output with chunked reads — safe for multi-GB exports.
  • Rotação do segredo de webhookSecretResolver accepts both the primary and a previous secret during a 7-day grace window. Daily cron signdocs_expire_prev_secret clears the previous secret once the window expires. Controller’s authorize step tries each configured secret before rejecting.

1.1.0

Hardening release + alignment with SignDocs PHP SDK 1.3.0.

  • Shared OAuth token cache — SDK TokenCacheInterface is implemented by WpTransientTokenCache, so a single token is reused across every PHP-FPM worker instead of one token fetch per request.
  • Webhook hardening — timestamp drift gate (≤300s), replay de-duplication via X-SignDocs-Webhook-Id transient lock (7-day TTL), proper permission_callback that runs HMAC before any business logic, input-shape guard on session / transaction IDs.
  • Full webhook coverage — added TRANSACTION.CREATED, TRANSACTION.FALLBACK, STEP.STARTED/COMPLETED/FAILED, QUOTA.WARNING, API.DEPRECATION_NOTICE, plus the two NT65 INSS-consignado events STEP.PURPOSE_DISCLOSURE_SENT and TRANSACTION.DEADLINE_APPROACHING. Covers the 13 events the server actually emits today.
  • ObservabilityDeprecation / Sunset (RFC 8594) response headers surface as admin notices; RateLimit-* headers are captured in a transient for the dashboard widget; structured log table {prefix}signdocs_log with 30-day retention and a daily cron prune.
  • IdempotencyX-Idempotency-Key is now sent on every resource-creating call, derived deterministically from site URL + user + action + resource, so AJAX retries no longer create duplicate sessions.
  • Capability model — four new caps (signdocs_manage, signdocs_send, signdocs_verify, signdocs_view_logs) instead of raw manage_options / edit_posts. Granted to administrator / editor / author on activation via Capabilities::install(); map_meta_cap wires them to CPT operations.
  • LGPD / GDPRwp_privacy_personal_data_exporters and wp_privacy_personal_data_erasers are registered. The eraser redacts signer name + email but preserves evidence IDs and completion timestamps for legal retention.
  • WP-CLIwp signdocs health|send|status|webhook-test|log-tail.
  • Test suite — PHPUnit (Brain Monkey unit tests), PHPStan level 5 (with phpstan-wordpress), PHPCS (WordPress-Extra + PHPCompatibilityWP), GitHub Actions matrix on PHP 8.1 / 8.2 / 8.3.

1.0.0

  • Initial release
  • [signdocs] shortcode with 8 configurable attributes
  • Gutenberg block with live preview (ServerSideRender)
  • signdocs_signing custom post type with status, signer, and policy columns
  • REST webhook receiver with HMAC-SHA256 verification
  • WooCommerce integration: product tab, automatic email, order notes
  • AES-256-CBC encryption for stored credentials
  • Popup, redirect, and overlay support
  • Rate limiting for anonymous signing
  • Trilingual: pt-BR, en, es