Rechazos y reenvío
Cuando la DIAN rechaza un documento, este pasa a rejected. No se pierde: conserva su número y puedes corregirlo y reenviarlo.
Leer el rechazo
Sección titulada «Leer el rechazo»GET .../documents/{document_id} trae dian.rules: cada regla con su code, si rechaza (kind: rejection) o solo notifica, el message tal como lo devolvió la DIAN, y una explanation y un hint con la corrección sugerida para los códigos conocidos.
"dian": { "rules": [{ "code": "FAK24", "kind": "rejection", "message": "El nombre del adquiriente no corresponde", "explanation": "Regla sobre los datos del adquiriente (identificación, nombre, dirección o responsabilidades).", "hint": "Corrige el campo `customer` según el mensaje y reenvía." }]}El significado de las reglas conocidas está en la referencia de errores. Un documento rechazado también produce el evento de webhook document.rejected.
Corregir y reenviar
Sección titulada «Corregir y reenviar»POST .../documents/{document_id}/resubmit con el mismo cuerpo de emisión, ya corregido, sin resolution_id ni number (el documento conserva los suyos). Responde 202 con el documento otra vez en pending.
curl -s -X POST "https://api.foliios.com/v1/companies/$FOLIIOS_COMPANY_ID/documents/$DOCUMENT_ID/resubmit" \ -H "Authorization: Bearer $FOLIIOS_API_KEY" -H "Content-Type: application/json" \ -d '{ "type": "invoice", "customer": { "identification": {"type": "nit", "number": "900373076"}, "name": "Comercializadora Andina S.A.S.", "emails": ["facturas@andina.example"] }, "lines": [{"code": "PARQ", "description": "Parqueadero", "quantity": "3", "unit": "HUR", "unit_price": "4000.00", "taxes": [{"scheme": "iva", "percent": "19"}]}] }'import timefrom foliios_inicio import EMPRESA, llamar
estado, documento, _ = llamar("GET", f"/v1/companies/{EMPRESA}/documents/{documento_id}")if documento["status"] == "rejected": for regla in documento["dian"]["rules"]: print(regla["code"], regla["message"], "->", regla["hint"]) corregido = armar_documento_corregido(documento) # tu código: arregla lo que dicen las reglas estado, documento, _ = llamar( "POST", f"/v1/companies/{EMPRESA}/documents/{documento_id}/resubmit", corregido ) assert estado == 202, documentoDetalles:
- Solo se reenvía un documento
rejected. Cualquier otro estado responde409 invalid_state. - El número se recupera. Si en modo manual otro documento lo tomó entretanto,
409 number_already_used. En modo automático el siguiente número libre más bajo puede haberse reutilizado: en ese caso también falla. - El reenvío se valida otra vez: un cuerpo corregido que sigue siendo inválido responde
422. - Cuando la corrección exige un dato fiscal que solo tu cliente tiene (un NIT, un dígito de verificación, un correo), no lo inventes: pídeselo.
Provocar un rechazo en el sandbox
Sección titulada «Provocar un rechazo en el sandbox»Para probar tu manejo de rechazos, pide un escenario de rechazo con la cabecera Foliios-Sandbox-Scenario en la emisión (o con la nota [sandbox:<id>] en notes, o un comprador 999000NNN). El catálogo completo, con la regla que dispara cada uno, está en escenarios; por ejemplo rejected_fad06:
curl -s -X POST "https://api.foliios.com/v1/companies/$FOLIIOS_COMPANY_ID/documents" \ -H "Authorization: Bearer $FOLIIOS_API_KEY" -H "Content-Type: application/json" \ -H "Idempotency-Key: rechazo-1" -H "Foliios-Sandbox-Scenario: rejected_fad06" \ -d @factura.jsonCon una clave que no es de sandbox, la cabecera responde 422 sandbox_scenario_not_allowed: se rechaza en vez de ignorarse.
Fallos failed y reintento
Sección titulada «Fallos failed y reintento»failed no es un rechazo de la DIAN: es un problema (casi siempre de configuración) que impidió firmar o transmitir. No se reintenta solo. El documento trae dian.reason y un dian.failure_code estable:
failure_code |
Qué falló | ¿Reintentable? | Quién corrige |
|---|---|---|---|
environment_mismatch, issuer_not_configured, certificate_unavailable |
Configuración de la empresa o su certificado | Sí | El alta de la empresa, en el portal |
resolution_expired, resolution_not_yet_valid, number_out_of_range |
La resolución del documento | Sí | La resolución en el portal |
dian_sender_fault, dian_certificate_rejected |
La DIAN rechazó la solicitud o el certificado | Sí | Configuración o certificado |
duplicate_unverified |
La DIAN dijo que ya procesó el documento y en 24 horas no se pudo confirmar su estado | Sí, solo verifica | Tú o soporte: reintentar consulta de nuevo, no reenvía |
invalid_document, rendering_failed, not_sent, unclassified |
Contenido o defecto de la plataforma | No | Documento nuevo o soporte |
Una vez corregida la causa: POST .../documents/{document_id}/retry, sin cuerpo. Antes de tocar nada foliios revisa que la configuración ya esté bien: si sigue mal responde 409 configuration_still_invalid y no cambia nada. Es idempotente por estado: sobre un documento que ya espera transmisión responde 202 con el documento actual e Idempotent-Replayed: true.
Un documento accepted o rejected no se reintenta (409 invalid_state): un rechazo se corrige con resubmit.
Cómo comprobarlo
Sección titulada «Cómo comprobarlo»Provoca un rechazo, corrígelo y reenvíalo hasta accepted. Esta comprobación la declara tu programa: la verificación de integración no puede comprobarla, y debes informarla como no verificada.