Edge cases and limits

Every reason BeeL can drop a Stripe event, how to replay one, and the known limits of the integration.


When BeeL drops a Stripe event without producing an invoice, it records a typed skip reason on the event log so you can audit it. This page lists every scenario, how to clear it, and the operational levers (replay, manual override) when you need to recover.

Necesita atención — inbox of skipped events

BeeL doesn't drop Stripe events silently. Every inbound webhook is ingested into a typed inbox; if it can't be turned into an invoice, BeeL parks it with a typed skip reason instead of discarding it. The dashboard's "Necesita atención" panel surfaces the parked events you can actually act on — the rest stay in the audit log for visibility, but don't ask for action.

Two layers decide whether an event goes to the panel:

  1. Envelope-level acceptance checks — first-line defence on the envelope itself (environment, currency, amount sanity). These run before BeeL spends any work on the event and short-circuit on the first match.
  2. Downstream skip reasons — emitted later in the pipeline when configuration is missing, fiscal data is incomplete, or a user-defined filter rejects the event.

Only reasons that require user action show up in the panel. Noise (duplicate sibling events, unsupported event types, dedup hits) goes to the event log but stays out of the panel.

Envelope-level acceptance checks

These checks are evaluated in this exact order — first match wins, cheapest checks first.

CheckWhat it checksSkip reason
Livemode mismatchThe Stripe event's livemode flag doesn't match the connection's environment (sandbox vs live)LIVEMODE_MISMATCH
Unsupported currencyThe event currency isn't EUR (current single supported currency)UNSUPPORTED_CURRENCY
Amount zero or negativeThe payment_intent / charge / invoice / refund has amount ≤ 0AMOUNT_ZERO_OR_NEGATIVE

Other reasons that surface in "Necesita atención"

Beyond envelope-level acceptance, the following downstream reasons also land in the panel because the user has a concrete action to take:

Skip reasonTriggered when
CONNECTION_DISCONNECTEDThe Stripe connection has been deauthorised; events keep arriving but no processing happens
AMOUNT_REQUIRES_FISCAL_DATAThe charge is above the simplified threshold and the customer mapping lacks NIF / address
RECTIFICATIVA_OUT_OF_PERIODA refund/credit note targets an original outside the rectificative window
REFUND_ORIGINAL_NOT_FOUNDA refund arrived but BeeL can't find the original payment (often out-of-order delivery)
MISSING_DEFAULT_SERIESNo default series is configured for the resolved document type
FILTER_AMOUNT_REJECTED, FILTER_CUSTOMER_REJECTED, FILTER_DESCRIPTION_REJECTED, FILTER_CATEGORY_REJECTEDA filter rule you configured rejected the event — visible in the panel for review, but won't trigger an email

What to do, by reason

  • LIVEMODE_MISMATCH — someone hit your test webhook with a live event (or vice versa). Reconfigure the Stripe webhook endpoint so the right connection receives the right environment.
  • UNSUPPORTED_CURRENCY — BeeL is EUR-only today (see Scope and limitations). Switch the Stripe price to EUR, or route non-EUR charges through a separate Stripe account that doesn't feed BeeL.
  • AMOUNT_ZERO_OR_NEGATIVE — typically $0 authorisations confused with charges, internal vouchers, or full-refund chains. Review the original charge in Stripe; if it's legitimately zero, mark the parked event resolved.
  • AMOUNT_REQUIRES_FISCAL_DATA — the charge is above the simplified threshold but the buyer has no NIF / address to escalate to a standard (F1) invoice. Add the missing fiscal data to the buyer's record in Stripe (or contact support if you need to backfill existing parked events), then replay.
  • CONNECTION_DISCONNECTED — reconnect the integration from the dashboard, then replay any events that arrived while disconnected.
  • MISSING_DEFAULT_SERIES — set a default series for the resolved document type (standard / simplified / rectificative) and replay.
  • REFUND_ORIGINAL_NOT_FOUND — usually out-of-order delivery; BeeL retries on a backoff for ~6 hours. If it persists, the original was issued by a different connection or before BeeL was connected — handle the refund manually.
  • FILTER_* — the event matched a filter you configured. Either widen the filter and replay, or mark resolved if the rejection was intentional.

Replaying from "Necesita atención"

Once you've fixed the underlying cause (e.g. set a NIF on the customer, reconnected the integration, configured a default series) you can replay the parked event from the dashboard. The pipeline behaves exactly as if Stripe had just delivered the event — there's no need to ask Stripe to resend.

For reasons where replay would deterministically produce the same skip (AMOUNT_ZERO_OR_NEGATIVE, UNSUPPORTED_CURRENCY, CONNECTION_DISCONNECTED while still disconnected, AMOUNT_REQUIRES_FISCAL_DATA without first editing the mapping), the dashboard offers Mark resolved instead of Generate draft / Replay — same parking semantics, manual sign-off.

