Auto-facturació amb Stripe
Emet factures automàticament des dels cobraments de Stripe Connect — captura de NIF al Checkout, llindar de factura simplificada, exigir NIF i quins cobraments es deriven a revisió manual.
Quan connectes Stripe mitjançant Stripe Connect, Factuarea pot emetre una
factura automàticament per cada cobrament correcte: el cobrament es converteix
en una factura amb status: sent, es dona d'alta a VeriFactu i se li registra un
Payment. El flux és idempotent d'extrem a extrem, així que un webhook
reentregat mai produeix una factura duplicada.
L'alimenten dos fluxos:
- Flux A — un cobrament que paga una factura de Factuarea ja existent (una Checkout Session que Factuarea va crear des d'un enllaç de pagament). La factura ja existeix; el cobrament la marca com a pagada.
- Flux B — un cobrament espontani sense factura prèvia (un Payment Link que el comerç va crear al seu propi Dashboard de Stripe, o qualsevol altre cobrament de Connect). Factuarea crea la factura a partir del cobrament.
La configuració es llegeix i s'escriu a través dels endpoints v1 a nivell d'empresa:
- Obtenir la configuració d'auto-facturació
(
stripe_autoinvoicing:read). - Actualitzar la configuració d'auto-facturació
(
stripe_autoinvoicing:write). - Llistar cobraments auto-facturats
(
stripe_autoinvoicing:read). - Llistar rectificatives auto-facturades
(
stripe_autoinvoicing:read).
Si gestiones diverses botigues amb comptes de Stripe diferents, cada compte té la seva pròpia sèrie i la seva pròpia configuració — consulta Diverses botigues.
L'auto-facturació està limitada pel mòdul d'integració amb Stripe del teu pla
i ve desactivada per defecte — activa-la explícitament amb enabled: true.
Què exposa l'API de Stripe. Configuració d'auto-facturació a nivell d'empresa (una comoditat heretada del model de botiga única — la font de veritat real és la configuració per compte connectat, veure Diverses botigues), comptes connectats, cobraments auto-facturats, rectificatives i payouts per a la conciliació bancària.
Diverses botigues
Un negoci pot operar diverses "botigues" o línies (una botiga física + un curs en
línia) amb comptes de Stripe diferents (Stripe Connect) i voler numeració de
factures independent per a cadascuna (TIENDA-2026-…, CURSOS-2026-…).
Factuarea modela cada compte de Stripe que connectes com un compte connectat:
cada Account Link que completes afegeix un compte — mai sobreescriu l'anterior —
i els cobraments de cada compte s'enruten a la sèrie i la configuració d'aquest
compte.
Cada compte connectat porta:
- una sèrie (
series_id) usada per a les factures auto-creades a partir dels seus cobraments —nullsignifica que s'usa la sèrie de factures per defecte de l'empresa; - la seva pròpia configuració d'auto-facturació (
autoinvoicing_enabled,simplified_threshold_cents,require_nif,refunds_enabled,subscription_autoinvoicing_enabled) — tota regla fiscal d'aquesta pàgina aplica per compte.
Quan arriba un webhook, Factuarea resol el compte de Stripe (acct_xxx) al seu
compte connectat i emet la factura en la sèrie d'aquest compte, amb la política
fiscal d'aquest compte — de manera que dues botigues produeixen factures en dues
sèries de numeració separades i correctes.
Els comptes nous neixen segurs
Un compte acabat de connectar no hereta la configuració d'un altre compte: neix amb els mateixos valors per defecte segurs que una alta nova — auto-facturació desactivada, llindar 400 €, "exigir NIF" desactivat, devolucions actives, subscripcions desactivades — i sense sèrie (cau en la sèrie per defecte de l'empresa fins que li n'assignes una). Configura'l explícitament abans que emeti res.
Endpoints v1 per compte
Gestiona els comptes sota el recurs connected-accounts (mateixos scopes
stripe_autoinvoicing:read|write; la identitat és l'id del compte, un UUID v7):
- Llistar comptes connectats
(
stripe_autoinvoicing:read). - Obtenir un compte connectat
(
stripe_autoinvoicing:read). - Actualitzar un compte connectat
— nom,
series_id(envianullper netejar-la) i la configuració per compte (stripe_autoinvoicing:write). - Desconnectar un compte connectat
(
stripe_autoinvoicing:write).
# Assignar la sèrie CURSOS i activar l'auto-facturació en una botiga
curl -X PUT https://api.factuarea.com/v1/connected-accounts/0192f3a4-… \
-H "Authorization: Bearer fact_test_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0192f3a4-…" \
-d '{
"series_id": "0192aaaa-…",
"autoinvoicing_enabled": true
}'Desconnectar un compte conserva les seves factures ja emeses i el seu historial;
els webhooks posteriors es registren sense processar. Referenciar l'id d'un
compte que pertany a una altra empresa retorna 404 (connected_account_not_found)
— l'aïllament multi-tenant mai filtra l'existència.
L'endpoint a nivell d'empresa mentre tens una botiga
Els endpoints de configuració
a nivell d'empresa de dalt segueixen vàlids mentre tens exactament un compte
connectat: el GET retorna la configuració efectiva d'aquest únic compte i el
PUT fa de proxy cap a ell (escriu en la configuració del compte, mai una
còpia duplicada a nivell d'empresa).
Tan bon punt connectes un segon compte, la configuració a nivell d'empresa ja
no pot respondre a "quin compte?". Tant el GET com el PUT retornen llavors 422
(per_account_config_required, missatge en castellà) apuntant-te als endpoints per
compte — Factuarea mai escriu en dos llocs, així que no hi ha divergència entre
una configuració a nivell d'empresa i els comptes.
Una sola font de veritat. La configuració per compte és l'únic lloc on viuen
els ajustaments. L'endpoint a nivell d'empresa és una comoditat que fa de proxy al
compte únic; mai guarda una còpia separada, de manera que llegir i escriure sempre
coincideixen. Amb dos o més comptes, usa connected-accounts/{account}
directament.
Factura ordinària o simplificada
Una factura espanyola necessita el NIF del destinatari per emetre's com a factura ordinària (F1). Un cobrament B2C sense NIF és justament el cas que la normativa resol amb una factura simplificada (F2). Factuarea decideix quina emetre a partir de les dades que porta el cobrament més la teva política fiscal:
| Situació | Factura emesa |
|---|---|
| Es captura un NIF vàlid al Checkout, o el client resolt ja té un NIF a la seva fitxa | Ordinària (F1) |
| Sense NIF, total del cobrament igual o per sota del llindar i "exigir NIF" desactivat | Simplificada (F2) |
| Sense NIF i (total per sobre del llindar o "exigir NIF" activat) | Revisió manual — no s'auto-emet cap factura |
Un NIF capturat es valida contra el format espanyol (NIF/NIE/CIF). Un NIF amb format no vàlid compta com a sense NIF, així que mai s'emet una F1 amb dades escombraries.
Els cobraments derivats a revisió manual no es perden: queden registrats al log de la integració perquè emetis la factura a mà. L'auto-facturació continua amb la resta — un cobrament en revisió mai fa fallar el webhook.
El sostre legal absolut d'una factura simplificada és de 3.000 €, garantit pel propi domini de facturació: un cobrament sense NIF per sobre de 3.000 € sempre va a revisió manual, sigui quin sigui el llindar configurat.
Capturar el NIF al Checkout
Perquè un client que sí té NIF pugui aportar-lo, les Checkout Sessions que crea
Factuarea (Flux A) activen la recollida de l'identificador fiscal de Stripe.
El client pot introduir el seu es_cif/eu_vat en pagar, i aquest NIF encamina
cap a la F1.
El NIF també es llegeix de qualsevol checkout.session.completed entrant:
- de
customer_details.tax_ids(el camp estàndard de Stripe), i - dels camps personalitzats dels Payment Links que el comerç construeix al
seu propi Dashboard de Stripe — Factuarea busca un camp la clau del qual
sembli un identificador fiscal (
nif,dni,cif,vat,tax).
Un cobrament que arriba només com a payment_intent.succeeded (sense Checkout) no
porta cap NIF capturat, però encara pot ser una F1 si el client es resol per
email i ja té un NIF a la seva fitxa.
El llindar
simplified_threshold_cents és l'import en cèntims igual o per sota del qual
un cobrament sense NIF s'auto-emet com a factura simplificada. El seu valor per
defecte és 40000 (400 €) i accepta qualsevol valor en el rang [0, 300000]
(0–3.000 €).
Un valor per defecte conservador de 400 € és deliberat: el sostre de 3.000 € només és legal en sectors taxats concrets, i Factuarea no coneix el teu sector — apuja el llindar únicament si la teva activitat ho permet.
curl -X PUT https://api.factuarea.com/v1/stripe-autoinvoicing/config \
-H "Authorization: Bearer fact_test_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0192f3a4-…" \
-d '{
"enabled": true,
"simplified_threshold_cents": 100000,
"require_nif": false
}'Tots dos camps fiscals són opcionals: si omets simplified_threshold_cents o
require_nif, es conserven els seus valors actuals. Un llindar fora del rang
retorna 422 (validation_error).
Exigir un NIF
require_nif (per defecte false) té dos efectes coherents:
- A les Checkout Sessions que crea Factuarea, l'identificador fiscal es marca com
a obligatori (
if_supported), de manera que se li sol·licita al client. - A la decisió de dalt, veta la F2: un cobrament sense NIF va a revisió manual en comptes de convertir-se en factura simplificada.
Activa'l quan la teva empresa no vulgui mai factures simplificades automàtiques: cada cobrament passa llavors a tenir NIF (F1) o a esperar-te en revisió manual.
Les factures auto-emeses són fiscalment reals i irreversibles (es crea el
registre d'Alta de VeriFactu). Valida la teva política fiscal primer amb una
clau fact_test_: al sandbox el registre de VeriFactu es
crea localment i mai es transmet a l'AEAT, així que pots exercitar la decisió
F1/F2/revisió sense risc abans de passar a producció.
L'esdeveniment sortint
Cada factura auto-creada — F1 o F2 — emet l'esdeveniment
invoice.auto_created i un
esdeveniment payment.received. En una factura simplificada el payload porta
client_id: null (sense destinatari), de manera que un receptor de webhooks pot
distingir la F1 de la F2.
Desglossament real d'IVA amb Stripe Tax
Si fas servir Stripe Tax, cada cobrament ja porta el desglossament fiscal real per línia — el tipus, la base imposable i, quan escau, la causa per la qual una línia està exempta o subjecta a inversió del subjecte passiu. Factuarea reflecteix aquest desglossament a la factura en lloc d'aplanar-ho tot a un únic tipus per defecte.
El webhook del Checkout no inclou les línies, així que Factuarea fa una segona crida de només lectura a l'API en nom teu per recuperar-les amb els seus impostos, i mapeja cada línia:
| Dada de Stripe Tax | Línia de la factura |
|---|---|
rate.percentage | el tipus d'IVA de la línia (vat_rate), tal qual — mai no es recalcula |
taxable_amount | la base imposable de la línia (preu unitari = base ÷ quantitat) |
taxability_reason zero_rated / product_exempt / customer_exempt | línia exempta al 0 % |
taxability_reason reverse_charge | línia amb inversió del subjecte passiu (ISP) al 0 % |
Així, un cobrament amb IVA mixt (p. ex. 21 % de consultoria + 10 % d'un llibre) es converteix en una factura amb dues línies reals, cadascuna al seu tipus, i el desglossament multi-IVA arriba fins al registre de VeriFactu.
L'IVA mai no es recalcula — Stripe ja l'ha calculat, i recalcular-lo introduiria desviacions de cèntims. Factuarea agafa el tipus i la base imposable directament de Stripe Tax.
Quan no hi ha Stripe Tax (no l'has activat al teu compte de Stripe) no canvia res: cada línia recorre a l'IVA per defecte de la teva empresa, igual que abans. Una empresa sense IVA per defecte configurat recorre al 0 % — mai a un 21 % fantasma.
Línies reals
Quan un cobrament porta diverses línies (diversos productes o conceptes), apareixen com a línies reals i independents a la factura — cadascuna amb la seva descripció, quantitat i preu — en lloc de col·lapsar-se en una de sola. Són línies lliures (no enllaçades al teu catàleg de productes).
Això és ortogonal al tipus de factura: la decisió F1/F2 de més amunt tria el tipus, el mapeig de línies tria les línies — tant una factura ordinària com una de simplificada obtenen les mateixes línies reals.
Un cobrament que arriba només com a payment_intent.succeeded (sense Checkout
Session, de manera que no hi ha línies recuperables), o un cobrament la
recuperació de línies del qual falla després dels reintents, continua produint
una factura: recorre a una sola línia amb l'IVA per defecte. La factura mai no
es perd per un detall no essencial.
Abans d'emetre, Factuarea valida el total: el total derivat de les línies
reflectides (suma de subtotal + IVA per línia, en EUR) ha de coincidir amb
l'import realment cobrat, dins d'una petita tolerància d'arrodoniment (±1 cèntim
per línia, mínim ±0,05 €). Si no coincideix, el cobrament es deriva a revisió
manual (total_mismatch) en lloc d'emetre una factura el total de la qual
divergeixi del cobrament real — el webhook respon correctament igualment.
Cobraments en una altra moneda
Un cobrament en una moneda diferent de l'EUR ja no es descarta. Factuarea el converteix a EUR fent servir el tipus de canvi de referència del Banc Central Europeu (BCE) de la data de pagament i emet la factura en euros — base, IVA i total, i el registre de VeriFactu/AEAT, tot en EUR (Art. 12.1 RD 1619/2012: la quota d'IVA s'ha de consignar en euros).
- Un cobrament en EUR passa intacte.
- Un cobrament ≠EUR amb tipus disponible es converteix; la traça de la conversió — import i moneda originals, tipus BCE i data del tipus — s'escriu a les notes de la factura i al registre d'integració per a l'auditoria fiscal.
- Un cobrament en una moneda sense tipus BCE disponible no s'auto-factura: es deriva a revisió manual i el webhook respon correctament igualment. Factuarea mai no inventa un tipus.
Els tipus del BCE es memoritzen a diari (sense taula de base de dades addicional), de manera que diversos cobraments ≠EUR del mateix dia comparteixen una sola consulta del tipus.
Emetre la factura en la moneda original (opció B) queda intencionadament fora d'abast — Factuarea sempre converteix a EUR (opció A).
Devolucions i factures rectificatives
Una factura emesa és fiscalment irreversible — mai s'esborra ni s'anul·la un
cop pagada. L'única manera legal de desfer-la és una factura rectificativa.
Per això, quan Stripe retorna un cobrament que Factuarea va facturar, Factuarea
tanca el cicle fiscal per tu: el webhook charge.refunded genera
automàticament una factura rectificativa enllaçada (amb el seu propi registre
R de VeriFactu), sense rectificar a mà.
Ho controla refunds_enabled (per defecte true). Només actua mentre
l'auto-facturació està activada — el gating és enabled && refunds_enabled. Una
empresa que mai va activar l'auto-facturació no veu cap canvi.
| Devolució | Rectificativa emesa |
|---|---|
Total (refunded: true) | Una rectificativa total que reflecteix tota la factura original com a línies negatives |
Parcial (amount_refunded < amount) | Una rectificativa partial amb una única línia negativa per l'import retornat, al tipus impositiu de la línia original |
La rectificativa s'emet sempre per diferències (AEAT TipoRectificativa: I),
perquè una devolució és un abonament amb imports negatius. Porta el motiu de
correcció devolucion; si l'original és una factura simplificada (F2), la
rectificativa s'emet com a R5 automàticament.
La factura original es localitza per dos camins — per la metadada
factuarea_invoice del cobrament (Flux A) o per l'UUID determinista derivat del
payment_intent (Flux B) — així que les devolucions de cobraments emesos abans
que existís aquesta funció també es rectifiquen.
La idempotència és per devolució individual. Stripe reenvia
charge.refunded amb l'amount_refunded acumulat, però Factuarea es basa en
l'id de cada devolució individual (re_xxx): cadascuna produeix com a màxim
una rectificativa. Un esdeveniment reentregat, o una segona devolució parcial,
mai abonen per duplicat. Una devolució la factura original de la qual no es pugui
localitzar, que no estigui en un estat rectificable (sent/paid) o que ja
estigui rectificada queda registrada al log de la integració per a revisió
manual — mai fa fallar el webhook.
Cada rectificativa automàtica emet l'esdeveniment
invoice.corrective_auto_created
(que porta la rectificativa, la factura original, el refund_id d'origen i el
provider), i pots llistar-les amb
Llistar rectificatives auto-facturades.
Per rebre devolucions has d'habilitar l'esdeveniment charge.refunded a
l'endpoint de webhook de Connect al Dashboard de Stripe. Com amb
l'auto-facturació, valida el flux primer amb una clau fact_test_: al
sandbox el registre R de VeriFactu es crea localment i mai
es transmet a l'AEAT. Per desactivar-ho, posa refunds_enabled: false — les
devolucions queden llavors al log de la integració per a gestió manual, el
comportament actual.
Cicles de subscripció
Si cobres amb Stripe Billing al teu compte connectat — subscripcions recurrents mensuals o anuals — Factuarea pot emetre una factura automàticament per cada cicle cobrat. Cada renovació que cobra Stripe produeix la seva pròpia factura conforme a VeriFactu, espejant el desglossament real (línies, període, impostos) que Stripe ja va calcular, igual que els cobraments únics.
És un toggle separat, subscription_autoinvoicing_enabled (per defecte
false), per sobre del flag general enabled. Tots dos han d'estar actius
perquè un cicle es facturi — activar només les subscripcions no fa res mentre
l'auto-facturació està globalment desactivada.
curl -X PUT https://api.factuarea.com/v1/stripe-autoinvoicing/config \
-H "Authorization: Bearer fact_test_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 0192f3a4-…" \
-d '{
"enabled": true,
"subscription_autoinvoicing_enabled": true
}'Quins cicles es facturen
Factuarea factura el cicle de facturació estàndard i deriva la resta a revisió
o l'ignora, segons el billing_reason de Stripe:
billing_reason | Què fa Factuarea |
|---|---|
subscription_create (primer cicle) | Es factura |
subscription_cycle (cada renovació) | Es factura |
subscription_update, subscription_threshold (prorrateigs standalone) | Revisió manual — es registra al log de la integració, no s'auto-factura |
manual, upcoming, quote_accept, altres | S'ignora amb un log informatiu |
- Els trials no facturen. Un cicle el
invoice.totaldel qual és 0 € (un període de prova, o un cicle cobert íntegrament per crèdit) no emet factura; el primer cobrament real després del trial es factura amb normalitat. - Els prorrateigs standalone (un upgrade/downgrade cobrat pel seu compte, fora del cicle regular) no s'auto-facturen avui — van a revisió manual perquè decideixis. El cicle regular següent es factura com sempre.
- La decisió F1/F2 és la mateixa. El NIF del destinatari es llegeix dels
customer_tax_idsde la invoice (més la fitxa del client resolt); amb NIF el cicle és una factura ordinària (F1), sense ell i igual o per sota del llindar una simplificada (F2), i sense ell per sobre del llindar (o amb "exigir NIF" activat) va a revisió manual — idèntic a les regles de la secció de decisió. S'apliquen el mateix espejament de línies/IVA de Stripe Tax, la conversió a EUR i la validació de total.
Cada cicle és la seva pròpia factura
Un cicle de subscripció es converteix en una factura solta — no crea ni
toca cap factura recurrent de Factuarea. Les dues són independents: Stripe
porta la cadència i cada invoice.paid produeix una factura.
Evita la doble facturació. Si ja modeles la subscripció del mateix client com una factura recurrent manual a Factuarea, activar l'auto-facturació de subscripcions per a aquesta subscripció de Stripe produirà dues factures per període — una de la teva plantilla recurrent i una altra del cicle de Stripe. Tria una sola font per client: atura la factura recurrent manual o deixa aquest toggle desactivat per a aquestes subscripcions.
L'esdeveniment sortint
Una factura de cicle de subscripció emet un esdeveniment diferent,
invoice.subscription_auto_created
(a més de payment.received), de manera que un receptor de webhooks pot distingir
els cicles de subscripció dels cobraments únics. Un cobrament únic continua emetent
invoice.auto_created com abans. El llistat de cobraments auto-facturats
(Llistar cobraments auto-facturats)
exposa el context de subscripció (subscription_id, stripe_invoice_id,
period_start, period_end) per als cobraments de cicle (null per a cobraments
únics), i un filtre opcional origin (subscription/oneshot).
La idempotència és per cicle de facturació. Factuarea es basa en cada id
d'invoice de Stripe (in_xxx): un esdeveniment reenviat, o un segon esdeveniment
del mateix cicle, produeix com a màxim una factura. Els cicles històrics no
es facturen retroactivament — només es facturen els cicles cobrats després que
activis el toggle; els replays d'esdeveniments invoice.paid antics s'ignoren.
Per rebre els cicles de subscripció has d'habilitar l'esdeveniment
invoice.paid a l'endpoint de webhook de Connect al Dashboard de Stripe.
Com sempre, valida el flux primer amb una clau fact_test_: al
sandbox el registre d'Alta de VeriFactu es crea localment i
mai no es transmet a l'AEAT.
Valors per defecte d'un cop d'ull
| Camp | Per defecte | Efecte del valor per defecte |
|---|---|---|
enabled | false | Auto-facturació desactivada — no s'emet res fins que l'activis |
simplified_threshold_cents | 40000 (400 €) | Els cobraments sense NIF de fins a 400 € es converteixen en F2 |
require_nif | false | Es permeten factures simplificades; l'identificador fiscal s'ofereix però no s'exigeix |
refunds_enabled | true | Una devolució de Stripe genera una factura rectificativa automàtica (mentre l'auto-facturació està activada) |
subscription_autoinvoicing_enabled | false | Els cicles de subscripció de Stripe no s'auto-facturen fins que ho activis (requereix també enabled) |
Amb aquests valors per defecte, l'únic canvi de comportament un cop activada
l'auto-facturació és que un cobrament sense NIF de fins a 400 € es converteix en
factura simplificada en comptes d'esperar en revisió, i una devolució genera la
seva factura rectificativa automàticament. Els cobraments amb NIF es comporten
exactament igual que abans. Els cicles de subscripció queden desactivats fins que
optis per ells amb subscription_autoinvoicing_enabled.
Glossari
Termes fiscals i de domini espanyols usats a tota l'API de Factuarea — NIF, VeriFactu, AEAT, FacturaE, Modelo 303/347, sèries, rectificativa, huella, CSV i més.
Payouts i conciliació bancària
Com Factuarea ingereix els payouts de Stripe, els vincula amb els cobraments que agrupen, els concilia contra el teu extracte Norma 43 i emet l'esdeveniment payout.reconciled.