Factuarea APIDevelopers
Contrato

Facturación desde terminales desatendidos

Una factura simplificada ya cobrada desde un cajero en una sola llamada idempotente, la remisión de VeriFactu a través de Factuarea, la subsanación de registros aceptados y errores por línea. Tres cambios que rompen: una línea sin tipo ya no toma el 21 %, emitir se rechaza cuando el registro no cabe en el esquema de la AEAT y, en modo NO VERI*FACTU, hace falta un certificado utilizable. POST /v1/verifactu/records/{id}/retry ya no responde max_retries_exceeded.

3 de octubre de 2026 — Un terminal de autoservicio o una máquina expendedora pueden ya emitir una factura simplificada cobrada, con su QR VERI*FACTU, en una sola llamada idempotente. Detrás hay una revisión de cómo llegan los registros a la AEAT, una forma de remitir a través de Factuarea en vez de con tu propio certificado y una comprobación más estricta antes de emitir una factura. Lee primero los tres cambios que rompen; las operaciones nuevas y las actualizadas se listan al final.

Cambios que rompen

1. Una línea sin tipo de IVA ya no toma el 21 %. Una línea de venta sin tax_rate, sin impuesto referenciado y sin producto con impuesto toma ahora el IVA por defecto de la empresa para ese tipo de documento. Si la empresa no tiene ninguno, la llamada responde 422 missing_required_param con error.param: lines.N.tax_rate. Afecta a facturas, presupuestos, proformas, albaranes y facturas recurrentes, en la API v1 y en MCP. Envía tax_rate explícitamente, o configura el IVA por defecto.

2. Una factura cuyo registro no cabe en la AEAT no se emite. Con VeriFactu activado, una factura que antes se emitía y cuyo registro fallaba después responde ahora 422 verifactu_not_eligible antes de emitirse, con el campo en error.param. No se consume número. Los límites están en la tabla de abajo.

3. El modo NO VERI*FACTU necesita un certificado utilizable para emitir y para anular. Una empresa que ha activado VeriFactu en modo NO VERI*FACTU y no tiene un certificado utilizable ya no puede emitir ni anular hasta que suba uno: la operación responde 422 verifactu_not_eligible con subcode: signing_certificate_unavailable y error.param certificate, representation o system_certificate, y la factura queda como estaba. No afecta a las empresas con VeriFactu desactivado — cuyo modo por defecto es no_verifactu sin estar en el sistema — ni a las empresas en modo VERI*FACTU, que nunca se bloquean por esto.

Además, POST /v1/verifactu/records/{record}/retry ya no responde max_retries_exceeded para los registros de facturación: ya no hay límite de intentos. El código sigue aplicando al reintento de un evento en modo no_verifactu.

Cobro desatendido en POST /v1/invoices

POST /v1/invoices y la tool MCP create_invoice ganan, con la misma semántica:

  • type: "F2": una factura simplificada, sin cliente (ticket anónimo) o con uno (factura simplificada cualificada, registrada como F1 con FacturaSimplificadaArt7273).
  • prices_include_tax: el unit_price de cada línea es el precio final, y la base se calcula al céntimo para que el total sea igual a la suma que enviaste («cualquier línea, y partir»; 422 amount_reconciliation_failed solo cuando una retención o un recargo desplazan el total).
  • payment (method, paid_at, reference): el pago se registra tras emitir.
  • operation_on: el día de la operación cuando difiere de issued_on.
  • options.register_verifactu: el alta VeriFactu se genera antes de responder. options.wait_for_pdf espera hasta unos 15 segundos al PDF A4.

El 201 lleva tres bloques adicionales, solo en un cobro desatendido: verifactu (status, error_code, aeat_status, huella, qr_url, qr_png_base64, legend, csv), pdf (status, url, expires_at) y public_url. La guía es Facturación desde terminales desatendidos, y lo que debe declarar tu terminal está en Cumplimiento del componente del integrador.

