autenticarProcurador method
Autentica procurador enviando XML assinado com Termo de Autorização
Parâmetros Obrigatórios
contratanteNome: Razão social da empresa contratante (quem faz requisições)autorNome: Nome do procurador (quem assina o termo)
Parâmetros do Contribuinte (obrigatório se diferente do contratante)
contribuinteNumero: CPF/CNPJ do contribuinte (em nome de quem serão feitas as requisições)
Certificado de Assinatura (obrigatório se diferente do authenticate)
O certificado usado para assinar o termo pode ser diferente do usado na autenticação OAuth2.
Desktop/Mobile:
certificadoPath: Caminho do certificado PFX/PEM do procuradorcertificadoPassword: Senha do certificado do procurador
Web (ou todas as plataformas):
certificadoBase64: Certificado PFX em Base64 (conteúdo do arquivo convertido)certificadoPassword: Senha do certificado do procurador
Parâmetros Opcionais (obtidos do ApiClient)
contratanteNumero: CNPJ do contratante (padrão: do authenticate)autorNumero: CPF/CNPJ do procurador (padrão: do authenticate)
Retorno
TermoAutorizacaoResponse contendo:
sucesso: se a autenticação foi bem-sucedidaautenticarProcuradorToken: token para usar em requisições subsequentesdataExpiracao: quando o token expiraisCacheValido: se está usando resposta em cache
Erros Possíveis
- ExcecaoAssinaturaCertificado: Problema com o certificado digital
- ExcecaoAssinaturaXml: Problema na assinatura do XML
- ExcecaoErroSerpro: Erro retornado pela API SERPRO
Implementation
Future<TermoAutorizacaoResponse> autenticarProcurador({
// Obrigatórios: nomes
required String contratanteNome,
required String autorNome,
// Contribuinte: obrigatório se diferente do contratante
String? contribuinteNumero,
// Certificado de assinatura: pode ser diferente do OAuth2
String? certificadoPath,
String? certificadoBase64,
String? certificadoPassword,
// Opcionais: obtidos do ApiClient se não fornecidos
String? contratanteNumero,
String? autorNumero,
}) async {
try {
// Verificar se ApiClient está autenticado
if (!_apiClient.isAutenticado) {
throw ExcecaoAutenticaProcurador(
'ApiClient não está autenticado. Chame authenticate() primeiro.',
codigo: 'NAO_AUTENTICADO',
statusHttp: 401,
);
}
// Obter dados do ApiClient (se não fornecidos)
final finalContratanteNumero =
contratanteNumero ?? _apiClient.contratanteNumero!;
final finalAutorNumero =
autorNumero ?? _apiClient.autorPedidoDadosNumero!;
final finalContribuinteNumero =
contribuinteNumero ?? finalContratanteNumero;
// Certificado de assinatura: pode ser diferente do OAuth2
// Prioridade: certificadoBase64 > certificadoPath > certificado do authenticate
String? finalCertificadoPath;
String? finalCertificadoBase64;
String? finalCertificadoPassword;
if (certificadoBase64 != null && certificadoBase64.isNotEmpty) {
// Usar Base64 fornecido (funciona em todas as plataformas)
finalCertificadoBase64 = certificadoBase64;
finalCertificadoPassword = certificadoPassword;
} else if (certificadoPath != null && certificadoPath.isNotEmpty) {
// Usar path fornecido (Desktop/Mobile)
finalCertificadoPath = certificadoPath;
finalCertificadoPassword = certificadoPassword;
} else if (_apiClient.certificadoPath != null) {
// Usar certificado do authenticate
finalCertificadoPath = _apiClient.certificadoPath;
finalCertificadoPassword = _apiClient.certificadoSenha;
} else {
throw ExcecaoAssinaturaCertificado(
'Nenhum certificado fornecido para assinatura.\n'
'Forneça certificadoPath (Desktop/Mobile) ou certificadoBase64 (Web/todas).',
);
}
if (finalCertificadoPassword == null ||
finalCertificadoPassword.isEmpty) {
throw ExcecaoAssinaturaCertificado(
'Senha do certificado não fornecida.',
);
}
// 1. Criar termo de autorização
final termo = TermoAutorizacaoRequest.comDataAtual(
contratanteNumero: finalContratanteNumero,
contratanteNome: contratanteNome,
autorPedidoDadosNumero: finalAutorNumero,
autorPedidoDadosNome: autorNome,
certificadoPath: finalCertificadoPath,
certificadoPassword: finalCertificadoPassword,
);
// 2. Validar dados (transparente)
final errosValidacao = termo.validarDados();
if (errosValidacao.isNotEmpty) {
throw ExcecaoAutenticaProcurador(
'Dados do termo de autorização inválidos:\n${errosValidacao.join('\n')}',
codigo: 'DADOS_INVALIDOS',
statusHttp: 400,
);
}
// 3. Criar XML do termo
final xml = termo.criarXmlTermo();
// 4. Assinar digitalmente com certificado real
final xmlAssinado = await _assinarXmlReal(
xml,
certificadoPath: finalCertificadoPath,
certificadoBase64: finalCertificadoBase64,
certificadoPassword: finalCertificadoPassword,
);
// 5. Enviar para API e obter token
return await _enviarParaAPI(
xmlAssinado,
finalContratanteNumero,
finalAutorNumero,
finalContribuinteNumero,
);
} on ExcecaoAutenticaProcurador {
rethrow;
} catch (e) {
throw ExcecaoAutenticaProcurador(
'Erro na autenticação de procurador: $e',
codigo: 'ERRO_INESPERADO',
statusHttp: 500,
);
}
}