Stripe × n8n Payment Automation
Zero manual invoice follow-ups. Payment before access. Every time.
By the Numbers
The Problem
Running a digital product business means there's a critical moment between "customer agreed to pay" and "money in your account." I was handling it the wrong way: sending Google Drive resources first, then invoicing.
About 40% of clients who received resources upfront never paid. They had everything they needed — there was no incentive to complete the transaction. For the remaining 60%, invoices would sit in inboxes for days before I manually chased them.
Manual follow-ups were eating several hours a week. The process looked like this: create invoice → send → wait → DM on LinkedIn → send reminder email → wait again → awkwardly ask again. Repeat for every client. It was an honor-system payment model masquerading as a business.
System Architecture
Three independent n8n workflows, each triggered by a different Stripe event, working together to cover every payment scenario.
Workflow 1 — Instant Delivery
Stripe
invoice.payment_succeeded
n8n
Check metadata.drive_link
Resend
Send delivery email
Customer
Gets link in <5s
Workflow 2 — Smart Reminder (Event-Driven)
Stripe
invoice.finalized
Wait 30s
Let them pay
Check status
Still unpaid?
Resend + Twilio
Email + SMS
Workflow 3 — Daily Scheduled Chaser
Cron
Runs daily
Stripe API
Fetch open invoices
JS Filter
Has drive_link?
Resend + Twilio
Per invoice
The Metadata Strategy
Every Stripe invoice I create includes a single metadata field. This one field drives the entire automation — if it exists, the invoice is a digital product that needs instant delivery and follow-up.
{
"metadata": {
"drive_link": "https://drive.google.com/drive/folders/..."
}
}This means zero schema changes, zero database tables. Stripe's metadata fields carry the business logic. Workflow nodes check for this key before sending anything — preventing the automation from firing on subscription renewals or unrelated invoices.
How Each Workflow Works
Workflow 1: Instant Resource Delivery
Stripe fires invoice.payment_succeeded
Check for drive_link in metadata
drive_link exists, this is a digital product invoice. If not, the workflow exits silently.Send branded delivery email via Resend
Workflow 2: Smart Reminder
Stripe fires invoice.finalized
Double-wait pattern
Email + SMS reminder
Workflow 3: Scheduled Daily Chaser
Cron trigger fires daily
JavaScript node filters invoices
drive_link in metadata.Rate-limited loop
The Invoice Filter (JS Code Node)
Stripe's API returns a lot of noise. This JavaScript code node runs inside n8n and extracts only the invoices worth chasing.
const invoices = $input.first().json.data;
// Keep only: finalized, unpaid, with a drive_link attached
const filtered = invoices.filter(inv =>
inv.status === 'open' &&
inv.metadata?.drive_link &&
inv.amount_remaining > 0
);
return filtered.map(inv => ({
json: {
id: inv.id,
customer_email: inv.customer_email,
customer_phone: inv.customer_phone,
drive_link: inv.metadata.drive_link,
amount_due: (inv.amount_due / 100).toFixed(2),
hosted_invoice_url: inv.hosted_invoice_url,
}
}));Key Technical Decisions
Email Provider
→ Resend over SendGrid / Mailgun
Simpler API (single HTTP POST), better transactional deliverability, and a cleaner pricing model for the volume I was sending.
Automation Platform
→ n8n over Zapier / Make
No per-task operation limits means the daily cron can process hundreds of invoices at no extra cost. First-class JS nodes handle the filtering logic without paying for extra 'Code' steps.
SMS Fallback
→ Twilio for SMS
Email gets lost in spam. SMS has a 98% open rate. If a phone number exists in Stripe, the system sends a concise text with a direct payment link as a second channel.
Self-Hosting
→ Self-hosted n8n
Stripe API keys and customer emails never leave my own server. No SaaS middleman with access to financial data.
Results
Lessons Learned
Start with the instant win. Workflow 1 (instant delivery) took about 20 minutes to build and immediately improved the customer experience. The reminder and chaser workflows came after and compounded the effect.
Stripe's metadata is criminally underused. You can attach business logic to any invoice without a custom database. The single drive_link field made the whole system possible.
Test the edge cases. What if someone pays between the "check" and the "send reminder" step? What if the Drive link is malformed? Build in explicit checks — n8n makes this cheap with IF nodes and error branches.
Want to build something like this?
I'm available for new projects and collaborations.