Where to find it. The panel lives in Dashboard → Stripe → Necesita atención. Each row links to the originating event in the event log and to the related customer mapping (when there is one) so you can fix and replay without leaving the page.

When BeeL skips an event

The reasons fall in three buckets — permanent (no invoice will ever come from this event), configuration (fix a setting and replay), and data (fix the source and replay).

Permanent — no action needed

ScenarioNotes
Event type not supportedBeeL only listens to a curated set — see Supported events
Sibling event has a canonical handlerSome Stripe events arrive in pairs (e.g. charge.succeeded + payment_intent.succeeded); BeeL uses the canonical one to avoid double-issue
Duplicate payment already invoicedWorking as intended — deduplication kicked in
Disputescharge.dispute.* is reserved for future support

Configuration — fix a setting and replay

ScenarioWhat to do
Stripe connection was deauthorizedReconnect the integration from the dashboard
Auto-invoicing is off on the connectionToggle on; replay events you want to backfill
No default series exists for the resolved document typeSet a default series for standard / simplified / rectificative
VeriFactu submission is disabledSee Auto-submit policy — the invoice is issued, just not submitted to AEAT

Data — fix the source and replay

ScenarioWhat to do
Payment amount ≤ 0 €No invoice for free or negative charges — investigate the Stripe charge
Currency ≠ EUREither bill in EUR or invoice manually outside the Stripe pipeline
Amount > simplified threshold and no NIF / addressCollect tax IDs in Stripe (Stripe Tax → Collect tax IDs) or lower the threshold
Refund / credit note with no matching original Beel invoiceWait for the original payment webhook (often out-of-order), or invoice manually
Refund amount > original payment amountInspect Stripe — usually a data anomaly
Refund on an already-voided invoiceChain is terminated — no further correctives
Webhook arrived for the wrong environment (live on test or vice versa)Verify the webhook endpoint configuration in Stripe

The exact verifactu_skip_reason or event-skip identifier exposed on the resource describes which scenario triggered. Use the dashboard event log to inspect the raw payload.

Inspecting skipped events

Every Stripe event lands in the log visible at Dashboard > Developers > Stripe events. Each row shows:

  • The Stripe event.id and type
  • The processing outcome (processed / skipped / failed)
  • The skip reason (when applicable)
  • The full raw payload (one click)

Most operational debugging starts here.

Replaying a Stripe event

When you need to reprocess an event (e.g. you fixed a configuration bug and want to backfill the invoices), you have two options.

Option 1 — From the dashboard

Open the event row, click Reprocess. The event flows through the pipeline as if it had just arrived.

Replay is only available from the dashboard today; the public API does not expose a programmatic replay endpoint. The dashboard-side button re-runs the same processing pipeline as the original event, producing an invoice (or a typed skip reason, same as the original path).

Replay always re-runs the handler. If the handler produces an invoice, you'll get a new invoice number (BeeL doesn't reuse old numbers). The original invoice — if it was created — must be cancelled separately to avoid duplicates.

Out-of-order delivery

Stripe doesn't guarantee event ordering. The most common ordering issue is a refund arriving before the original payment. BeeL handles this with a small retry budget: parked events are retried on a backoff for ~6 hours. After that they stay failed for manual handling.

If you see persistent "refund original not found", check whether the original was issued by a different connection or before BeeL was connected — in either case the refund needs manual handling.

Hard limits

LimitValueNotes
CurrencyEUR onlyMulti-currency support is a roadmap item
Connections per account10Soft cap; raise via support
Webhook timeout10 seconds per eventStandard Stripe timeout
Retry budget for transient failuresFollows Stripe's default scheduleUp to 3 days
Event log retention90 days for processed events; indefinite for parked eventsOlder entries are archived
Simplified threshold0 € – 3 000 €Default 400 €

Known limitations

ItemStatus
Disputes (charge.dispute.*)Not auto-handled; surfaced in the dashboard for manual processing
Multi-currency invoicesEUR only; payments in other currencies are skipped
Partial capturesTreated as the captured amount (BeeL doesn't see the authorisation total)
Subscription proration creditsTranslated to a credit note → corrective, same as any other credit note
Stripe Tax disabledBeeL falls back to your configured default IVA — invoice may not match what the customer expects

What about Stripe Connect Express vs Standard?

The integration treats both the same way. The differences are on Stripe's side (KYC flow, fee handling) — BeeL only sees the resulting events. The same processing rules, the same skip reasons.

When to write to support

Open a ticket at it@beel.es for:

  • Persistent processing errors on a specific event ID
  • Genuine total mismatches between Stripe and BeeL that aren't explained by refunds or inclusivity toggles
  • VeriFactu rejection codes you can't decipher (we'll cross-check with AEAT)

Include the Stripe event ID and the BeeL invoice number (if one was created).