Installation Guide
KeepFlow adds a retention flow in front of your cancel button. Installation is two steps: add one script tag, then call KeepFlow.open() when a customer clicks “Cancel subscription”. Most teams are done in under 15 minutes.
Before you start
- A KeepFlow account with your Stripe account connected (done from the dashboard in one click).
- A project created in the dashboard — this gives you the API key used in the script tag below.
- Your app must know each customer's Stripe
cus_…andsub_…IDs — you already store these if you bill with Stripe subscriptions.
Step 1: Add the script
Add this tag to any page where customers can cancel (your billing or account-settings page), or globally in your layout. Replace YOUR_API_KEY with the key from your project's Install tab.
<script src="https://keepflow.io/widget/keepflow.js" data-api-key="YOUR_API_KEY"></script>The API key is publishable — it's safe in your page source. It only identifies your project and can't read data or touch subscriptions the visitor doesn't own. The script is ~7 KB, loads asynchronously (plain async and tag-manager installs are supported), and does nothing until you call it.
As soon as the script is live, your dashboard's Install tab flips to “Installation detected” so you can confirm this step worked before writing any code.
Step 2: Trigger the widget
Call KeepFlow.open() from your cancel button instead of canceling directly:
document.getElementById('cancel-button').addEventListener('click', () => {
KeepFlow.open({
// Required — from your own Stripe integration
customerId: 'cus_xxx', // the customer's Stripe ID
subscriptionId: 'sub_xxx', // the subscription being canceled
// Optional — values for {{variables}} in your widget headline
userData: { name: 'Ada', planName: 'Pro' },
// Optional — where to send users if the widget can't load
fallbackUrl: 'https://billing.stripe.com/p/session/...',
onComplete: (result) => {
if (result.status === 'saved') {
// Customer accepted an offer — subscription unchanged or discounted
} else {
// Customer canceled (at period end) — update your UI
}
},
onError: (error) => {
// Widget failed — let your normal cancel flow proceed
},
});
});What KeepFlow does with the result
- Customer accepts a discount — KeepFlow creates the coupon and applies it to the subscription via your connected Stripe account. Discounts never stack, and a customer who already used a save offer in the last 12 months won't get another.
- Customer accepts a pause — the subscription's collection is paused and auto-resumes after the configured number of months.
- Customer still cancels — the subscription is canceled at the end of the billing period (they keep what they paid for), and the reason + feedback land in your analytics.
- Anything fails — the widget shows a fail-safe screen so the customer can always complete their cancellation; you're notified via
onError.
API reference
| Option | Type | Description |
|---|---|---|
customerId | string, required | Stripe customer ID (cus_…). Must own the subscription. |
subscriptionId | string, required | Stripe subscription ID (sub_…) being canceled. |
userData | object | Values interpolated into {{variable}} placeholders in your widget copy. |
fallbackUrl | string (https) | Shown as “Manage Subscription” if the widget can't load (e.g. your Stripe customer-portal link). |
onComplete(result) | function | result.status is 'saved', 'canceled', or 'fallback_cancel'; result.reason is the selected reason ID. |
onError(error) | function | Called when the widget can't load or submit. Fall back to your own cancel flow here. |
onFallbackCancel(info) | function | Called when the user chooses to cancel from the fail-safe screen — complete the cancellation in your own backend. |
FAQ
Does this work from my domain? (CORS)
Yes — the widget API is built for cross-origin use and works from any domain where you embed the script.
Can KeepFlow cancel the wrong subscription?
No. The server verifies the subscription belongs to the customer you pass before doing anything, and every Stripe action happens on your connected account with the IDs you provided.
What if KeepFlow is down when someone tries to cancel?
The widget times out after 10 seconds and shows a fail-safe screen so your customer can always cancel — via your fallbackUrl or your own flow through onFallbackCancel. KeepFlow never blocks a cancellation.
I use React / Next.js / Vue — anything special?
No framework adapter needed. Load the script tag once (e.g. in your root layout or with your framework's Script component) and call window.KeepFlow.open() from your cancel handler.
Need help with your integration?
Email support@keepflow.io — integration questions are answered same-day.
Start Your Free Trial