El reenvío por external_id no caduca nunca:

  • El mismo external_id con el mismo tipo y total responde 200 con Idempotent-Replayed: true y la factura ya emitida, completando el alta y el pago si faltaban. Un email encolado o entregado no se vuelve a enviar.
  • Un tipo o un total distintos responde 409 idempotency_key_reused, con error.type: idempotency_error, subcode: unattended_replay_mismatch y param: external_id.
  • Otra petición con el mismo external_id todavía en curso hace que la segunda espere hasta 20 segundos, y responda después 409 resource_locked si la primera no ha terminado; la misma petición puede enviarse otra vez.

Un email pedido sin destinatario posible (options.send_automatically sin options.send_to y sin email de cliente) se rechaza antes de crear nada: 422 missing_required_param con error.param: options.send_to, sin borrador y sin número. También rige para las demás peticiones de POST /v1/invoices, que antes rechazaban después de crear el borrador.

Emitir se rechaza cuando el registro no cabe

422 verifactu_not_eligible lo devuelven las operaciones que emiten una factura: POST /v1/invoices con options, POST /v1/invoices/{id}/issue, POST /v1/invoices/{id}/send y …/mark-sent cuando emiten, POST /v1/invoices/{id}/corrective y POST /v1/invoices/substitute-simplified. La factura sigue siendo un borrador y no consume número; corriges el campo y repites. En bulk-create y bulk-status el rechazo aparece en failures[], por elemento.

error.paramCausa
client_idNombre del cliente ausente o de más de 120 caracteres; un NIF español que no tiene 9 caracteres; una identificación extranjera de más de 20; un país que la AEAT no admite; una factura completa sin cliente.
series_idEl número de la factura tiene más de 60 caracteres o caracteres que la AEAT no admite.
original_invoice_idEl número de la factura rectificada no es admisible.
simplified_invoice_uuidsEl número de una factura simplificada sustituida no es admisible.
company_nameRazón social de la empresa de más de 120 caracteres. Una razón social ausente es 422 business_rule_violation con el mismo param.
linesMás de 12 desgloses fiscales, o un importe que no cabe en 12 cifras enteras y 2 decimales.
totalUn total, o su cuota, que no cabe en el formato; una F2 por encima de 3.000 €.
typeLa marca de simplificada cualificada con un tipo que no la admite.

Sin certificado de firma utilizable

Para una empresa con VeriFactu activado en modo NO VERI*FACTU, emitir y anular se rechazan antes de ejecutarse cuando la empresa no puede firmar el registro. Las operaciones son POST /v1/invoices con options, …/issue, …/send, …/mark-sent, …/corrective, substitute-simplified, …/annul y …/void. error.param dice qué falta:

error.paramQué faltaQuién lo resuelve
certificateEl certificado de la empresa está ausente, caducado, revocado, de otro NIF o ilegible.La empresa, en Ajustes → Certificado digital.
representationLa representación que permite a Factuarea firmar en nombre de la empresa no está activa.La empresa: registrarla o cambiar a su propio certificado.
system_certificateEl certificado de Factuarea no está disponible.Factuarea.

GET /v1/invoices/{invoice}/can-annul lo anticipa: can_annul es false y reasons lleva el mismo mensaje. En bulk-status el rechazo aparece en failures[], por elemento. Consulta Alta automática en VeriFactu.

Anular una operación cobrada, tickets y fecha de la operación

  • revert_collections — POST /v1/invoices/{invoice}/annul lo acepta (false por defecto). Con true, todos los pagos vigentes se revierten con el motivo reservado issued_in_error y la factura se anula en una sola operación atómica. GET …/can-annul añade requires_collection_reversal y active_collections_amount. POST /v1/invoices/{invoice}/payments/{payment}/reversal rechaza issued_in_error con 422 reversal_reason_reserved. POST …/void no tiene esta opción.
  • Formato ticket — GET /v1/invoices/{invoice}/pdf y …/pdf-link aceptan format: a4 (por defecto), ticket_80 o ticket_58. Cada formato se genera y se guarda en caché por separado, y el ETag cambia cuando se crea el alta VeriFactu y con el formato.
  • operation_on — el recurso de factura lo devuelve, y POST /v1/invoices, PUT /v1/invoices/{invoice} y POST /v1/invoices/bulk-create lo aceptan. No puede ser posterior a issued_on (422 operation_date_after_issue_date) salvo que la primera línea que declara un regime_key use 14 o 15, y una factura rectificativa lo hereda.
  • Detalle de pagos — cada entrada de payments.detail en el recurso de factura lleva las cinco claves de reversión (is_reversed, reversed_at, reversal_reason, reversal_reason_text y reversal_note), también un pago que sigue en vigor (false y null).
  • Envío de la proforma — shipping_cost es un importe con IVA incluido. Al convertir la proforma en factura se desglosa en base e IVA y se conserva el total.
  • Conversiones — convertir un presupuesto, una proforma o un albarán responde, solo cuando hay algo que advertir, warnings y warning_codes (zero_rate_line_without_exemption): una línea quedó al 0 % sin causa de exención. No bloquea. El warnings de la factura rectificativa pasa a ser opcional.

