Representación
El documento que habilita a VeriBai a remitir en nombre de cada emisor, y su flujo de firma.
Para remitir registros en nombre de un emisor, la administración exige un documento de representación firmado por ese emisor. Cada hacienda tiene el suyo, y la API genera el que corresponde según la hacienda del cliente:
hacienda |
Documento |
|---|---|
verifactu |
Anexo I (modelo AEAT) |
tbai-araba |
Mandato de representación TicketBAI |
tbai-gipuzkoa |
Anexo II oficial de la DFG (OF 523/2020) |
tbai-bizkaia |
Modelo R32 oficial de la DFB |
En TEST la representación no bloquea nada. En LIVE es requisito: emitir o anular para un emisor sin representación firmada devuelve 403 REPRESENTATION_PENDING.
Estos endpoints pertenecen a la API de gestión: base URL
https://manage-api.veribai.com, misma clavex-api-key.
Endpoints
| Método | Endpoint | Descripción |
|---|---|---|
GET |
/v1/clientes/{nif}/representacion/generar |
Genera el documento sin firmar y devuelve su URL de descarga. |
POST |
/v1/clientes/{nif}/representacion/firmar |
Firma en la nube con un certificado .p12. |
POST |
/v1/clientes/{nif}/representacion/verificar |
Sube el documento firmado externamente. |
GET |
/v1/clientes/{nif}/representacion/estado |
Estado actual del documento. |
DELETE |
/v1/clientes/{nif}/representacion/firma-en-curso |
Cancela una firma en curso para volver a empezar. |
Flujo
-
Genera el documento con
GET …/representacion/generar. La respuesta incluye el PDF sin firmar y una URL temporal de descarga.Si al cliente le faltan datos para rellenar el formulario, la respuesta es un
400concamposFaltantes: la lista de campos que faltan, con la misma ruta que usarías en la API (direccion.calle, por ejemplo). Complétalos conPATCH /v1/clientes/{nif}y vuelve a generar. -
Firma por una de las dos vías:
- Firma local: el emisor firma el PDF con su propio medio de firma y tu software lo sube con
POST …/representacion/verificar(pdfFirmadoen base64). El certificado del emisor nunca sale de sus manos. - Firma en la nube:
POST …/representacion/firmarconpdf,certificado(el.p12en base64) ypassword. Útil cuando tu plataforma ya custodia el certificado del cliente con su consentimiento.
- Firma local: el emisor firma el PDF con su propio medio de firma y tu software lo sube con
-
Consulta el resultado con
GET …/representacion/estado.
La respuesta de verificar detalla el resultado de la comprobación: firmaValida, infoFirmante (el sujeto y el emisor del certificado X.509), detallesVerificacion (el diagnóstico nivel a nivel) y contrafirmadoPorVeriBai. Cuando el documento queda pendiente de revisión, incluye además horasRevisionEstimadas. Si la firma se rechaza, la respuesta es un 400 cuyo code nombra la causa, con el mismo detallesVerificacion. Ver rechazos de verificar.
curl -X POST https://manage-api.veribai.com/v1/clientes/B98765432/representacion/firmar \
-H "x-api-key: TU_CLAVE" \
-H "Content-Type: application/json" \
-d '{
"pdf": "<PDF sin firmar, base64>",
"certificado": "<certificado .p12, base64>",
"password": "••••••••"
}'
import os
from pathlib import Path
import veribai
client = veribai.Client(api_key="TU_CLAVE", environment="test")
resultado = client.representacion.firmar(
"B98765432",
pdf=Path("representacion.pdf").read_bytes(),
certificado=Path("certificado.p12").read_bytes(),
password=os.environ["VERIBAI_CERT_PASSWORD"],
)
const respuesta = await fetch("https://manage-api.veribai.com/v1/clientes/B98765432/representacion/firmar", {
method: "POST",
headers: {
"x-api-key": "TU_CLAVE",
"Content-Type": "application/json",
},
body: JSON.stringify({
"pdf": "<PDF sin firmar, base64>",
"certificado": "<certificado .p12, base64>",
"password": "••••••••"
}),
});
if (!respuesta.ok) throw new Error(`VeriBai ${respuesta.status}`);
const datos = await respuesta.json();
Estados
GET …/representacion/estado devuelve estadoRepresentacion (más firmaEnCurso, true mientras hay una firma pendiente de verificar):
| Estado | Significado |
|---|---|
pendiente |
Documento pendiente de firma. |
firmado_pendiente_revision |
Firmado, en revisión. |
firmado |
Firmado y verificado. El emisor puede operar en LIVE. |
rechazado |
La firma no superó la verificación. Genera y firma de nuevo. |
no_aplica |
La hacienda del cliente no tiene documento gestionado. Hoy las cuatro lo tienen, así que ningún emisor debería estar en este estado. |
Errores
| Código | Cuándo |
|---|---|
400 NOT_APPLICABLE_FOR_TAX_AGENCY |
La hacienda del cliente no tiene flujo de representación gestionado. Las cuatro lo tienen, así que en la práctica solo aparece si la hacienda del emisor falta o no se reconoce. |
400 VALIDATION_ERROR |
El NIF de la ruta no tiene formato válido, o en firmar falta pdf, certificado o password. |
400 INVALID_BODY |
firmar y verificar: el cuerpo no se pudo decodificar. |
400 INVALID_PDF |
pdf (firmar) o pdfFirmado (verificar) no es base64 válido. |
400 INVALID_CERT |
firmar: certificado no es base64 válido. |
400 CERT_ERROR |
firmar: el .p12 no se pudo cargar. Archivo equivocado o contraseña incorrecta; la respuesta no distingue cuál, a propósito. |
400 SIGNING_ERROR |
firmar: el certificado cargó pero la firma del PDF falló. Comprueba que el pdf es el que devolvió generar. |
404 NOT_FOUND |
El cliente no existe bajo tu cuenta. |
Rechazos de verificar
Cuando el documento firmado no supera la verificación, verificar responde 400 con uno de estos códigos. detallesVerificacion acompaña siempre, con el resultado de cada nivel de comprobación.
| Código | Motivo |
|---|---|
SIGNATURE_CRYPTO_INVALID |
La firma criptográfica no valida, el documento se modificó después de firmarlo, o el PDF no contiene ninguna firma digital. |
SIGNATURE_UNTRUSTED_CA |
El certificado no procede de una autoridad de certificación cualificada española reconocida. |
SIGNATURE_REVOKED |
El certificado de firma está revocado. |
SIGNATURE_CONTENT_MISMATCH |
El texto del PDF firmado no coincide con el documento generado, o no se pudo extraer texto. Genera el documento de nuevo y fírmalo sin modificarlo. |
SIGNATURE_COMPANY_NIF_MISMATCH |
El NIF de empresa del certificado no es el del cliente. |
SIGNATURE_REP_NIF_MISMATCH |
El NIF del firmante no es el del representante registrado en el cliente. |
NO_GENERATION_RECORD |
No consta ningún documento generado para este cliente, así que no hay contra qué verificar. Llama antes a generar. |
SIGNATURE_INVALID |
La firma no se pudo verificar y no aplica ninguna causa más concreta. |