Assinatura Digital em Django: Guia Completo de Integração
Django dá tudo de que uma integração de assinatura precisa — settings, ORM, admin de graça — e um tropeço garantido: o 403 do CSRF no webhook, que já consumiu tardes de metade dos integradores Python do Brasil. Este guia monta a integração completa do jeito Django: cliente singleton a partir das settings, view de criação, webhook com csrf_exempt + verificação HMAC sobre request.body, model de registros e fila para o trabalho pesado. A base conceitual da API está no guia Python; aqui o foco é o framework.
Setup: settings, ambiente e o cliente singleton
Instale com pip install signdocs-brasil. O SIGNDOCS_BASE_URL por variável é o que troca homologação→produção sem tocar código — desenvolvimento inteiro acontece contra o sandbox gratuito.
O model que ancora tudo
Com transaction_id único e indexado, o webhook vira um update atômico — e o admin do Django lhe dá de graça a tela de auditoria dos envios que todo time de operação pede depois.
A view de criação
O webhook: csrf_exempt + HMAC sobre request.body
@csrf_exempt na view, e ela é segura porque você troca o CSRF por uma proteção mais forte para este caso: a verificação HMAC prova que a requisição veio da SignDocs, coisa que token CSRF nunca provaria. O que é inaceitável é o meio-termo: csrf_exempt sem HMAC.
A tarefa Celery baixa o PDF (GET /v1/transactions/{id}/download) e o pacote de evidências (/evidence) pelas URLs temporárias e preenche os FileFields. Sem Celery no projeto? django-q ou um management command em cron cumprem o papel em volumes menores — o que não muda é o princípio: a view responde rápido; a fila trabalha.
Teste: as três camadas no Django
- Unidade: mocke
core.signdocs.cliente valide a sua lógica — a suíte continua rápida. - Contrato: uma suíte menor contra o sandbox real (credenciais de HML, dados fictícios, cada teste cria o que consome — TTL de 7 dias).
- Webhook: em local, exponha o
runservercom um túnel e disparePOST /v1/webhooks/{webhookId}/test— chega um payload assinado de verdade. Os cinco casos que o handler deve cobrir estão em como testar do sandbox ao CI.
E antes do go-live, confira os 12 erros mais comuns — três deles (corpo re-serializado, redirect como prova, reentrega sem idempotência) são exatamente os que o desenho acima já evita.
Perguntas Frequentes
Por que meu webhook em Django retorna 403 Forbidden?
É a proteção CSRF do Django fazendo o trabalho dela — no lugar errado. O middleware CSRF exige um token que só formulários do seu próprio site carregam; um webhook externo nunca o terá, então o POST morre em 403 antes de chegar à sua view. A correção é marcar a view do webhook com @csrf_exempt — e isso é seguro exatamente porque você substitui a proteção CSRF por uma mais forte para esse caso: a verificação da assinatura HMAC-SHA256 do evento. CSRF protege contra requisições forjadas por navegadores; o HMAC prova que a requisição veio da SignDocs. Nunca deixe o endpoint com csrf_exempt E sem verificação HMAC.
Como leio o corpo bruto do webhook no Django?
Use request.body — os bytes crus da requisição — para a verificação HMAC, e só depois faça json.loads. O erro clássico é usar dados já processados (request.POST ou um json já parseado e re-serializado): a re-serialização muda a ordem das chaves ou o espaçamento, os bytes mudam e a assinatura nunca confere. A sequência correta na view: raw = request.body; verificar HMAC sobre raw com o helper verify_webhook_signature do SDK signdocs-brasil (comparação timing-safe + tolerância de timestamp); event = json.loads(raw); processar.
Onde instancio o cliente da SignDocs num projeto Django?
Num módulo próprio (por exemplo, core/signdocs.py) que cria uma instância única de SignDocsBrasilClient a partir das configurações — o SDK obtém e renova o token OAuth2 de 15 minutos sozinho, então uma instância por processo é o desenho certo. As credenciais entram via settings lidas de variáveis de ambiente (os.environ ou django-environ): SIGNDOCS_CLIENT_ID, SIGNDOCS_CLIENT_SECRET e SIGNDOCS_BASE_URL — esta última apontando para api-hml.signdocs.com.br em desenvolvimento e para produção via variável, nunca hardcoded. Jamais coloque o client_secret no settings.py versionado.
Devo processar o webhook de forma síncrona na view?
Só o essencial. A regra dos webhooks é responder 200 rápido: verifique o HMAC, registre a idempotência pelo id do evento, atualize o status no banco — e delegue o trabalho pesado (baixar o PDF assinado e o .p7m, gerar notificações, chamadas a outros sistemas) para uma fila. No ecossistema Django, Celery é o caminho natural; django-q ou um cron com management command também servem para volumes menores. Se a view demorar demais, o retry da SignDocs reenvia o evento — e sem idempotência você processa duas vezes.
Como modelo os registros de assinatura no banco do Django?
Um model dedicado com os identificadores da API e o estado local: session_id e transaction_id (únicos, indexados), referência ao seu objeto de domínio (contrato, matrícula, pedido), status, o event_id do último webhook processado (para idempotência) e timestamps. Guarde também o caminho do PDF assinado e do pacote de evidências depois do download. Com transaction_id único no model, o processamento do webhook vira um update atômico — e o admin do Django lhe dá de graça uma tela de auditoria dos envios.
Como testo a integração Django antes de produção?
Três camadas: testes de unidade com o cliente mockado (a suíte do Django roda rápido e valida a sua lógica); testes contra o sandbox api-hml.signdocs.com.br com credenciais de homologação (valida o contrato real — lembre do TTL de 7 dias: cada teste cria o que consome); e, para o webhook, o endpoint POST /v1/webhooks/{webhookId}/test, que envia um payload assinado de verdade ao seu endpoint — em desenvolvimento local, exponha o runserver com um túnel. O guia completo de estratégia está em como testar do sandbox ao CI.
Do pip install à primeira assinatura, ainda hoje
Credenciais de homologação gratuitas, SDK Python oficial com OAuth2 automático e webhook de teste sob demanda — a integração Django completa no sandbox, sem cartão.
Criar credenciais de homologação Falar com o time comercial