Autorizar VeriFactu
Exportar contenido
Firma digitalmente el documento legal que autoriza a Factux a enviar tus registros de facturación a la AEAT.
- Ve a Configuración > VeriFactu — se abre el panel de autorización.
- Clic en “Crear Autorización” — el sistema genera el documento legal.
- Revisa el documento en el formulario embebido — aparece un PDF con tus datos fiscales.
- Completa los campos requeridos:
- Nombre del negocio: Pre-rellenado (editable)
- Documento de identidad (NIF): Pre-rellenado (editable)
- Fecha: Pre-rellenada con fecha actual (editable)
- Firma en el recuadro designado — usa ratón, trackpad o pantalla táctil.
- Clic en “Completar” — el documento se envía a DocuSeal.
- Espera unos segundos — el estado se actualiza automáticamente a “Firmada”.
Campos del documento
Sección titulada «Campos del documento»| Campo | Origen | Editable |
|---|---|---|
| Nombre del negocio | businesses.legal_name o businesses.name | Sí |
| NIF | businesses.tax_id | Sí |
| Fecha de autorización | Fecha actual | Sí |
| Firma digital | — | Obligatorio |
Como se que lo hice bien
Sección titulada «Como se que lo hice bien»- Badge cambia a Firmada (verde).
- Aparece la fecha de firma: “Firmada el 16/02/2026”.
- Botón “Descargar Documento” disponible.
- Toast de confirmación: “Autorización completada”.
- Las facturas emitidas se envían automáticamente a VeriFactu.
Errores comunes
Sección titulada «Errores comunes»| Mensaje | Causa | Solución |
|---|---|---|
| ”Only business owners can create VeriFactu authorizations” | No eres owner del negocio | Solo el propietario puede autorizar |
| ”Business already has a valid authorization” | Ya existe autorización firmada | No es necesario crear otra |
| ”DOCUSEAL_API_KEY not configured” | Error de configuración del servidor | Contactar soporte técnico |
Detalles tecnicos — Autorizar VeriFactu
Sección titulada «Detalles tecnicos — Autorizar VeriFactu»Edge Function: create-verifactu-authorization
Trigger: Usuario clic en “Crear Autorización”.
Validaciones:
- Usuario autenticado
- Usuario es owner del negocio (
user_businesses.role = 'owner') - No existe autorización activa (
status IN ('pending', 'signed'))
Flujo:
- Carga datos del negocio:
name,legal_name,tax_id,email - Genera texto legal reemplazando placeholders:
{{BUSINESS_NAME}} → businesses.legal_name || businesses.name{{BUSINESS_TAX_ID}} → businesses.tax_id{{CURRENT_DATE}} → new Date().toLocaleDateString('es-ES')
- Genera HTML del documento con estilos
- Crea submission en DocuSeal API:
POST https://api.docuseal.co/api/submissionsBody: {template_id: DOCUSEAL_TEMPLATE_ID,send_email: false,submitters: [{role: "Primera Parte",email: business.email || user.email,name: businessName,fields: [...]}]}
- Extrae
embed_srcde respuesta DocuSeal - INSERT en
verifactu_authorizations:INSERT INTO verifactu_authorizations (business_id,docuseal_submission_id,status,business_name,business_tax_id,signer_email,legal_text,created_by,embed_url,docuseal_document_url) VALUES (...) - Retorna
authorizationconembed_url
Variables de entorno:
DOCUSEAL_API_KEY: API keyDOCUSEAL_TEMPLATE_ID: ID de plantillaDOCUSEAL_API_URL: URL base (default: https://api.docuseal.co)
Output:
{ "success": true, "authorization": { "id": "uuid", "status": "pending", "embed_url": "https://docuseal.co/s/..." }}Webhook: docuseal-webhook
Trigger: DocuSeal envía POST cuando cambia estado del documento.
Eventos:
form.completed: Usuario completó firmaform.declined: Usuario rechazó firma
Flujo para form.completed:
- Valida signature del webhook
- Extrae
submission.iddel payload - Busca en DB:
SELECT * FROM verifactu_authorizationsWHERE docuseal_submission_id = '<submission_id>'
- Actualiza registro:
UPDATE verifactu_authorizationsSET status = 'signed',signed_at = NOW(),signed_document_url = '<documents[0].url>'WHERE id = '<authorization_id>'
Payload ejemplo:
{ "event_type": "form.completed", "timestamp": "2026-02-16T10:30:00Z", "data": { "submission": { "id": "12345", "status": "completed", "email": "empresa@ejemplo.com" }, "documents": [{ "url": "https://docuseal.co/d/signed.pdf" }] }}Componente React: VeriFactuAuthorizationForm
Ubicación: src/features/invoices/sub-modules/verifactu/components/VeriFactuAuthorizationForm.tsx
Estados:
- Sin autorización: Muestra botón “Crear Autorización”
- Pendiente: Muestra iframe con DocuSeal embed + polling cada 3s
- Firmada: Muestra badge verde + botón descarga + botón revocar
- Rechazada/Revocada: Muestra alerta + botón “Crear Nueva Autorización”
Polling:
useEffect(() => { if (authorization?.status === 'pending' && showEmbeddedForm) { pollingRef.current = setInterval(() => { refetch(); // Query a BD cada 3s }, 3000); } return () => clearInterval(pollingRef.current);}, [authorization?.status, showEmbeddedForm]);Auto-cierre al firmar:
useEffect(() => { if (authorization?.status === 'signed') { clearInterval(pollingRef.current); setShowEmbeddedForm(false); toast({ title: '¡Autorización completada!' }); }}, [authorization?.status]);Query de diagnóstico
-- Ver estado completo de autorizaciónSELECT id, business_id, status, signed_at, declined_at, revoked_at, docuseal_submission_id, docuseal_document_url, signer_email, created_atFROM verifactu_authorizationsWHERE business_id = '<business_id>'ORDER BY created_at DESCLIMIT 1;Estados posibles:
pending: Esperando firmasigned: Firmada y activadeclined: Usuario rechazórevoked: Owner revocóexpired: Expirada (uso futuro)