📬 Response y manejo de errores
Independientemente del canal (REST o WebSocket), xPOS Core devuelve un objeto JSON con dos partes: un núcleo común que aparece siempre y un subconjunto opcional que depende del país. La ficha de cada país indica qué campos aparecen y cómo interpretarlos.
Esta página describe la respuesta estándar de xPOS, que es JSON y tiene una estructura fija. Si tu sistema necesita recibir la respuesta con otra estructura —un XML propio, un JSON distinto—, eso se resuelve con la respuesta personalizada, que es un mecanismo aparte y no altera nada de lo descrito aquí.
Ejemplo de response completo
Este es el shape completo del response: incluye todos los campos posibles. Los valores aparecen como null cuando el país o la operación no los aplica.
{
"transactionId": null,
"message": null,
"custom_response": null,
"error_description": null,
"stage": null,
"number": null,
"docNumber": null,
"output": null,
"signedXml": null,
"input": null,
"barcodeText": null,
"barcodeBase64": null,
"countryIdentificationCode": null,
"statusCode": null,
"statusDescription": null,
"statusMessage": null,
"applicationResponse": null,
"timeGeneration": null,
"timeValidation": null,
"contingencyCode": null
}Campos del núcleo (todos los países)
Cuando message es Operation Error (o Operation Successful con observación en código 200), los campos stage y error_description indican exactamente qué pasó. Ver la sección Manejo de errores para el contrato de integración y el catálogo completo de códigos para la acción recomendada por etapa.
Campos opcionales por país
Código visual (QR / PDF417)
Chile usa PDF417 y solo devuelve
barcodeBase64. El resto de los países usa QR y devuelve ambos campos.
Identificación tributaria
Eco de la entidad tributaria
Estos campos aparecen cuando la autoridad tributaria responde de forma sincrónica al envío. Los países con respuesta asíncrona (Chile, Paraguay) no los devuelven en el response inicial — se consultan después vía /api/v1/status.
Contingencia
Cada país tiene sus propios valores. Una contingencia automática la activa xPOS cuando no puede comunicarse con la entidad tributaria; una manual la declara el emisor según las reglas de la entidad tributaria, por ejemplo al regularizar un comprobante físico. La contingencia manual del dashboard no es una de estas últimas: emula una caída de internet, así que responde el código automático de caída de internet o de contingencia del emisor. El detalle está en la ficha de cada país:
| País | Automáticas | Manuales |
|---|---|---|
| Colombia | 03 y 07 (contingencia del emisor); 04 y 08 (contingencia DIAN). Coinciden con el tipo de documento que se genera | — |
| Costa Rica | 03 (sin internet) | 02 (contingencia: sustituye al comprobante físico) |
| El Salvador | 1 (sistema del Ministerio de Hacienda no disponible); 3 (falla del internet del emisor) | 2 (sistema del emisor no disponible); 4 (falla de energía eléctrica); 5 (otro, declarado por el POS) |
| Guatemala | 01 (contingencia del emisor) | — |
| Panamá | 01 (contingencia del emisor) | — |
| Perú | 1, con el motivo ContingencyTypeCode 01 (caída de internet del emisor) | 3 (comprobante físico regularizado), con un motivo del 02 al 07 |
| República Dominicana | 1 (caída de internet) | 2 (documentos con serie B) |
| Chile y Paraguay | No se usa | No se usa |
contingencyCodeUn documento en contingencia responde 200, igual que uno aceptado. Para distinguirlos, usa contingencyCode: el texto de message es solo descriptivo.
Matriz de presencia por país
| Campo | CL | CO | CR | SV | GT | PA | PE | PY | DO |
|---|---|---|---|---|---|---|---|---|---|
barcodeText | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓² | ✓ | ✓ |
barcodeBase64 | ✓¹ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓² | ✓ | ✓ |
countryIdentificationCode | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
statusCode / statusDescription / statusMessage | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓³ | – | ✓ |
applicationResponse | – | ✓ | ✓ | ✓ | – | ✓ | ✓ | – | ✓ |
timeGeneration | – | ✓ | ✓ | ✓ | – | ✓ | ✓ | – | ✓ |
timeValidation | – | ✓ | ✓ | ✓ | – | ✓ | – | – | – |
contingencyCode | – | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – | ✓ |
¹ Chile devuelve barcodeBase64 en formato PDF417 (no QR).
² Desde la versión 2.7.1, Perú devuelve el QR de SUNAT (Anexo B) y agrega el campo propio valorResumen (hash del XML firmado); en las guías de remisión, además, gre.qrUrl y gre.transportEnabled. Hasta la 2.7.0, barcodeText no se devolvía y barcodeBase64 llegaba como la cadena "null". Ver ficha de Perú.
³ Perú emite statusCode y statusMessage (leídos de la CDR de SUNAT/OSE), pero no statusDescription. Además devuelve el campo propio series — ver ficha de Perú.
Cada ficha de país incluye un mock de response con valores ilustrativos. Ver Comunicación por país.
🚦 Manejo de errores
xPOS-Core expresa cualquier resultado anómalo —error de validación, rechazo de la entidad tributaria, fallback de contingencia o reintento programado— a través de tres campos del núcleo del response: message, stage y error_description. El catálogo completo de etapas vive en Códigos de errores xPOS-Core; esta sección describe el contrato de integración que el POS debe respetar para reaccionar a cada caso.
Contrato del response
Cuando el procesamiento del documento no termina en éxito, xPOS puebla los tres campos así (los errores previos al procesamiento tienen otra forma: ver Errores antes del procesamiento):
Ejemplo de response en error: ver el tab Response — Error al inicio de esta página.
Stage code vs. HTTP status
El stage es un campo del cuerpo y no es el status HTTP, pero el status HTTP de POST /api/v1/process-documents se deriva de él: TIMEOUT_ERROR_503 → 503, COMPLIANCE_ERROR_510 → 510 y cualquier otro error del procesamiento → 400. Por eso el code de cada fila del catálogo de errores es el status HTTP que recibe el POS.
| HTTP | Cuándo | Países |
|---|---|---|
200 | Documento procesado: aceptado por la entidad tributaria, en contingencia o encolado para envío diferido | Todos |
400 | Error de la petición o del documento, de foliación o firma, o rechazo de la entidad tributaria | Todos |
403 | xPOS bloqueado: bloqueo técnico, financiero o versión vencida | Todos |
404 | El origin no corresponde a un emisor instalado, o faltan las hojas de transformación del onboarding | Todos |
409 | Certificado de firma vencido o sin fecha de vencimiento, o falla interna al resolver el emisor | Todos (el certificado no se valida así en Chile) |
422 | El cuerpo no es JSON válido | Todos |
500 | Falla interna al armar la respuesta de error (SERVER_PROCESS_REQUEST_STAGE) | Todos |
503 | TIMEOUT_ERROR_503: la entidad tributaria no respondió a tiempo y el documento pudo haber llegado | Colombia, Costa Rica, El Salvador, Guatemala, República Dominicana y Perú |
510 | COMPLIANCE_ERROR_510: la entidad tributaria respondió algo que no es una respuesta válida, o recibió el documento y no lo procesó | Colombia y Perú |
Un documento en contingencia también responde 200: se distingue por contingencyCode en el cuerpo. En Chile y Paraguay el 200 indica que el documento quedó encolado y el veredicto de la entidad tributaria llega después. Un rechazo de la entidad tributaria responde 400, con la etapa de respuesta de la autoridad (DIAN_RESPONSE_STAGE, ET_RESPONSE_STAGE, MEGAPRINT_RESPONSE_STAGE, …).
Perú clasifica toda respuesta de su entidad tributaria en 200, 503, 510 o 400, de modo que el status HTTP ya le dice al POS qué hacer. El canal WebSocket no tiene status HTTP: devuelve el mismo JSON con su stage.
Errores antes del procesamiento
Antes de procesar el documento, xPOS valida la petición, el emisor, el estado del equipo y el certificado. Estos errores no pasan por el catálogo de etapas y, salvo los del emisor, no traen stage ni transactionId. El orden es el de las validaciones:
| HTTP | Causa | Cuerpo |
|---|---|---|
422 | El cuerpo no es JSON válido | { error } |
400 | Falta origin y el equipo tiene más de un emisor instalado | { error, message, error_description, stage } con stage = SET_CONTEXT_STAGE |
404 | El origin no corresponde a ningún emisor instalado | Ídem |
409 | Falla interna al resolver el emisor | Ídem |
403 | xPOS bloqueado: bloqueo técnico, financiero o versión vencida | { errors: [] } |
400 | country, operation, typeDoc, env o inputType inválidos para el país, o el cuerpo está vacío o no corresponde al inputType | { errors: [] } o { message } |
404 | Faltan las hojas de transformación del onboarding | { errors: [] } |
409 | Certificado de firma vencido —incluso después de recargar la configuración— o sin fecha de vencimiento (no aplica a Chile) | { message } |
Qué tiene que hacer el POS
Cada fila del catálogo trae una acción sugerida que el POS debería adoptar como contrato (en Perú, la acción la da directamente el código HTTP):
| Acción | Decisión del POS |
|---|---|
| Corregir y reintentar | El input es el responsable. Corregir el dato indicado por error_description y reenviar POST /api/v1/process-documents. |
| Reintentar | Error transitorio (red, token, validación temporal). Reenviar tal cual. |
| Recargar y reintentar | El estado local del xPOS no está sano (folios, certificados, plantillas). Llamar a PUT /api/v1/reobtain-config y reenviar. |
| Corregir | Revisar el caso sin reenviar automáticamente (la entidad tributaria ya respondió y deja la acción al operador). |
| Fin del proceso | No requiere acción del POS (documento duplicado, reintento automático programado en xPOS, o escalamiento manual a Gosocket). |
Cuando el POS pierde el response
Si la red se cortó o el POS reinició antes de procesar el response, no hace falta reenviar el documento: el endpoint GET /api/v1/status recupera el response original a partir del transactionId o el docNumber — ver Reobtención de estados. Para diagnóstico más profundo (auditoría, escalamiento), los logs operativos en GET /api/v1/db-data/logs se filtran por uuid o metadata libre.