NewStripe: a buyer with a NIF always gets a standard invoice, and the simplified threshold is deprecated
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog

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.

At a glance

What decides submissionThe issuing NIF's VeriFactu configuration — enabled, and nif_status: ACTIVATED
Per-connection controlNone. A connection cannot opt its invoices in or out
Submission state on the invoiceNested 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.

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.

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.

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:

{
  "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 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 with the invoice IDs or date range.

To find affected invoices via the API, list with verifactu_enabled=false — see the list invoices endpoint.

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, 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.