NewProvince is only required for addresses in Spain
BeeL
Get startedMulti-NIFVeriFactuRulesStripeAPI referenceChangelog
n8n

Recipes

Workflows worth building, including the one that closes a gap nothing else covers.


From a form to an issued invoice

The shape most people want first: someone fills in a form and receives an invoice.

Form (NIF, name, email, concept, amount)
  └─▶ store the raw request
       └─▶ NIF → Validate            ← real AEAT lookup
            ├─ invalid ─▶ end: "that NIF does not exist"
            └─ valid
                 └─▶ Customer → Get Many (filter by NIF)
                      ├─ found ─────────────┐
                      └─ not found ─▶ Create┴─▶ Merge
                           └─▶ Company → Issuing Readiness
                                ├─ not ready ─▶ end: says what is missing
                                └─ ready ─▶ Invoice → Create
                                              (issue_directly + send_automatically)

Three details carry this workflow:

Validate the NIF first. It is one node and a real lookup against the AEAT registry — an invented NIF is rejected before anything is created.

Ask before you issue. Issuing Readiness answers whether the company can issue right now and what is missing if not, instead of you attempting it and reading an error.

Derive the idempotency key from the submission. Two clicks on the button, or a re-run, then return the invoice that already exists rather than issuing a second one.

Store the raw form response before anything else. If a later step fails, what the customer asked for is not lost.


Sweep the charges that never became invoices

This one closes a gap nothing else covers.

The native Stripe connection invoices every charge automatically. Sometimes that fails — a missing default series, for instance. When it does, no webhook is emitted: there is no event for a payment that failed to invoice. A charge that took money without producing an invoice is only visible by asking for it: a payment with no invoice that nobody notices. It is exactly the sort of boring hourly job you do not want depending on someone remembering.

Build this one with the HTTP Request node

In the current release of the node (0.2.2), the Payment Event operations and Payment Connection → Disconnect still address a connection by its provider, a route shape the API no longer serves, so they fail. Until a release fixes them, call the API from an HTTP Request node with a header credential Authorization: Bearer <your API key>. Each connection has its own ID, which Payment Connection → Get Many returns.

Schedule (hourly)
  └─▶ Payment Connection → Get Many          ← gives each connection's id
       └─▶ HTTP Request: GET /v1/companies/{company_id}/payment-connections/{connection_id}/events
           ?needs_action=true                ← only the events still worth acting on
            ├─ retry_available ─▶ HTTP Request: POST …/events/{event_id}/retry
            └─ draft_available ─▶ HTTP Request: POST …/events/{event_id}/draft + notify

Each event carries failure_category and failure_reason, plus retry_available and draft_available telling you which recovery it accepts: retry when the cause was transient, draft when a human should look before issuing. The full request and response are in List payment events.


Watch for recurring invoices that stopped

Two nodes, and it prevents a quiet revenue leak.

BeeL Trigger (recurring_invoice.paused) ─▶ notify the team

BeeL. pauses a recurring invoice on its own after repeated generation failures or a downgrade. If nobody watches that event, a monthly invoice silently stops being issued and you find out at the end of the quarter. To resume it once fixed: Recurring Invoice → Set Status → ACTIVE.


Alert on VeriFactu rejections

BeeL Trigger (verifactu.status.updated) ─▶ if REJECTED ─▶ alert

Issuing is not the same as complying. The invoice gets its number immediately, but the AEAT answers afterwards. Most integrations stop at "issued" and never learn that a submission was rejected.

Pair it with a daily sweep as a belt-and-braces: Invoice → Get Many filtered by verifactu_status = REJECTED catches anything whose webhook delivery was lost.


Events the trigger does not offer

The BeeL Trigger lists eight events. The API sends two more that the trigger does not offer in version 0.2.2:

  • invoice.pdf.generated — the PDF of an invoice is ready.
  • invoice.schedule_failed — a scheduled invoice could not be generated on its date.

To start a workflow on either one, use n8n's generic Webhook node and subscribe to it yourself:

  1. Add a Webhook node (method POST) and turn on its Raw Body option. The signature is computed over the exact bytes BeeL. sent.
  2. Create the subscription with an HTTP Request node or any client: POST /v1/accounts/{account_id}/webhooks with the Webhook node's production URL and the events you want. See Create a webhook subscription. The response carries the signing secret, and only this once: store it in an n8n credential.
  3. Verify the BeeL-Signature header before doing anything with the payload: an HMAC-SHA256 of t, a . and the raw body, with that secret, plus the 5-minute timestamp check. The steps are in Signatures. Stop the workflow when it does not match.

The BeeL Trigger does all three for you, which is why it is the better choice for the events it lists.