Facturació FACe (B2G)
Envia factures FacturaE 3.2.2 a FACe — codis DIR3, XML signat XAdES-EPES conservat per intent, estats de tramitació, transmissions incertes i com recuperar-te, anul·lació, simulació en sandbox i l'scope facturae:write.
Facturar a una administració pública espanyola (B2G) és obligatori a través de FACe, el punt general d'entrada de factures electròniques (Ley 25/2013). Factuarea genera l'XML FacturaE 3.2.2 de qualsevol factura emesa, el signa XAdES-EPES amb el certificat de la teva empresa i el presenta al web service de FACe — i després segueix rastrejant l'estat de tramitació que informa FACe fins que la factura es paga (o es rebutja).
El cicle de vida complet el cobreixen les cinc operacions del grup FacturaE de la Referència de l'API:
- Descarregar l'XML FacturaE d'una factura — signat o sense signar, amb FACe o sense.
- Enviar una factura a FACe.
- Llistar els enviaments d'una factura.
- Recuperar un enviament per seguir el seu estat de tramitació.
- Sol·licitar l'anul·lació d'un enviament.
Les lectures usen l'scope facturae:read; enviar i anul·lar requereixen
facturae:write. El mòdul FacturaE està inclòs des del pla Profesional.
Totes les rutes d'aquesta guia pengen de /v1/companies/{company}/…: {company} és l'id (UUID v7)
del NIF amb què operes, i als exemples curl és $COMPANY_ID.
Arribar a un NIF explica com resoldre'l.
Abans d'enviar
Configura els codis DIR3 del client. Tot client administració
pública porta tres codis del directori DIR3, cadascun amb el format
^[A-Z][A-Z0-9]{8,9}$ (p. ex. L01280796), i opcionalment un quart, el
proponent. Configura'ls en crear o actualitzar el client:
curl -X PATCH https://api.factuarea.com/v1/companies/$COMPANY_ID/contacts/0197a2a8-4cf0-7a31-9a5e-3f2b8c1d6e42/customer-profile \
-H "Idempotency-Key: $(uuidgen)" \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Content-Type: application/json" \
-d '{
"dir3_accounting_office": "L01280796",
"dir3_managing_body": "L01280796",
"dir3_processing_unit": "L01280796"
}'| Camp | Rol DIR3 |
|---|---|
dir3_accounting_office | Oficina contable (01) |
dir3_managing_body | Órgano gestor (02) |
dir3_processing_unit | Unidad tramitadora (03) |
dir3_proponent | Proponente (04), opcional |
L'administració t'indica els codis (els tres primers sovint coincideixen); també pots consultar-los al directori públic DIR3. L'operació reemplaça el perfil, de manera que un codi que deixis fora s'esborra: envia tots els que vulguis conservar.
La factura captura aquests codis quan es crea, i pots substituir-los per
factura o corregir-los després d'emetre amb una
revisió administrativa. L'encaminament que
compta és el de la factura, no el del contacte en viu; els rols 01 a 03 són
obligatoris per enviar i el 04 és opcional. Si la factura té un encaminament
conegut sense centres, l'enviament falla amb client_missing_dir3_codes encara
que el contacte tingui codis.
Puja un certificat de signatura actiu. FACe només accepta factures
signades, així que l'enviament requereix el certificat FNMT (PKCS#12)
que la teva empresa ja usa per a VeriFactu
(POST /v1/companies/{company}/verifactu/certificates). Sense certificat actiu
l'enviament falla amb signing_certificate_required.
Emet la factura. Les factures en esborrany no poden viatjar a FACe —
enviar o emetre abans la factura és el que congela el seu contingut legal.
Els esborranys i les factures programades (encara sense número fiscal) responen invoice_not_emittable_for_facturae.
Descarregar l'XML FacturaE
Pots descarregar l'XML en qualsevol moment — per a presentació manual,
arxiu o validació — sense involucrar FACe. Qualsevol factura que ja tingui
número fiscal és exportable (també una cobrada, anul·lada o cancel·lada); només
les factures draft i scheduled no ho són. Una factura anterior sense
calendari de pagaments capturat s'exporta sense el bloc de venciments:
Factuarea mai no l'inventa.
curl -OJ https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/facturae \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"Amb un certificat actiu el cos va signat XAdES-EPES (política de signatura
Facturae v3.1) i el fitxer es diu .xsig; sense, l'XML torna sense signar
com a .xml. El header de resposta X-Facturae-Signed: true|false
distingeix ambdós casos. Consulta la
referència de l'endpoint.
La descàrrega tolera l'absència de certificat (obtens l'XML sense signar); l'enviament a FACe no — FACe exigeix la signatura.
Per obtenir el fitxer exacte que es va presentar en un intent, afegeix
submission_id:
curl -OJ "https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/facturae?submission_id=0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d" \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"Això retorna els bytes conservats d'aquell intent: mai no regenera, torna a signar
ni llegeix el certificat o el contacte actuals, així que és l'evidència del que va
rebre l'administració encara que la factura, els codis DIR3 o el certificat hagin
canviat després. La resposta afegeix X-Facturae-Sha256 (i el mateix valor com a
ETag) quan es coneix el hash del fitxer conservat. Un fitxer absent o corrupte
respon 500 facturae_artifact_unavailable; no es regenera. La factura i l'intent
s'han de correspondre; si no, 404.
Enviar a FACe
L'operació d'enviament no necessita cos de petició: la factura viatja a la ruta. Cada crida prepara un intent: congela la factura, l'encaminament DIR3 efectiu (proponent inclòs), el calendari de pagaments, el certificat que signa i l'XML signat exacte, i només després parla amb FACe:
curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/face-submissions \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)"Resposta (201 per a un intent nou):
{
"data": {
"id": "0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d",
"object": "face_submission",
"invoice_id": "0197b1c2-89ab-7def-8123-456789abcdef",
"status": "submitted",
"registry_number": "202612345678",
"dir3_accounting_office": "L01280796",
"dir3_managing_body": "L01280796",
"dir3_processing_unit": "L01280796",
"error_code": null,
"error_message": null,
"status_updated_at": "2026-06-12T10:15:00Z",
"last_polled_at": null,
"created_at": "2026-06-12T10:15:00Z",
"dir3_proponent": null,
"administrative_version": 1,
"administrative_revision_id": null,
"payment_terms_version": 1,
"source_fingerprint": "6d2f8a4c1b73e5b0a9c4d7e1f3a6b8c2d5e9f0a1b4c7d8e2f3a5b6c9d0e1f2a3",
"artifact_sha256": "b4c7d8e2f3a5b6c9d0e1f2a36d2f8a4c1b73e5b0a9c4d7e1f3a6b8c2d5e9f0a1",
"prepared_at": "2026-06-12T10:14:58Z",
"transmission_started_at": "2026-06-12T10:14:59Z",
"can_transmit": false,
"requires_reconciliation": false,
"signing_certificate_fingerprint": "e5b0a9c4d7e1f3a6b8c2d5e9f0a1b4c7d8e2f3a5b6c9d0e1f2a36d2f8a4c1b73",
"artifact_status": "ready"
}
}registry_number és l'assentament registral de FACe que acredita la
presentació — conserva'l per a qualsevol disputa amb l'administració. Els camps
addicionals identifiquen el que ha congelat l'intent: source_fingerprint,
artifact_sha256 (hash de l'XML conservat), l'administrative_version i la
payment_terms_version usades i l'empremta del certificat. artifact_status és
ready, unverified (un intent anterior al hash), unavailable o corrupt.
L'intent és la unitat, no la crida
El cos és opcional. Sense ell, Factuarea crea la identitat de l'intent i respon
201. També pots enviar el teu propi submission_id (un UUID v7) al cos:
curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/invoices/0197b1c2-89ab-7def-8123-456789abcdef/face-submissions \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{ "submission_id": "0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d" }'- Un
submission_idnou crea un intent nou:201. - Un d'existent d'aquella factura el continua:
200, amb el mateix XML conservat i el mateix certificat, sense tornar a mirar el certificat actual ni el contacte. Si FACe ja l'havia acceptat, reps el resultat desat i no s'envia res dues vegades. submission_id: nulles rebutja, i un id d'una altra factura o d'una altra empresa és un404.- L'
Idempotency-Keyno substitueix elsubmission_id: la clau reprodueix una petició HTTP; l'id identifica l'intent durador. Les operacions d'enviament i cancel·lació estan declarades com a no reintentables automàticament (x-no-retry): els SDK no les reintenten, així que gestiona els errors com es descriu a continuació en lloc d'embolicar la crida en un bucle de reintents a cegues.
Si la crida acaba amb 502 face_transmission_failed (FACe caigut, timeout,
resposta mal formada) o 500 face_submission_completion_failed, l'intent
existeix i error.details.attempt_id et dona el seu id. No enviïs mai un
enviament nou a cegues: llista els intents de la factura
(historial)
o recupera aquell, i mira el seu status:
status després de l'error | Què significa | Què fas |
|---|---|---|
prepared | Congelat i signat, mai transmès. | Reintenta amb el mateix submission_id. |
transmission_uncertain | La petició ha sortit cap a FACe i es desconeix el resultat. Un timeout no demostra que FACe no l'hagi rebuda. | No tornis a enviar. Les crides responen 409 face_transmission_uncertain amb el mateix attempt_id fins que l'intent es concilii, cosa que Factuarea fa amb evidència auditada (requires_reconciliation: true); contacta amb suport. |
submitted i posteriors | FACe ja el té. | Segueix-lo com qualsevol enviament. |
error | L'intent ha fallat. Només s'allibera si FACe l'ha rebutjat explícitament (error_code: face_rejected) o s'ha confirmat la no recepció (confirmed_not_received). | En aquests casos corregeix la causa i envia de nou amb una identitat nova; si no, continua bloquejat. |
Un intent prepared o en qualsevol estat de tramitació no final en bloqueja un de nou
per a la mateixa factura (409 face_submission_already_exists), i un d'incert
respon 409 face_transmission_uncertain; rejected i cancelled l'alliberen. Un
409 face_submission_attempt_conflict vol dir que una altra petició ja té o ha
acabat aquell intent: torna a llegir-lo.
Seguir l'estat de tramitació
FACe informa de com l'administració tramita la factura. Factuarea consulta FACe periòdicament i actualitza cada enviament — recuperar el detall de l'enviament (o l'historial d'enviaments de la factura) és la manera de seguir el progrés; no hi ha endpoint de refresc a v1:
curl https://api.factuarea.com/v1/companies/$COMPANY_ID/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW"status | Significat |
|---|---|
prepared | XML signat conservat, encara sense transmetre. Continua'l amb el seu submission_id. |
transmission_uncertain | La transmissió ha començat i es desconeix el resultat. Bloqueja nous enviaments fins que es concilii. |
submitted | Presentada a FACe; número de registre assignat. |
registered_rcf | Registrada al RCF (el registre comptable de factures de l'administració). |
accounted | Reconeguda com a obligació comptable per l'administració. |
paid | L'administració informa de la factura com a pagada. |
rejected | Rebutjada per l'administració — consulta el motiu a FACe i emet una factura corregida. |
cancellation_requested | Has sol·licitat l'anul·lació; pendent de confirmació de FACe. |
cancelled | Anul·lació confirmada per FACe. |
error | Error local de transmissió — error_code i error_message porten el detall. |
Prefereixes push a polling? Subscriu-te als
esdeveniments de webhook facturae.face_submitted,
facturae.face_status_changed i facturae.face_cancellation_requested.
Sol·licitar l'anul·lació
Mentre la factura no s'hagi pagat ni rebutjat pots
sol·licitar-ne l'anul·lació
(anul·lació 4200). El reason és obligatori i viatja a FACe:
curl -X POST https://api.factuarea.com/v1/companies/$COMPANY_ID/face-submissions/0197c3d4-5e6f-7a8b-9c0d-1e2f3a4b5c6d/cancel \
-H "Authorization: Bearer fact_test_3pXnR2VbY7TcA9eFmN5z8KqW" \
-H "Content-Type: application/json" \
-d '{ "reason": "Factura emitida por error al organismo equivocado." }'L'anul·lació només es permet en un estat anul·lable (submitted,
registered_rcf, accounted); en cas contrari la crida respon
face_submission_not_cancellable. L'enviament passa a
cancellation_requested fins que FACe confirma l'estat final cancelled.
Mode de prova
Amb una clau de prova (fact_test_) tot el flux es simula: cap crida
SOAP arriba a FACe i l'enviament rep un número de registre sintètic amb
prefix FACE-SANDBOX-*. Les validacions de signatura i DIR3 segueixen
aplicant, així que el sandbox exercita els mateixos camins d'error que
producció. Consulta el mode de prova.
Errors
| HTTP | code / subcode | Quan |
|---|---|---|
| 404 | resource_not_found | La factura o l'enviament no existeix o pertany a una altra empresa. |
| 422 | business_rule_violation / invoice_not_emittable_for_facturae | La factura està en esborrany o programada, així que no té número fiscal — emet-la primer. |
| 422 | business_rule_violation / client_missing_dir3_codes | Al client li falta un o més codis DIR3. |
| 422 | business_rule_violation / signing_certificate_required | Sense certificat de signatura actiu — puja'n un via POST /v1/companies/{company}/verifactu/certificates. |
| 422 | business_rule_violation / face_submission_not_cancellable | L'enviament no està en un estat anul·lable. |
| 409 | resource_already_exists / face_submission_already_exists | Ja existeix un enviament actiu per a la factura. |
| 422 | face_submission_rejected | FACe ha analitzat l'enviament i l'ha rebutjat amb el seu propi codi (codi DIR3 erroni, signatura no vàlida, duplicat); no ha registrat la factura. details.attempt_id identifica l'intent (el seu error_code és face_rejected): corregeix les dades i envia de nou amb una identitat nova. |
| 409 | face_transmission_uncertain | Un intent anterior té un resultat desconegut. No es transmet res; details.attempt_id és l'intent que has de revisar. |
| 409 | face_submission_attempt_conflict | Una altra petició té o ja ha completat aquell intent. Torna a llegir-lo. |
| 500 | face_submission_completion_failed | No s'ha registrat el resultat; l'intent es conserva (details.attempt_id) i continua bloquejat. |
| 500 | facturae_artifact_unavailable | L'XML conservat de l'intent falta o està corrupte; no es regenera. |
| 403 | facturae_operation_forbidden | L'autoritat vigent de l'emissor no permet l'operació (enviar exigeix autoritat d'enviament; cancel·lar exigeix accés d'edició al mòdul). |
| 403 | insufficient_scope | La clau no té l'scope facturae:write. |
| 502 | face_transmission_failed | El web service de FACe ha fallat o ha esgotat el temps. L'intent es conserva i details.attempt_id l'identifica: mira el seu status abans de fer res més. |