# VeriFactu submission for Stripe invoices

Stripe-generated invoices follow the same VeriFactu rule as any other — decided by the NIF, not by the connection.

Stripe-generated invoices follow the same VeriFactu rule as any other invoice:
whether one reaches AEAT is decided by the **issuing NIF's** regime at issue
time, not by the connection that produced it. There is no Stripe-specific gate
and no per-connection switch. This page covers what is specific to Stripe; the
rule itself is in [Auto-submit policy](/verifactu/auto-submit).

## At a glance

| | |
|---|---|
| **What decides submission** | The issuing NIF's VeriFactu configuration — `enabled`, and `nif_status: ACTIVATED` |
| **Per-connection control** | None. A connection cannot opt its invoices in or out |
| **Submission state on the invoice** | Nested `verifactu` object — `verifactu.enabled` and `verifactu.submission_status` |

## There is no Stripe-specific gate

If the NIF that issues is under the regime, every invoice it issues is
registered — including the ones a Stripe charge produced. If it is not, none is.
Connecting a second Stripe account for a different revenue stream does not
change that: both accounts issue under the same NIF and land on the same side of
the axis.

An invoice from a NIF outside the regime is still **issued locally**, with
`verifactu.enabled: false` and no `submission_status`, no hash and no QR. To
find them over the API, list invoices with `?verifactu_enabled=false`; no value
of `verifactu_status` selects them, because they have no submission to describe.

<Callout type="info">
  **`skip_reason` is historical.** Stripe invoices issued while the connection
  carried its own switch can still show a `skip_reason` naming which one was off
  — `CONNECTION_DISABLED` was that switch. Nothing writes it any more, so on
  invoices issued today it is always `null`.
</Callout>

<Callout type="warn">
  **A sandbox Stripe account does not make a submission a test.** What decides
  the environment is the NIF you issue under, not the Stripe account that paid.
  Issue under a sandbox NIF for test traffic.
</Callout>

## How to read the result on an invoice

The VeriFactu state is exposed as a nested `verifactu` object on the Invoice response. For a submitted-and-accepted invoice it looks like this:

```json
{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "type": "STANDARD",
  "status": "ISSUED",
  "verifactu": {
    "enabled": true,
    "submission_status": "ACCEPTED",
    "invoice_hash": "3A5B7C9D1E2F3A4B5C6D7E8F9A0B1C2D3E4F5A6B7C8D9E0F1A2B3C4D5E6F7A8B",
    "registration_number": "094365f5-9637-40e9-851a-4e964a939b0b",
    "qr_url": "https://verifactu.agenciatributaria.gob.es/v?id=ABC123XYZ",
    "qr_base64": "iVBORw0KGgoAAAANSUhEUgAAAMgAAADI...",
    "registered_at": "2026-05-18T10:24:36Z"
  },
  "metadata": {
    "external_payment_id": "pi_3O...XYZ"
  }
}
```

For an invoice issued by a NIF outside the regime the object collapses to `{ "enabled": false }` and the AEAT-specific fields are absent. When AEAT rejects a submission, `verifactu.submission_status` is `REJECTED` and `verifactu.error_code` / `verifactu.error_message` carry the AEAT response. See [Submission states](/verifactu/submission-states) for the full state machine.

## What to do with invoices issued outside VeriFactu

The public API does **not** expose an endpoint to manually trigger a submission for an invoice that was issued with `verifactu.enabled = false`. Your options:

- **Fix it going forward.** Enable VeriFactu on the issuing NIF and every subsequent invoice it issues — Stripe-generated or not — is registered automatically. Already-issued invoices stay as they were: an issued invoice is a closed fiscal document.
- **Bulk backfill.** For a wave of historical invoices, write to [it@beel.es](mailto:it@beel.es) with the invoice IDs or date range.

To find affected invoices via the API, list with `verifactu_enabled=false` — see the [list invoices endpoint](/invoices/listCompanyInvoices).

## What happens on rejection

AEAT can still reject a Stripe-generated invoice — most commonly because of:

- **Recipient NIF not in census** — the customer's tax ID isn't registered. Pre-validate via [NIF validation](/nif-validation/validateNif), or accept the invoice will be issued as F2.
- **Chain integrity error** — internal; open a ticket.
- **Amount mismatch** — the invoice is built from the charge, so this should not happen; if you see it, the Stripe charge had a quirk worth investigating.

Handle the rejection like any other rejection — see [Cancel vs amend](/verifactu/cancel-and-fix).

## Related

<Related>

- [Auto-submit policy](/verifactu/auto-submit) — what decides submission, in full
- [Submission states](/verifactu/submission-states) — the lifecycle after submission
- [Edge cases and limits](/stripe/edge-cases-and-limits) — what to do when the submission keeps failing

</Related>

---

Full OpenAPI spec: https://docs.beel.es/api/openapi