Errores que nombran la línea

Un error de dominio que nace de una línea de un documento lleva line_index, la posición de la línea empezando en cero, junto a param: error.line_index en la API (y como miembro raíz de application/problem+json) y error.data.line_index en MCP. Es aditivo; param sigue nombrando el campo exactamente como antes.

Rectificativas y edición

  • Naturaleza por línea en una rectificativa — POST /v1/invoices/{invoice}/corrective y la tool create_corrective_invoice aceptan unit, regime_key, exemption_reason y exemption_reason_text por línea. Una clave que omites hereda la línea original por índice; una clave que envías la sustituye; null significa ninguno.
  • Las ediciones no revalidan lo ya guardado. Editar un documento de las cinco familias de venta ya no exige que las referencias que ya lleva guardadas (variante o presentación del catálogo, configuración, opciones, gastos vinculados) sigan activas o existentes. Las referencias nuevas o cambiadas se validan como siempre. update_delivery_note en MCP valida como la API.
  • original_pack_data se devuelve y se conserva también en las líneas de proformas y albaranes, de modo que sobrevive a las ediciones y a la conversión a factura.

VeriFactu: remisión, registros bloqueados y subsanación

  • Remisión por lotes — los registros de una empresa van a la AEAT en lotes ordenados de hasta 1.000, respetando el tiempo de espera que indica la AEAT, con la respuesta leída registro a registro. Los fallos técnicos se reintentan al menos cada hora sin tope. Consulta Cómo llegan los registros a la AEAT.
  • POST /v1/verifactu/records/retry-blocked (nueva, scope verifactu:write) — reactiva todos los registros bloqueados de la empresa y responde 202 con data.reactivated. La tool MCP es retry_blocked_verifactu_records.
  • Estadísticas — GET /v1/verifactu/stats añade pending_incident_count, blocked_incident_count y oldest_pending_at.
  • Registro — añade is_blocked, block_reason, aeat_error_code (incluye SCHEMA_INVALID, un registro que incumplió el esquema de la AEAT y nunca se envió) y can_subsanar.
  • POST /v1/verifactu/records/{record}/subsanar — ahora admite también registros aceptados y genera siempre un registro nuevo: data.id es el id del nuevo, no el del registro que enviaste. Los errores de la subsanación son record_not_rejected, record_not_subsanable y requires_annulment. Consulta Subsanación de registros VeriFactu.
  • Remisión por un tercero — GET, POST y DELETE /v1/verifactu/representation (nuevas) registran, leen y revocan la representación, con valid_until (como máximo cinco años), is_expired y un aviso 30 y 7 días antes de que caduque, y remission_mode en PUT /v1/verifactu/settings. El 201 del registro lleva remission_mode; revocar admite reason de 3 a 500 caracteres. GET /v1/verifactu/config añade remission_mode, social_collaborator_available, has_active_representation, active_representation_valid_until, active_representation_is_expired y presenter_certificate_status. Las tools MCP son get_company_representation, register_company_representation y revoke_company_representation.
  • Declaración responsable — GET /v1/verifactu/declaracion-responsable devuelve el contenido del artículo 15: components, producer_address y signature_types, y system_name es ahora el nombre del sistema y no su código.
  • Facturas simplificadas — una factura simplificada con el NIF del destinatario se registra como F1 con FacturaSimplificadaArt7273, y su rectificativa como R1 a R4; la rectificativa de una anónima sigue siendo R5.

