Stripe to Google Sheets, deals close when invoices pay
Your pipeline looks “healthy”… until finance says three invoices were paid last week and nobody updated the CRM. Now your forecast is wrong, your follow-ups are awkward, and you’re stuck doing the same copy-paste routine again.
This is the kind of mess that hits sales ops first, but founders and account managers feel it too. A simple Stripe Sheets automation closes the loop so “paid” actually means “Closed” where your team works.
Below you’ll see exactly how the workflow syncs paid Stripe invoices into Google Sheets, what results you should expect, and the few setup details that keep it running clean.
How This Automation Works
The full n8n workflow, from trigger to final output:
n8n Workflow Template: Stripe to Google Sheets, deals close when invoices pay
flowchart LR
subgraph sg0["⏰ Daily Flow"]
direction LR
n0@{ icon: "mdi:play-circle", form: "rounded", label: "⏰ Daily Trigger", pos: "b", h: 48 }
n1@{ icon: "mdi:database", form: "rounded", label: "🔍 Find Customer in CRM Sheet", pos: "b", h: 48 }
n2["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/httprequest.dark.svg' width='40' height='40' /></div><br/>💳 Get Paid Invoices from Str.."]
n3@{ icon: "mdi:swap-vertical", form: "rounded", label: "📋 Split Invoice List", pos: "b", h: 48 }
n4["<div style='background:#f5f5f5;padding:10px;border-radius:8px;display:inline-block;border:1px solid #e0e0e0'><img src='https://flowpast.com/wp-content/uploads/n8n-workflow-icons/code.svg' width='40' height='40' /></div><br/>🧹 Clean Data & Mark as Closed"]
n5@{ icon: "mdi:database", form: "rounded", label: "✅ Update CRM Sheet with Clos..", pos: "b", h: 48 }
n0 --> n2
n3 --> n1
n1 --> n4
n4 --> n5
n2 --> n3
end
%% Styling
classDef trigger fill:#e8f5e9,stroke:#388e3c,stroke-width:2px
classDef ai fill:#e3f2fd,stroke:#1976d2,stroke-width:2px
classDef aiModel fill:#e8eaf6,stroke:#3f51b5,stroke-width:2px
classDef decision fill:#fff8e1,stroke:#f9a825,stroke-width:2px
classDef database fill:#fce4ec,stroke:#c2185b,stroke-width:2px
classDef api fill:#fff3e0,stroke:#e65100,stroke-width:2px
classDef code fill:#f3e5f5,stroke:#7b1fa2,stroke-width:2px
classDef disabled stroke-dasharray: 5 5,opacity: 0.5
class n0 trigger
class n1,n5 database
class n2 api
class n4 code
classDef customIcon fill:none,stroke:none
class n2,n4 customIcon
The Problem: Paid invoices don’t automatically close deals
Most teams have two sources of truth that drift apart: Stripe (what actually got paid) and a CRM tracker (what the team thinks happened). Someone has to notice a paid invoice, find the right row in Google Sheets, update the stage, and make sure they didn’t touch the wrong record. It sounds small. Then it’s 30 invoices later, the sheet has duplicates, and you’re debating which “[email protected]” is the real one. Meanwhile, your forecast meeting is in an hour.
The friction compounds. Here’s where it breaks down.
- Updating deals by hand turns into a daily admin chore that quietly eats about an hour a week for small teams.
- Email mismatches and duplicate rows create “Closed” updates on the wrong record, which is honestly worse than no update at all.
- Sales and finance end up working from different numbers, so follow-ups happen at the wrong time.
- Your pipeline stages stop reflecting revenue, which makes forecasting feel like guessing.
The Solution: Auto-close deals in Sheets when Stripe marks invoices paid
This workflow runs on a schedule you choose and checks Stripe for invoices that are already marked “paid.” For each paid invoice, it pulls the customer email, then searches your Google Sheets CRM tracker for the matching record. Once it finds the right row, it cleans things up by filtering empty rows and removing duplicates, then tags the deal with a “Closed” status (you can rename it to “Won” or whatever your pipeline uses). Finally, it updates the existing row in Google Sheets so your IDs and other CRM fields stay intact. The end result is simple: your sheet reflects real revenue without anyone touching it.
The workflow starts with a scheduled run in n8n, then calls Stripe’s API to fetch paid invoices. It processes each invoice one-by-one, matches by email in Google Sheets, and writes back a clean “Closed” update so the tracker stays consistent.
What You Get: Automation vs. Results
| What This Workflow Automates | Results You’ll Get |
|---|---|
|
|
Example: What This Looks Like
Say you process about 20 paid invoices a week. Manually, it’s usually 3 minutes to find the right row, 2 minutes to confirm it’s not a duplicate, then another minute to update status and notes, so around 2 hours weekly. With this workflow, the “work” is basically waiting for the scheduled run (daily or hourly) and glancing at the sheet afterward, maybe 5 minutes total. That’s time you can put into selling, onboarding, or fixing the pipeline instead of maintaining it.
What You’ll Need
- n8n instance (try n8n Cloud free)
- Self-hosting option if you prefer (Hostinger works well)
- Stripe for paid invoice data via API
- Google Sheets to store and update your CRM tracker
- Stripe API credentials (get them from Stripe Developers dashboard)
Skill level: Beginner. You’ll connect accounts, confirm your sheet columns, and run a test sync.
Don’t want to set this up yourself? Talk to an automation expert (free 15-minute consultation).
How It Works
A scheduled check runs automatically. You choose the frequency (daily is common, hourly if you want tighter reporting). When it triggers, n8n starts the sync without anyone logging in.
Stripe invoices are pulled from the API. The workflow uses an HTTP request to fetch invoices where the status is “paid,” then breaks the response into single invoice records so each customer can be matched properly.
Your CRM tracker is matched by email. For each invoice, n8n looks up the customer email in Google Sheets. This is the practical part: you keep your existing Deal IDs or CRM references, but the status changes automatically when payment is real.
Duplicates are removed and the row is updated. A small code step cleans out empty rows, filters duplicates, and sets the deal stage to “Closed” (or your preferred wording). Then the workflow writes back to Google Sheets so your team sees the update in the tracker they already use.
You can easily modify the “Closed” label to “Won,” “Paid,” or a custom stage based on your needs. See the full implementation guide below for customization options.
Step-by-Step Implementation Guide
Step 1: Configure the Scheduled Trigger
Set the workflow to start automatically on a daily schedule.
- Add the ⏰ Scheduled Daily Start node as your trigger.
- Confirm the trigger is configured to run on a daily interval (the node uses the built-in schedule rule).
- Connect ⏰ Scheduled Daily Start to 💳 Retrieve Paid Stripe Invoices to match the execution flow.
Step 2: Connect Stripe and Retrieve Paid Invoices
Pull only paid invoices from Stripe to drive CRM updates.
- Add the 💳 Retrieve Paid Stripe Invoices node.
- Set URL to
https://api.stripe.com/v1/invoices. - Enable Send Query and set Query Parameters → status to
paid. - Set Authentication to Predefined Credential Type and Credential Type to
stripeApi. - Credential Required: Connect your
stripeApicredentials in 💳 Retrieve Paid Stripe Invoices.
Step 3: Connect Google Sheets and Locate CRM Records
Find matching CRM rows by Stripe email in your Google Sheet.
- Add 📋 Expand Invoice Items and set Field To Split Out to
datawith Include set toallOtherFields. - Add 🔎 Locate Client in CRM Sheet and set Operation to
lookup. - Set Sheet ID to
[YOUR_ID]and Range toA:C. - Set Lookup Column to
Stripe Emailand Lookup Value to{{ $json.data.customer_email }}. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials in 🔎 Locate Client in CRM Sheet.
{{ $json.data.customer_email }} is blank in Stripe, the lookup will return no rows. Ensure invoices include customer email in Stripe.Step 4: Set Up Processing and Output Sync
Deduplicate matched clients, mark deals as Closed, and write results back to Google Sheets.
- Add 🧹 Deduplicate & Set Closed and paste the provided JavaScript to filter duplicates and set
DealtoClosed. - Add ✅ Sync Closed Deals to Sheet with Operation set to
appendOrUpdate. - Set Document ID to
[YOUR_ID]and Sheet Name toCRM. - Map columns using these expressions: Deal →
{{ $json.Deal }}, Stripe Email →{{ $json["Stripe Email"] }}, HubSpot Deal ID →{{ $json["HubSpot Deal ID"] }}, Pipedrive Deal ID →{{ $json["Pipedrive Deal ID"] }}. - Credential Required: Connect your
googleSheetsOAuth2Apicredentials in ✅ Sync Closed Deals to Sheet.
Stripe Email. Ensure this column exists and is spelled exactly the same in your CRM sheet.Step 5: Test and Activate Your Workflow
Verify the end-to-end flow before enabling daily automation.
- Click Execute Workflow to run ⏰ Scheduled Daily Start manually.
- Confirm 💳 Retrieve Paid Stripe Invoices returns invoice data with customer emails.
- Check that ✅ Sync Closed Deals to Sheet appends or updates rows with
Dealset toClosed. - When successful, toggle the workflow to Active to run daily in production.
Common Gotchas
- Stripe credentials can expire or need specific permissions. If things break, check your Stripe Developers API keys and n8n credential settings first.
- If you’re using Wait nodes or external rendering, processing times vary. Bump up the wait duration if downstream nodes fail on empty responses.
- Default prompts in AI nodes are generic. Add your brand voice early or you’ll be editing outputs forever.
Frequently Asked Questions
About 30 minutes if your Stripe and Google accounts are ready.
No. You’ll mostly connect Stripe and Google Sheets, then map a few fields. The included deduplication logic is already set up for you.
Yes. n8n has a free self-hosted option and a free trial on n8n Cloud. Cloud plans start at $20/month for higher volume. You’ll also need to factor in Stripe API usage, which is typically negligible for simple invoice lookups.
Two options: n8n Cloud (managed, easiest setup) or self-hosting on a VPS. For self-hosting, Hostinger VPS is affordable and handles n8n well. Self-hosting gives you unlimited executions but requires basic server management.
Yes, and it’s straightforward. You’ll change the status value in the “Deduplicate & Set Closed” code step so it writes “Won” (or your exact stage name) instead. Common customizations include updating a “Close Date” column, writing the Stripe invoice ID into the row for auditability, and switching the match logic from email to a customer ID column if your sheet uses one.
Usually it’s an expired or rotated API key in Stripe, so regenerate it and update the n8n credential. It can also be missing permissions on the Stripe account, or a typo in the request configuration if you adjusted the HTTP node. If it fails only sometimes, you may be hitting rate limits when pulling lots of invoices at once, so reduce frequency or add basic retry handling.
A typical small-business setup can handle hundreds of invoices per run, and self-hosted n8n has no execution limit beyond your server capacity.
Often, yes, if you care about clean matching and deduplication in one flow. n8n makes it easier to loop through invoice arrays, add a small data-cleaning code step, and keep logic readable without paying extra for every branch. Zapier or Make can still work for a basic “invoice paid → update row” if you have perfect data hygiene, but that’s a big “if.” With n8n you can also self-host for high volume without per-task pricing, which matters once you scale. Talk to an automation expert if you want help choosing the simplest option for your setup.
Your CRM tracker shouldn’t rely on someone remembering to do the “last little update.” Set this up once, and paid invoices will keep closing deals in Google Sheets automatically.
Need Help Setting This Up?
Our automation experts can build and customize this workflow for your specific needs. Free 15-minute consultation—no commitment required.