Ambiente de testes
O sandbox é uma cópia da API com os mesmos endpoints, os mesmos códigos de erro e as mesmas validações, e sem nenhuma consequência: nada é cobrado, nada tem valor jurídico e nenhum e-mail chega a quem não deveria. É onde a sua integração deve nascer, e é onde ela deve continuar sendo testada depois de estar em produção.
>>> PENDENTE DE BACKEND <<<
O ambiente de sandbox ainda não está no ar. Os gatilhos de simulação descritos nesta página são o desenho do contrato e não foram exercidos. A URL base pode ainda mudar até a publicação; mantenha-a em variável de ambiente, e não escrita no código.
Começar
Duas mudanças em relação a produção, e nenhuma outra:
# Sandbox
ADM_BASE=https://api.adigitalmax.com.br/v1/sandbox
ADM_CHAVE=adx_test_3a5e1c92f704...
# Producao
# ADM_BASE=https://api.adigitalmax.com.br/v1
# ADM_CHAVE=adx_live_9f2c7d41b8e6...
A chave de sandbox sai do mesmo lugar da de produção, em
Configurações → API → Chaves, escolhendo ambiente
SANDBOX. O prefixo adx_test_ deixa isso visível em qualquer log,
o que é útil quando alguém pergunta se aquele documento estranho de ontem era teste.
Os dois ambientes não se enxergam. Chave, documento, pasta, modelo,
contato e webhook de um nunca aparecem no outro. Usar chave de sandbox para pedir um
documento de produção devolve 404, e não 403, exatamente como
se o documento não existisse. Esse 404 é a causa mais comum de confusão em
integração nova.
O que muda em relação à produção
| Item | Produção | Sandbox |
|---|---|---|
| Cobrança | Consome franquia e gera excedente. | Nada é cobrado. Os contadores existem e são consultáveis, para você prever custo, mas não faturam. |
| Valor jurídico | O documento assinado é prova. | Nenhum. O PDF sai com marca d'água AMBIENTE DE TESTES em todas as páginas e o certificado declara isso no cabeçalho. |
| Entregue a qualquer endereço. | Entregue apenas a endereços verificados na sua organização e a domínios de teste. Para os demais, a API responde 201 e registra o envio, sem entregar nada. |
|
| SMS e WhatsApp | Enviados de verdade. | Nunca enviados. O código do fator SMS_OTP é sempre 000000. |
| Biometria facial | Prova de vida real, com provedor externo. | Aprovada ou recusada conforme o gatilho no e-mail do signatário. Nenhuma imagem é processada. |
| Assinatura PAdES e carimbo do tempo | Emitidos pela autoridade. | Simulados, e o certificado declara que são simulados. |
| Limite de requisição | 60 por minuto. | 60 por minuto, idêntico. É de propósito: se a sua integração estoura o limite no sandbox, ela vai estourar em produção. |
| Webhooks | Só recebem eventos de produção. | Só recebem eventos de sandbox, e são cadastrados com uma chave de sandbox. O segredo é próprio, e é ele que distingue um evento de teste de um real. |
| Validação pública | Confirma autenticidade. | Funciona, e o resultado traz "sandbox": true. A página pública mostra um aviso vermelho. |
| Retenção | Política da organização. | Documentos são apagados após 30 dias, sem aviso. Não use o sandbox como arquivo. |
Gatilhos de simulação
O problema de testar assinatura eletrônica é que o caminho feliz depende de uma pessoa clicar em um link, e os caminhos infelizes dependem de esperar dias. Os gatilhos resolvem isso: o endereço de e-mail do signatário determina o que ele vai fazer, e a plataforma age sozinha em segundos.
| O que acontece | Quando | |
|---|---|---|
assina@teste.adigitalmax.com.br | Assina automaticamente, cumprindo todos os fatores exigidos. | ~5 segundos após o envio |
assina-lento@teste.adigitalmax.com.br | Visualiza, espera, depois assina. Serve para exercer o estado PARCIALMENTE_ASSINADO. | visualiza em ~5 s, assina em ~60 s |
recusa@teste.adigitalmax.com.br | Recusa com o motivo "Recusa simulada em ambiente de testes." | ~5 segundos |
visualiza@teste.adigitalmax.com.br | Abre o documento e nunca assina. Fica em VISUALIZADO até expirar. | ~5 segundos |
nunca-abre@teste.adigitalmax.com.br | Não faz nada. Fica em ENVIADO para sempre. | nunca |
falha-entrega@teste.adigitalmax.com.br | O e-mail volta e o signatário vai para FALHA_ENTREGA. | ~5 segundos |
falha-autenticacao@teste.adigitalmax.com.br | Erra o código três vezes e é bloqueado. Serve para testar o seu tratamento de signatário travado. | ~10 segundos |
biometria-recusa@teste.adigitalmax.com.br | Envia a selfie e é recusado pela prova de vida. | ~10 segundos |
Além dos e-mails, dois campos aceleram o relógio:
| Campo | Efeito em sandbox |
|---|---|
prazoEm no passado próximo | Em produção é 422. Em sandbox, aceito até 1 hora no passado, e o documento vai para EXPIRADO na varredura seguinte, em até 1 minuto. |
expiraEm no passado próximo | Mesmo tratamento: o documento vai para EXPIRADO na varredura seguinte, em até 1 minuto, sem esperar o prazo real. |
#!/usr/bin/env bash
# Envia, espera concluir e baixa. O ciclo inteiro em menos de um minuto,
# sem ninguem precisar clicar em nada.
set -euo pipefail
ADM_CHAVE="${ADM_CHAVE:?use uma chave adx_test_}"
ADM_BASE="https://api.adigitalmax.com.br/v1/sandbox"
AUTH=(--header "Authorization: Bearer $ADM_CHAVE")
DADOS='{
"titulo": "Contrato de teste - ciclo completo",
"nivelAssinatura": "SEGURA",
"fatoresExigidos": ["EMAIL", "SMS_OTP"],
"signatarios": [
{
"nome": "Robo Que Assina",
"email": "assina@teste.adigitalmax.com.br",
"telefone": "+5511900000000",
"funcao": "ASSINAR",
"metodoEntrega": "EMAIL",
"ordem": 1
}
],
"campos": [
{ "tipo": "ASSINATURA", "pagina": 1, "x": 0.10, "y": 0.75, "largura": 0.34, "altura": 0.07 }
]
}'
# 1. Criar. Nasce em RASCUNHO; nada e disparado.
DOC=$(curl --fail-with-body --silent --show-error "${AUTH[@]}" \
--request POST "$ADM_BASE/documentos" \
--form "dados=$DADOS;type=application/json" \
--form "arquivo=@./contrato.pdf;type=application/pdf")
DOC_ID=$(echo "$DOC" | jq -r '.id')
# 2. Enviar, que e sempre uma chamada separada.
curl --fail-with-body --silent --show-error "${AUTH[@]}" \
--request POST "$ADM_BASE/documentos/$DOC_ID/enviar" > /dev/null
echo "Documento $DOC_ID enviado. Aguardando o robo assinar..."
# O robo assina em ~5s. Consultamos a cada 3s, no maximo 10 vezes,
# que e sondagem aceitavel em teste e inaceitavel em producao.
for _ in $(seq 1 10); do
sleep 3
STATUS=$(curl --silent "${AUTH[@]}" "$ADM_BASE/documentos/$DOC_ID" | jq -r '.status')
echo " status: $STATUS"
[ "$STATUS" = "ASSINADO" ] && break
done
[ "$STATUS" = "ASSINADO" ] || { echo "Nao concluiu a tempo."; exit 1; }
curl --silent "${AUTH[@]}" "$ADM_BASE/documentos/$DOC_ID/certificado" \
| jq '{codigo, versao, hashDocumento}'
curl --location --fail-with-body --silent "${AUTH[@]}" \
--output "teste-assinado.pdf" \
"$ADM_BASE/documentos/$DOC_ID/arquivo?tipo=ASSINADO"
echo "Gravado teste-assinado.pdf (com marca d'agua de ambiente de testes)."
Dados de exemplo
Toda organização nasce, no sandbox, com um acervo pronto para você não precisar construir nada antes de ler. Os identificadores abaixo são estáveis por organização e aparecem no painel, em ambiente de sandbox.
| Recurso | O que é |
|---|---|
| 1 modelo de documento | Contrato de prestação de serviços (exemplo), com dois papéis e as variáveis cliente_nome, cliente_documento, valor_mensal e vigencia_meses. Serve para exercer a instanciação sem subir PDF. |
| 3 pastas | Contratos, Termos e Arquivo, sendo Arquivo subpasta de Contratos. |
| 6 documentos | Um em cada estado: rascunho, aguardando, parcialmente assinado, assinado, recusado e expirado. O assinado tem certificado e código de verificação válidos. |
| 1 modelo de e-mail | Convite padrão, referenciável por modelo_email_id. |
| 4 contatos | Já apontando para os endereços de gatilho, para você montar teste sem digitar e-mail longo. |
Um PDF de teste com sete páginas, marcadores de variável e espaço reservado para
assinatura no rodapé da última página está em
contrato-exemplo.pdf, disponível no painel do sandbox. As coordenadas
usadas nos guias foram calculadas para ele.
>>> PENDENTE DE BACKEND <<<
Roteiro de aceitação
Antes de considerar a integração pronta, exerça os doze casos abaixo no sandbox. Os quatro primeiros são o caminho feliz e todo mundo faz; os oito seguintes são os que produzem chamado de suporte às sextas-feiras.
| Caso | Como provocar | O seu sistema deve |
|---|---|---|
| 1. Envio simples | Um signatário, assina@teste... | Receber document.completed e baixar o PDF. |
| 2. Envio sequencial | Dois signatários, sequencial: true | Não tratar o primeiro document.signed como conclusão. |
| 3. Instanciar modelo | O modelo de exemplo | Gerar o documento sem upload e com as variáveis certas. |
| 4. Baixar certificado | Documento concluído | Guardar PDF, certificado e código de verificação no seu lado. |
| 5. Recusa | recusa@teste... | Fechar o caso, registrar o motivo e não ficar esperando conclusão. |
| 6. Expiração | expiraEm no passado próximo | Reagir a document.expired sem intervenção manual. |
| 7. Falha de entrega | falha-entrega@teste... | Detectar FALHA_ENTREGA, corrigir o e-mail e reenviar. |
| 8. Cancelamento externo | Cancelar pelo painel, não pela API | Receber document.cancelled e fechar o caso. Muitos integradores nunca testam este. |
| 9. Webhook duplicado | Reenviar a mesma entrega | Processar uma vez só, pelo eventoId do corpo. |
| 10. Assinatura inválida no webhook | Alterar um byte do corpo | Responder 401 e não processar. |
| 11. Limite de requisição | Um laço apertado | Tratar 429 respeitando o Retry-After, sem falhar o lote. |
| 12. Retentativa após timeout | Repetir uma criação com a mesma Idempotency-Key | Receber o mesmo documento, e não um segundo. |
Antes de ir para produção
- Troque a chave e a URL base por variável de ambiente, se ainda não estiverem. Nenhuma das duas deve aparecer escrita no código.
- Cadastre o webhook de produção, com segredo próprio. Ele é separado do de sandbox e não herda nada.
- Confirme que você valida a assinatura HMAC com o segredo do ambiente certo. Segredo de sandbox contra evento de produção falha em toda entrega, e o sintoma é um webhook silenciosamente desativado depois de 72 horas.
- Use um endpoint de webhook por ambiente, com segredos diferentes. É a última defesa contra um evento de teste virar pedido real: o receptor de produção simplesmente não valida a assinatura de um evento de sandbox.
- Verifique os endereços de e-mail dos remetentes no painel, em Configurações. Em produção o e-mail sai de verdade e a entregabilidade depende disso.
- Revise os escopos da chave de produção. É comum a de sandbox ter sido criada com tudo marcado, para não travar o desenvolvimento; a de produção deve ter o mínimo.
- Guarde o primeiro documento de produção e confira o PDF, o certificado e a validação pública com olho humano, antes de abrir o volume. Marca d'água esquecida, campo fora de lugar e nome de remetente errado só aparecem olhando.
Depois de ir para produção, mantenha o sandbox vivo. Toda mudança na sua integração
deve passar pelos doze casos de aceitação antes de subir, e é bem mais barato descobrir
um 422 novo em um documento de teste do que em um contrato que já chegou
na caixa de entrada do cliente.