Códigos de error: verifactu_not_eligible, signing_certificate_unavailable, resource_locked, idempotency_key_reused, unattended_replay_mismatch, amount_reconciliation_failed, reversal_reason_reserved, operation_date_after_issue_date, simplified_invoices_disabled, representation_required, invalid_representation y social_collaborator_unavailable.

Migración

  1. Envía tax_rate en cada línea de venta, o configura el IVA por defecto de la empresa para cada tipo de documento, y trata 422 missing_required_param con lines.N.tax_rate.
  2. Trata 422 verifactu_not_eligible en cada operación que emite una factura: se recupera corrigiendo el campo de error.param.
  3. Si una empresa funciona con VeriFactu en modo NO VERI*FACTU, comprueba que tiene un certificado utilizable (o una representación activa) antes de emitir o anular.
  4. Deja de ramificar según max_retries_exceeded en los registros de facturación.
  5. Si llamas a subsanar, lee data.id como el registro nuevo.
  6. Un terminal envía un external_id estable por venta y reenvía la misma petición hasta recibir una respuesta definitiva.

Nuevos endpoints4

EndpointDescripción
POST/v1/verifactu/records/retry-blockedReintentar todos los registros VeriFactu bloqueados
GET/v1/verifactu/representationRecuperar la representación vigente
POST/v1/verifactu/representationRegistrar una representación
DEL/v1/verifactu/representationRevocar la representación vigente

Endpoints actualizados32

EndpointDescripción
POST/v1/invoicesCrea una factura
PUT/v1/invoices/{invoice}Actualizar una factura
POST/v1/invoices/bulk-createCrear facturas en bloque
GET/v1/invoicesListar todas las facturas
GET/v1/invoices/{invoice}Recupera una factura
POST/v1/invoices/{invoice}/issueEmite una factura
POST/v1/invoices/{invoice}/sendEnvía la factura por email
POST/v1/invoices/{invoice}/mark-sentMarca una factura como enviada
POST/v1/invoices/{invoice}/correctiveGenerar factura rectificativa
POST/v1/invoices/substitute-simplifiedSustituir facturas simplificadas por factura completa
POST/v1/invoices/{invoice}/annulAnular una factura
POST/v1/invoices/{invoice}/voidAnular una factura
GET/v1/invoices/{invoice}/can-annulComprobar elegibilidad para anulación
GET/v1/invoices/{invoice}/pdfDescargar el PDF de la factura
GET/v1/invoices/{invoice}/pdf-linkGenerar enlace temporal a PDF
POST/v1/invoices/{invoice}/payments/{payment}/reversalAnular un pago de una factura
GET/v1/invoices/{invoice}/verifactuRecupera el registro VeriFactu de la factura
POST/v1/quotes/{quote}/convertConvertir presupuesto en factura
POST/v1/proformas/{proforma}/convertConvertir proforma en factura
POST/v1/delivery_notes/{delivery_note}/convertConvertir albarán en factura
GET/v1/verifactu/configRecupera la configuración de VeriFactu
PUT/v1/verifactu/settingsActualizar la configuración de VeriFactu
GET/v1/verifactu/statsObtener estadísticas de VeriFactu
GET/v1/verifactu/recordsLista los registros VeriFactu
GET/v1/verifactu/records/{record}Obtener un registro VeriFactu
POST/v1/verifactu/records/{record}/retryReintenta la transmisión a VeriFactu
POST/v1/verifactu/records/{record}/subsanarSubsanar un registro VeriFactu
POST/v1/verifactu/records/find-by-csvBuscar un registro VeriFactu por CSV de la AEAT
POST/v1/verifactu/records/find-by-huellaBuscar un registro VeriFactu por hash
POST/v1/verifactu/records/find-by-invoice-numberBuscar un registro VeriFactu por número de factura
GET/v1/verifactu/declaracion-responsableRecupera la declaración responsable actual
GET/v1/verifactu/declaracion-responsable/historyListar el historial de declaración responsable

En esta página

¿Te echamos una mano?Contactar con soporte