All projects
Automation

Stripe payments to invoices

Seven n8n workflows turn Stripe payments into German invoices (email with PDF) and a Telegram message. No double invoice, no lost event.

Live demo coming soonGitHubDocumentation

Problem

Stripe delivers payment events by webhook, sometimes more than once, and expects a quick answer. A webhook that acknowledges an event before storing it loses that event when the database is down. Processing the same event twice creates duplicate invoices and messages. And failures go unnoticed when nobody is alerted.

Solution

Intake checks the Stripe signature (HMAC-SHA256) and rejects timestamps older than 5 minutes. It answers only after the event is stored; if the insert fails it answers 500, so Stripe retries.

Every minute a Processor claims up to 10 events atomically (FOR UPDATE SKIP LOCKED). Each paid event gets exactly one invoice, enforced by UNIQUE constraints in PostgreSQL. The email, the PDF and the Telegram message are built from the stored invoice row only, so every retry produces the same document.

A Monitor workflow reports dead or stuck events by Telegram and email; a failed event can be replayed with a reason and an audit row. An outside heartbeat reports when the system has been silent for about 15 minutes.

Architecture

Flow diagram: Stripe sends to Intake, which verifies the signature and stores in stripe_events (400 on a bad signature, 200 when stored or duplicate, 500 when the insert fails). Every minute the Processor creates the invoice, which is rendered into an email with PDF and a Telegram message.

Results

54

end-to-end checks in one script, run after every change

Evidence
384

cases checked on the real Processor graph

Evidence
1

invoice, email and Telegram message per payment, even when Stripe resends the event

Evidence
7

n8n workflows, versioned as TypeScript source files

Evidence

Tech stack

  • n8n
  • PostgreSQL
  • TypeScript (n8n Workflow SDK)
  • Docker Compose (WSL)
  • Gotenberg
  • Mailpit
  • Telegram Bot API
  • Healthchecks.io
  • Stripe
  • PowerShell

Screenshots

The invoice email for a demo payment, with the PDF attached (Mailpit, the local inbox).
The invoice email for a demo payment, with the PDF attached (Mailpit, the local inbox).
The attached PDF: a fictional shop, 30,00 EUR split into net and 19 % VAT, marked as paid, with the demo disclaimer in the footer.
The attached PDF: a fictional shop, 30,00 EUR split into net and 19 % VAT, marked as paid, with the demo disclaimer in the footer.
The owner's Telegram chat after a demo payment: the message with the customer, payment method and invoice number, then the PDF as a document.
The owner's Telegram chat after a demo payment: the message with the customer, payment method and invoice number, then the PDF as a document.

Runs only in Stripe's sandbox on my own machine. The invoices are a technical demo and do not claim compliance with German invoicing rules (§ 14 UStG, GoBD). The repository cannot be cloned and run yet; that is the next step.