Catch at-risk Ghost members the moment Stripe flags trouble
When a Ghost member's payment fails or they cancel, label them in Ghost and post a retention brief to Slack so you can win them back before they leave.
Build me an agent workflow that catches paid Ghost members the moment Stripe flags trouble, so I can intervene before they're gone.
Trigger: a Stripe webhook for the events invoice.payment_failed and customer.subscription.deleted. The same workflow should handle both event types.
For each incoming event:
1. If the Stripe event has livemode: false (i.e. test mode), stop and do nothing. We do not want test events polluting the retention channel.
2. Pull the customer id from the event (it lives at data.object.customer for invoice.payment_failed and data.object.customer for customer.subscription.deleted). Use Stripe's Retrieve Customer operation to fetch the customer's email, name, and any metadata or balance info that can stand in for lifetime value (e.g. total_spend metadata if present, otherwise the customer's balance or the invoice amount).
3. Use Ghost's Browse Members (Admin API) operation with the NQL filter email:"<that email>" to find the matching Ghost member. Capture their name, id, current labels, subscription tier (the plan or product name from the member's subscriptions array), and, if available on the member record, the URL of the most recently opened post.
4. Use Ghost's Update Member (Admin API) operation to add a label to that member. Use "at-risk" if the event was invoice.payment_failed, and "churned" if the event was customer.subscription.deleted. Preserve the member's existing labels rather than overwriting them.
5. Compose and send a Slack message via Send a Message to the channel #retention. Keep it short and skimmable. Include: the member's name and email, their tier, their lifetime value (or best available proxy from Stripe), the event reason in plain English ("payment failed on $X invoice" vs "subscription canceled"), the URL of the most recent Ghost post they opened if visible on the member record, and a one-sentence suggested next step (for example: "Send a 20% win-back offer" for a small failed payment, "Manual outreach worth it" for a high-LTV cancellation). The agent should pick the suggestion based on lifetime value and event type.
Edge cases:
- If no matching Ghost member is found for that email, skip the Update Member step but still post to Slack with whatever Stripe details we have, and note in the message that the member could not be located in Ghost. - If the same member triggers multiple events in quick succession (e.g. a payment_failed followed by a subscription_deleted), it's fine to post both messages, but make sure the labels in Ghost are additive, not overwritten. - Never include raw Stripe ids or JSON in the Slack message. Write it like a person would: short paragraph or 4-5 bullet lines.
Additional information
What does this prompt do?
- Listens for Stripe billing trouble in real time, including failed invoice payments and canceled subscriptions, so you hear about churn risk the same minute Stripe does.
- Finds the matching member in Ghost by email and quietly tags them as at-risk or churned, keeping your internal segments and win-back lists honest without manual cleanup.
- Posts a short, human-readable brief to your retention channel in Slack with the member's name, tier, lifetime value, why they're slipping, and a one-line suggested next move.
- Ignores test-mode events from Stripe so your retention channel never gets polluted with noise from sandbox transactions.
What do I need to use this?
- A Ghost site with Admin API access (a Custom Integration set up under Settings, Integrations).
- A Stripe account connected to your Ghost membership, with permission to receive webhooks.
- A Slack workspace and the name of the channel where you want retention alerts to land (for example, #retention).
How can I customize it?
- Change the Slack channel, or send to multiple channels if growth and support both want a copy.
- Adjust the labels that get applied in Ghost, for example payment-failed versus canceled, or add tier-specific tags like vip-at-risk.
- Tune the suggested next step language so it matches your playbook, for example a 20% win-back offer for paid tiers and a personal note for VIPs.
- Add a value threshold so only members above a certain lifetime value trigger a Slack ping, and silently label the rest.
Frequently asked questions
Does this work for Ghost sites that bill through Stripe?
Will I get pinged for test payments?
What if a member's email in Ghost doesn't match their Stripe email?
Can I use this without Slack?
How fast is the alert?
Stop losing paid members you could have saved.
Connect Ghost, Stripe, and Slack once, and Geni pings your retention channel the moment a member's payment fails or cancels.