The moment it happens
Log every Stripe cancellation and its reason in a sheet
Each cancelled subscription is added to your churn sheet with the customer, plan, revenue lost and the reason they gave.
- Runs
- The moment it happens
- Apps
- Google Sheets, Stripe
- AI
- Not needed
- Access
- Stripe read; sheet editor
Send this to your assistant
Create a ClickRuntime automation: when a Stripe subscription is cancelled, add the customer, plan, monthly revenue lost and their cancellation feedback to my churn sheet.
First time? Adding ClickRuntime to your assistant takes about two minutes.
Why use it
Why teams use this automation
A product manager wants to know why customers leave. Stripe's cancellation flow asks them, but the answers sit inside individual subscription records, so looking at them means clicking through dozens of customers one by one. The churn conversation in planning meetings ends up resting on a handful of remembered complaints.
This automation copies every cancellation into a Google Sheet the moment it happens: who, which plan, how much monthly revenue went with them, the reason they picked and any comment they wrote. After a month the sheet shows patterns that no-one could see before, and it can be filtered, charted and shared with the whole team.
What you get out of it
All churn in one place
Every cancellation is a row, instead of being spread across separate Stripe records.
Revenue lost is visible
Each row includes the monthly amount, so you can see which reasons cost the most.
Customers' own words
Free-text comments are kept alongside the reason, which is often where the useful detail is.
Easy to share
Anyone with access to the sheet can filter, chart and discuss it, with no Stripe login needed.
Recorded as it happens
Rows are added within seconds of the cancellation, so the log is always current.
How it works
What happens, step by step
When a subscription ends, Stripe tells ClickRuntime straight away, and the message is checked to be genuinely from Stripe.
It reads the plan, the price and any reason or comment the customer gave.
It looks up the customer's name and email in Stripe.
A row with the date, customer, plan, monthly revenue lost and reason is added to your churn sheet.
Before it runs live
- Connect your Google Sheets account and pick the spreadsheets it may use
- Connect Stripe
- Paste your automation's link into the other app's webhook settings
What you get
Build your own
Need it to work differently?
Your own rules
Conditions, thresholds, filters and exceptions, written the way you'd explain them to a colleague.
Any number of apps
One automation can read from one app and update several others. Over 248 apps are ready, and anything with an API works too.
AI where it helps
Summaries, classification, extraction and drafts use ClickRuntime's built-in AI, with no extra key.
On a schedule or on each event
Runs as often as every 5 minutes, or the moment an app sends an event, and keeps track of what it already handled.
Changes you can ask for
- Act only on the items that match your own rules, and skip the rest
- Add an AI step, for example to summarize, sort or draft a reply
- Add another app, for example also send it to Slack
- Combine it with other Google Sheets and Stripe steps into one automation
Under the hood
The code that runs this automation
from google.oauth2.credentials import Credentials
from googleapiclient.discovery import build
import stripe
from clickruntime import on_event, credentials, verify
SHEET_ID = "your-sheet-id"
@on_event
def handle(event):
if not verify.stripe(event.body, event.header("Stripe-Signature"), credentials.secret("STRIPE_WEBHOOK_SECRET")):
return {"ignored": "bad signature"}
sub = event.json["data"]["object"]
stripe.api_key = credentials.secret("STRIPE_API_KEY")
customer = stripe.Customer.retrieve(sub["customer"])
item = sub["items"]["data"][0]
price = item["price"]
monthly = price["unit_amount"] * item.get("quantity", 1) / 100 / (12 if price["recurring"]["interval"] == "year" else 1)
details = sub.get("cancellation_details") or {}
sheets = build("sheets", "v4", credentials=Credentials(credentials.connection("google", "work")), cache_discovery=False).spreadsheets()
sheets.values().append(spreadsheetId=SHEET_ID, range="Churn!A:G", valueInputOption="USER_ENTERED", body={"values": [[
event.received_at[:10], customer.name or "", customer.email, price.get("nickname") or price["id"], round(monthly, 2),
details.get("feedback") or "no reason given", details.get("comment") or ""]]}).execute()
return {"logged": sub["id"]}FAQ
Common questions
Where does the reason come from?
How is monthly revenue lost worked out?
Does it include cancellations I make myself in Stripe?
What permissions does it need?
Does it need AI?
How many runs does it use?
Can I change how it works?
Related
You might also like
Log Stripe sales in a sheet and send buyers their product
Every payment becomes a row in your sales sheet, and the buyer gets the download link you keep in that sheet.
See how it worksLog failed Stripe payments to Google Sheets
Every failed Stripe payment is added to a Failed payments tab with the customer's email, amount, decline reason and a link to the payment.
See how it worksLog Stripe payments to Google Sheets
Every successful Stripe payment is added as a new row in a Google Sheet within seconds.
See how it worksKeep exploring
Set up “Log every Stripe cancellation and its reason in a sheet” from your assistant
Copy the prompt above, or connect your assistant first. Free plan, no credit card.