Send Stripe Payments to Google Sheets
A live payment log your finance team can filter, without exporting a CSV every Monday.
Quick Answer
Create a free webhook URL at requex.me, add it in Stripe under Developers → Webhooks with the events you care about, then connect Google in Settings → Connectors and map columns to fields like {{body.data.object.amount}}. Every event Stripe sends becomes a row. Setup takes about five minutes and costs nothing.
Stripe's dashboard is excellent at answering “what happened to this one payment”. It is far less good at “show me every refund this quarter next to the customer's plan, sorted by amount”. That question belongs in a spreadsheet, which is why so many teams end up exporting a CSV on a schedule someone eventually forgets to run.
A webhook removes the schedule. Stripe pushes each event as it happens, and the row appears.
Step 1: Get a webhook URL
Open requex.me. A URL like https://api.requex.me/hook/ab12cd34 is ready immediately. Sign in so the webhook is saved to your account — connectors need an owner.
Step 2: Register it in Stripe
In the Stripe Dashboard go to Developers → Webhooks → Add endpoint, paste the URL, and select the events you want logged. A useful starting set:
charge.succeeded— money incharge.refunded— money back outcharge.failed— the ones worth chasingcustomer.subscription.createdand.deleted— churn either way
Use Send test webhook before going further. The payload appears in Requex instantly, and you need to see its exact shape to write the field map — guessing at Stripe's nesting is how people end up with a column full of blanks.
Step 3: Map the fields
Every Stripe event wraps the interesting part in data.object, so paths are a little deeper than you might expect:
Received at → {{timestamp}}
Event → {{body.type}}
Customer → {{body.data.object.billing_details.email}}
Amount → {{body.data.object.amount}}
Currency → {{body.data.object.currency}}
Status → {{body.data.object.status}}
Charge ID → {{body.data.object.id}}Amounts arrive in the smallest currency unit — 4900 means £49.00. Rather than fight that in the template, log the integer and divide in the sheet: =D2/100 in a neighbouring column. Sheets is better at arithmetic than a field map is, and the raw value stays auditable.
Step 4: Verify the signature
Anyone who learns your webhook URL can post to it, and a payment log full of forged rows is worse than no log. Stripe signs every request with a Stripe-Signature header. In Settings → Auth, choose HMAC, paste the signing secret from the Stripe endpoint page (it starts whsec_), and set the header name. Unsigned requests are then rejected before they ever reach your sheet.
Related reading: webhook security practices and testing Stripe webhooks.
What the finished sheet is good for
- A pivot table of revenue by day, plan, or country without touching the API
- Conditional formatting that flags refunds over a threshold
- A shared tab finance can read without a Stripe seat
- Cross-referencing charges against your own user table with
VLOOKUP
Things that bite
Stripe retries. A delivery that fails is retried for up to three days, so a row can appear twice. Log {{body.id}} — the event id, which is stable across retries — and deduplicate on it in the sheet.
Test mode and live mode are separate. Endpoints registered in test mode only receive test events. Register the URL twice, or use two webhooks and two tabs, so test charges never pollute the real revenue log.
Volume. Sheets and the Sheets API are comfortable into the low thousands of rows a day. Past that, log to a database and roll up into Sheets on a schedule.
Related
Start Testing Webhooks Now
Generate your unique URL and test webhooks instantly. Free, no signup.
Open Webhook Tester →