Stripe to Google Sheets Automation (2026): Make.com Setup & Webhooks
Updated: October 1, 2026Question: How do you automate Stripe to Google Sheets?
Quick Answer: Build a Stripe event → Make.com → Google Sheets workflow. For general successful payments, Stripe currently recommends handling payment_intent.succeeded; charge.succeeded is also useful when your ledger is specifically charge-based. Send only the event types you need, use the Stripe Event ID as your primary deduplication key, map the amount using the currency’s smallest-unit rules, and append the normalized record to Google Sheets.
Want the visual automation layer?
Make.com gives this workflow webhooks, routers, filters, data stores and Google Sheets actions in one scenario.
This link may be an affiliate link. CreatorOpsMatrix may earn a commission at no additional cost to you.
1. The Stripe → Google Sheets Setup That Actually Holds Up
A basic Stripe-to-Sheets integration is easy. The problem begins when the spreadsheet becomes the operating report for revenue, refunds, subscriptions or acquisition analysis.
A production-minded workflow has to answer five questions before it starts writing rows:
- Which Stripe event represents the business event you actually want to record?
- How will duplicate webhook deliveries be identified?
- How will money be converted correctly for every supported currency?
- How will refunds and failed payments be represented?
- How will you attach attribution or order metadata to the payment record?
That is the difference between a simple integration and a useful revenue data pipeline.
Recommended architecture: Stripe event → Make Custom Webhook → event-ID deduplication → normalization → Google Sheets Add a Row. Add routers for refunds, payment failures, subscription events or downstream attribution workflows when required.
2. Native Make Integration vs Custom Stripe Webhook
Make already provides a native Stripe and Google Sheets integration, including Stripe event triggers and a Google Sheets Add a Row action.
That means the question is not whether Make can connect Stripe to Google Sheets. It can. The more useful question is whether you need simple logging or greater control over event selection, deduplication and downstream routing.
Stripe module → Google Sheets
Use Make’s native Stripe module when the workflow is straightforward and you do not need custom webhook handling.
- Less configuration
- Native Stripe connection
- Native Google Sheets action
- Good for simple internal logging
Stripe Webhook → Make Custom Webhook
Use a custom webhook when the data model matters and you need explicit event selection, idempotency and branching.
- Explicit Stripe event control
- Event-ID deduplication
- Routers and filters
- Custom downstream API logic
For the architecture documented on this page, the second option is the stronger fit because it turns the Stripe event stream into a controlled data pipeline instead of a simple row logger.
3. Choose the Right Stripe Event First
This is one of the most important parts of the implementation. Stripe can emit multiple event types around the same payment lifecycle. If you subscribe to several success events and treat all of them as independent revenue rows, you can create duplicate business records even when Stripe has delivered everything correctly. Stripe explicitly notes that one action can generate multiple events.
| Stripe event | Use it for | Important note |
|---|---|---|
payment_intent.succeeded | General successful-payment workflow | Stripe recommends this event for post-payment business actions. |
charge.succeeded | Charge-oriented transaction logging | Useful when the ledger is intentionally based on Charge objects. |
invoice.payment_succeeded | Successful invoice payments | Useful for subscription and invoice-oriented workflows. |
payment_intent.payment_failed | Failed payment attempts | Useful when the sheet is also a payment-failure monitor. |
invoice.payment_failed | Failed invoice payment attempts | Useful for subscription billing failure reporting. |
charge.refunded | Charge refunds | Use when refunds need to enter the reporting workflow. |
Do not blindly subscribe to every success event. If you listen for both payment_intent.succeeded and charge.succeeded and append both as revenue rows, one payment can produce multiple records. Pick the business event that represents the row you want, or deliberately normalize multiple event types into one transaction model.
Stripe’s current documentation also recommends listening for asynchronous payment events instead of relying on a browser callback for critical post-payment actions.
4. The Architecture
Make’s Custom Webhook module creates a unique URL that third-party services can call. Make also supports incoming JSON, request headers, optional API-key authentication and webhook queues.
5. Step-by-Step Setup
Create the Google Sheet structure
Start with a simple header row. A useful transaction sheet can begin with:
| Column | Purpose |
|---|---|
| Event ID | Primary deduplication key from the Stripe Event. |
| Event Type | For example payment_intent.succeeded. |
| Payment ID | PaymentIntent, Charge or other relevant object ID. |
| Amount | Normalized monetary value for reporting. |
| Currency | Three-letter Stripe currency code. |
| Customer Email | Optional. Only store it when your workflow actually needs it. |
| Product / Description | Useful for revenue breakdowns. |
| Order ID | Your own internal order or transaction reference. |
| UTM Source | Optional acquisition attribution field. |
| Created At | Human-readable payment/event timestamp. |
Keeping the event ID in the sheet is useful even when you also use a Make Data Store. It gives you an audit trail when troubleshooting duplicate rows.
Create the Make.com webhook
In a new Make scenario, add Webhooks → Custom Webhook and create a new webhook URL.
Make’s Custom Webhook module supports JSON payloads and can also expose incoming request headers. Make recommends defining a data structure when you know what the sender will provide because it allows incoming data to be validated before later modules process it.
Useful security option: Make’s Custom Webhook module supports API-key authentication. That is useful when the sender can provide the required header. For Stripe’s own cryptographic signature verification, however, use an implementation that preserves Stripe’s raw request body and follows Stripe’s signature-verification requirements rather than assuming a basic webhook URL performs that verification automatically.
Create the Stripe event destination
Stripe currently manages webhook endpoints through Workbench. Create the webhook destination, choose the account scope and select only the event types the workflow actually needs. Stripe explicitly recommends avoiding unnecessary event subscriptions.
For a simple successful-payment ledger, select one primary success event instead of subscribing to multiple success events and counting each as a new sale.
Official Stripe webhook documentation:
Deduplicate before writing the row
This is where the original implementation needed the biggest upgrade.
Stripe can retry webhook deliveries, including automatic retries that continue for up to three days in live mode. Stripe recommends logging processed Event IDs and not processing the same Event ID twice.
Build this logic in Make:
- Read the incoming Stripe Event ID.
- Check a Make Data Store using that ID as the key.
- If the record already exists, stop the route.
- If it does not exist, continue processing.
- Write the Event ID to the Data Store before or as part of your controlled processing flow.
- Only then append the transaction to Google Sheets.
Make Data Stores are designed to hold records between scenario runs, and the platform provides a dedicated Check the Existence of a Record module.
Incoming Stripe Event
↓
Event ID = evt_XXXXXXXX
↓
Make Data Store
↓
Already exists?
┌──────┴──────┐
YES NO
↓ ↓
STOP Store Event ID
↓
Normalize data
↓
Google SheetsStripe also notes that in some cases two separate Event objects can represent duplicate delivery semantics. In those cases, Stripe recommends using the underlying object ID together with the event type as an additional duplicate-detection signal.
Normalize the payment data correctly
Do not treat every Stripe amount as “cents divided by 100.” Stripe represents monetary values in the currency’s smallest unit, and Stripe explicitly documents zero-decimal currencies.
For example, 9700 represents $97.00 in a two-decimal currency such as USD. A universal division-by-100 formula across all currencies is not safe.
Also do not label amount_captured as “net after Stripe fees.” Stripe defines that field as the amount captured, which can be lower than the original amount after partial capture.
| Stripe field | Correct interpretation | Sheet column |
|---|---|---|
id | Unique Event ID when taken from the Event envelope. | Event ID |
type | Event type such as payment_intent.succeeded. | Event Type |
data.object.id | ID of the underlying Stripe object. | Payment ID |
data.object.amount | Amount intended to be collected, in the currency’s smallest unit. | Gross Amount |
data.object.amount_received | PaymentIntent amount actually received. | Amount Received |
data.object.amount_captured | Charge amount actually captured. | Amount Captured |
data.object.currency | Lowercase ISO currency code. | Currency |
data.object.created | Unix timestamp in seconds. | Created At |
data.object.receipt_email | Email used for the receipt when present. | Customer Email |
Important: “Amount captured” and “net revenue after Stripe fees” are different concepts. If you need actual fee-adjusted accounting data, use the appropriate Stripe balance/transaction information rather than pretending the Charge amount field already contains your net proceeds.
Map the data to Google Sheets
Add the Google Sheets module and choose Add a Row. Make’s current module documentation describes Add a Row as appending a new row to the bottom of the table.
Map the normalized values into the columns you created earlier. Keep the Event ID and Event Type in the sheet even if your Data Store already handles deduplication.
For operational reporting, a useful minimum row looks like this:
Event ID → evt_XXXXXXXX Event Type → payment_intent.succeeded Payment ID → pi_XXXXXXXX Amount → normalized payment amount Currency → usd Order ID → your-order-id Product → your-product UTM Source → paid-search Created At → formatted timestamp
Test with controlled events
Do not immediately activate the workflow on live revenue and assume it is correct.
Run controlled test events and verify:
Stripe recommends testing webhook handlers before going live, and Stripe provides both Dashboard and CLI methods for test events.
6. Add Attribution Without Turning Google Sheets Into a Mess
A Stripe-to-Sheets workflow becomes substantially more useful when the payment record contains the same identifiers used by your acquisition system.
Stripe supports metadata on objects including Charge, PaymentIntent, Customer, Refund and Subscription. Metadata is intended for structured key-value information associated with the object.
That means you can design a transaction record around fields such as:
order_idproduct_idutm_sourceutm_campaignlanding_pagecustomer_segmentcreator_id
The key idea is to attach the identifier before payment, then carry it into your Stripe object and ultimately into Google Sheets. This is much more reliable than trying to infer acquisition data later from the customer email address.
Attribution rule: Store identifiers, not assumptions. A UTM value, order ID or campaign identifier that originated in your own system is much easier to reconcile than attempting to reconstruct attribution from unrelated logs after the payment has already occurred.
7. Refunds, Failed Payments and Subscription Events
A successful-payment row is only one part of a financial reporting system. Stripe provides separate event types for failed payments, refunds and invoice payments.
A better Make scenario uses a Router after the webhook:
| Route | Event | Suggested Sheet action |
|---|---|---|
| Successful payment | payment_intent.succeeded | Add transaction row |
| Refund | charge.refunded or refund-specific events | Add refund row or update transaction state |
| Payment failure | payment_intent.payment_failed | Log failure event |
| Invoice payment | invoice.payment_succeeded | Log invoice/subscription payment |
| Invoice failure | invoice.payment_failed | Log billing failure |
That structure is more useful than a single “sales” sheet because the reporting layer can distinguish money coming in from money being refunded or payment attempts failing.
8. Duplicate Webhooks: The Correct Fix
Stripe explicitly states that webhook endpoints can occasionally receive the same event more than once. It recommends recording processed Event IDs and not reprocessing an already handled ID.
The critical mistake is using the timestamp as your duplicate key. Stripe also states that events are not guaranteed to arrive in the order they were generated and advises using event IDs rather than created timestamps to identify duplicates.
GOOD: Event ID = evt_12345 → Data Store key → Already exists? → Stop / Process WEAK: Created timestamp = 1720000000 → Assume duplicate? → Process WRONG: Charge amount + email → Guess whether the event is duplicate
Make instant webhooks are processed in parallel by default, so two incoming executions can overlap. If your workflow genuinely needs ordered processing, Make provides a “Process data in order” setting.
9. Google Sheets Scaling: Know the Real Constraint
Google Sheets is excellent as an accessible reporting layer, but it is still an API-backed destination with quotas.
Google currently documents:
- 300 write requests per minute per project
- 60 write requests per minute per user per project
Google also notes that requests can be sent concurrently within those limits and that batch requests count as one API request toward the quota.
Scaling implication: do not design around “sleep one second before every write” as your primary capacity strategy. For bursts, consider batching records, reducing unnecessary writes, or moving high-volume transactional storage to a database while keeping Sheets as the reporting/export layer.
Make currently provides both an Add a Row module and a Bulk Add Rows module for Google Sheets.
10. Make.com Credits and the Cost of This Workflow
Make currently lists the following plans:
| Plan | Current listed allowance | Relevant point |
|---|---|---|
| Free | Up to 1,000 credits/month | Good for learning and lighter workflows. |
| Core | $12/month for 10,000 credits | Scheduled scenarios can run down to the minute. |
| Pro | $21/month for 10,000 credits | Adds priority execution, custom variables and execution-log features. |
| Teams | $38/month for 10,000 credits | Adds team roles and scenario-sharing features. |
Make defines an operation as a module run, with the number of operations depending on how many bundles the module processes. That means you should not promise a universal “one Stripe sale equals exactly X operations” figure for every scenario.
For a simple one-event workflow, your consumption depends on the modules actually executed and the number of bundles that reach each module.
Check current Make.com pricing →
11. When Google Sheets Stops Being the Right Database
Google Sheets is useful because operators can inspect it, filter it and build formulas without learning SQL. That does not make it the ideal long-term transactional database.
A practical progression is:
Google Sheets
Best when the goal is visibility, simple reporting and operator-friendly inspection.
- Fast to understand
- Easy formulas
- Easy sharing
Database / warehouse
Better when transaction volume, relational reporting or concurrent writes become the main concern.
- Structured joins
- Indexed queries
- Better long-term data architecture
The useful architecture is often not “replace Sheets completely.” It can be “store transactions in a proper system of record and use Sheets as a controlled reporting surface.”
12. Why Make.com Fits This Workflow
The value of Make here is not simply that it can connect two applications. Make currently provides webhooks, routers, filters, Data Stores and Google Sheets modules in the same visual workflow environment.
That makes it useful when your Stripe workflow grows from:
Stripe → Sheet
into:
Stripe ↓ Make Webhook ↓ Validate event ↓ Deduplicate ↓ Router ├── Successful payment → Sheets ├── Refund → Refund log ├── Failed payment → Failure log ├── Subscription event → CRM └── Attribution event → Ad platform ↓ Monitoring / reporting
That is the point where a visual automation platform becomes much more valuable than a simple one-trigger, one-action integration.
Build the Stripe workflow in Make.com
Make provides the webhook, routing, data-store and Google Sheets modules needed for the architecture on this page.
Start with Make.com →Affiliate disclosure: this may be an affiliate link. CreatorOpsMatrix may earn a commission if you sign up or purchase through it.
13. Common Failure Modes
| Problem | Likely cause | Fix |
|---|---|---|
| Two rows for one payment | Repeated event or multiple event types treated as separate revenue rows | Deduplicate by Event ID and define one canonical revenue event. |
| Rows arrive out of order | Webhook processing is not guaranteed to follow creation order | Use event IDs and object relationships rather than timestamp order. |
| Amount is 100× too large | Currency conversion logic assumes every currency has 100 subunits | Normalize according to the actual Stripe currency. |
| “Net revenue” is incorrect | Captured amount is being mistaken for fee-adjusted proceeds | Use the appropriate Stripe balance/transaction data for fee calculations. |
| Refunds don’t appear | Only success events are subscribed to | Add the relevant refund events and define how the sheet should represent them. |
| Rows stop during a traffic spike | Destination/API limits or downstream execution pressure | Reduce unnecessary writes, batch where practical and design for retries. |
| Webhook security is unclear | Endpoint is treated as authenticated simply because the URL is secret | Use available webhook authentication and follow Stripe’s signature verification requirements when cryptographic verification is required. |
14. FAQ — Stripe to Google Sheets Automation
Can Stripe send data directly to Google Sheets?
Stripe can send event data to a webhook endpoint, but Google Sheets is not itself the normal Stripe webhook destination. A common architecture is Stripe → webhook or automation platform → Google Sheets. Make provides both Stripe and Google Sheets modules for this workflow.
Should I use payment_intent.succeeded or charge.succeeded?
For a general successful-payment workflow, Stripe currently recommends handling payment_intent.succeeded for post-payment business actions. charge.succeeded is appropriate when your reporting model is intentionally charge-based. Choose one canonical event for your revenue rows unless you have explicit normalization logic for multiple event types.
How do I stop Stripe webhook duplicates in Google Sheets?
Store the Stripe Event ID and check it before writing the row. Stripe explicitly recommends tracking processed Event IDs and not reprocessing an event that has already been handled.
Why should I not divide every Stripe amount by 100?
Stripe represents money in the smallest currency unit, but not every currency uses 100 subunits per major unit. A universal divide-by-100 rule is therefore unsafe across currencies.
Does amount_captured mean my net Stripe revenue?
No. amount_captured represents the amount actually captured for a Charge and may be lower than the original amount after a partial capture. It is not a substitute for fee-adjusted net proceeds.
Can I capture refunds and failed payments too?
Yes. Stripe exposes separate event types for refunds and payment failures. Add those events to the same webhook architecture and route them into dedicated rows, status fields or separate reporting tabs according to your data model.
Does Make process webhook requests instantly?
Make describes webhooks as instant triggers. By default, instant webhook executions are processed in parallel, while ordered processing can be enabled when a workflow requires it.
Is Make free for Stripe to Google Sheets automation?
Make currently lists a Free plan with up to 1,000 credits per month. Paid plans increase the available credit allowance and add additional scheduling and execution capabilities. Actual credit use depends on the modules and bundles processed by your scenario.
When should I stop using Google Sheets as the transaction store?
Move the transactional system of record to a database or warehouse when the workflow requires higher write volume, relational queries, large-scale historical data or stronger database guarantees. Sheets can remain useful as a reporting surface.