Errores
Todos los errores traen la misma forma: un objeto error con
code y message. El code es estable y es
contra el que conviene programar; el mensaje está en español y puede cambiar de redacción.
details.invoice: la factura queda guardada en estado
error para que puedas leer el motivo contra un folio real y reintentar sobre ella.
Un rechazo no gasta timbre.
De la API
Nuestros, y los que se resuelven de tu lado.
- unauthorized
- 401
- Falta la llave o ya fue revocada.
- plan_required
- 403
- La API está incluida en el plan Pro.
- payment_required
- 402
- La cuenta tiene un pago pendiente.
- not_found
- 404
- Ese recurso no es de tu cuenta, o no existe. Contestamos igual a los dos.
- missing_parameter
- 422
- Falta un campo obligatorio. El mensaje dice cuál.
- invalid_parameter
- 422
- Un campo está presente pero no se puede usar: una cantidad que no es número, una fecha que no es fecha.
- issuer_not_ready
- 422
- Al emisor le falta su régimen, su código postal o su CSD.
- folio_conflict
- 409
- Otra factura tomó ese folio mientras timbrábamos ésta. Reintenta.
- document_unavailable
- 404
- La factura no está timbrada, o su comprobante todavía no llega.
- renderer_unavailable
- 503
- El servicio que arma el PDF no respondió. El XML sí está.
Del PAC
Sobre el sello, el certificado y la cuenta. Todos llegan con 422.
- invalid_seal
- El sello no coincide con la cadena original.
- csd_revoked
- El certificado está revocado o caduco.
- csd_not_from_sat
- El certificado no lo expidió el SAT. En sandbox hay que usar los CSD de prueba.
- duplicate_cfdi
- Ese comprobante ya tiene timbre.
- date_out_of_range
- La fecha de emisión tiene más de 72 horas, o está en el futuro.
- no_stamps_left
- El RFC emisor no tiene timbres asignados.
- account_suspended
- La cuenta del PAC está suspendida. Se puede reintentar.
De la matriz del Anexo 20
Las validaciones del SAT sobre el contenido del comprobante. Traducimos las más frecuentes a un código estable; el
resto llega como pac_error con el texto del SAT, que suele traer entre paréntesis el
dato exacto que falló.
- cfdi_use_not_allowed
- El uso del CFDI no lo admite el régimen del receptor. Es el rechazo más común de todos.
- recipient_not_registered
- Ese RFC no está en el padrón del SAT, o está cancelado.
- recipient_name_mismatch
- La razón social tiene que ir tal cual el SAT la tiene, sin el régimen de capital.
- recipient_postal_code_mismatch
- El código postal del receptor no es el que el SAT tiene para ese RFC.
- recipient_regime_mismatch
- El régimen del receptor no es el que el SAT tiene registrado.
- exchange_rate_missing
- Falta el tipo de cambio, obligatorio en cualquier moneda que no sea MXN.
- payment_form_must_be_99
- Una factura PPD lleva la forma de pago 99, por definir.
- invalid_product_key
- La clave de producto o servicio no está en c_ClaveProdServ.
- invalid_unit_key
- La clave de unidad no está en c_ClaveUnidad.
- total_mismatch
- El total no cuadra con el subtotal, los descuentos y los impuestos.
- unclassified
- El SAT rechazó sin clasificar el motivo. El mensaje trae su texto crudo.
Qué se reintenta
folio_conflict, account_suspended,
no_stamps_left y renderer_unavailable son de estado, no
del comprobante: reintentar tiene sentido. Los demás describen algo que hay que corregir antes de volver a llamar.
Reintenta siempre con llave de idempotencia.