A simple, open-source cancellation flow modal for Stripe subscriptions. Reduce churn by understanding why users cancel.
- π¨ Customizable cancellation reasons
- π¬ Optional feedback collection
- π Automatic dark mode support
- π± Mobile responsive
- πͺΆ Lightweight (~4KB minified)
- π§ Framework agnostic
<script src="https://unpkg.com/keepflow-lite@latest/dist/keepflow-lite.min.js"></script>
<script>
document.getElementById('cancel-btn').addEventListener('click', function() {
KeepFlowLite.show({
onComplete: function(result) {
console.log('Reason:', result.reason);
console.log('Feedback:', result.feedback);
// Call your backend to cancel the subscription
fetch('/api/cancel-subscription', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
reason: result.reason.id,
feedback: result.feedback
})
});
}
});
});
</script>npm install keepflow-liteimport KeepFlowLite from 'keepflow-lite';
KeepFlowLite.show({
onComplete: (result) => {
// Handle cancellation
}
});KeepFlowLite.show({
// Customize the title and subtitle
title: 'Before you go...',
subtitle: "We'd love to know why you're leaving",
// Define your cancellation reasons
reasons: [
{ id: 'too_expensive', label: 'Too expensive' },
{ id: 'not_using', label: 'Not using it enough' },
{ id: 'switched', label: 'Switched to another service' },
{ id: 'missing_features', label: 'Missing features I need' },
{ id: 'other', label: 'Other' }
],
// Button text
cancelButtonText: 'Cancel Subscription',
keepButtonText: "Never mind, I'll stay",
// Feedback step
showFeedbackStep: true,
feedbackTitle: 'One last thing...',
feedbackSubtitle: 'Any additional feedback?',
feedbackPlaceholder: 'Tell us more (optional)...',
// Thank you screen
thankYouTitle: "We're sorry to see you go",
thankYouMessage: 'Your subscription has been canceled.',
// Styling
primaryColor: '#6366f1',
// Callbacks
onReasonSelected: (reason) => {
console.log('User selected:', reason.label);
},
onFeedbackSubmitted: (feedback) => {
console.log('Feedback:', feedback);
},
onComplete: (result) => {
// result = { reason, feedback, action: 'canceled' }
// Call your backend here to actually cancel the subscription
},
onCancel: () => {
// User clicked "I'll stay"
console.log('User decided to stay!');
}
});KeepFlow Lite handles the UI - you need to implement the actual cancellation logic.
// routes/cancel-subscription.js
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY);
app.post('/api/cancel-subscription', async (req, res) => {
const { reason, feedback, subscriptionId } = req.body;
try {
// Cancel the subscription in Stripe
await stripe.subscriptions.cancel(subscriptionId);
// Log the reason for analytics
await db.cancellationReasons.create({
subscriptionId,
reason,
feedback,
canceledAt: new Date()
});
res.json({ success: true });
} catch (error) {
res.status(500).json({ error: error.message });
}
});See the examples folder for complete implementations.
The modal automatically adapts to dark mode. To customize colors:
KeepFlowLite.show({
primaryColor: '#your-brand-color',
// ...
});For more advanced styling, override the CSS classes:
.kfl-modal { /* modal container */ }
.kfl-title { /* heading */ }
.kfl-reason { /* reason buttons */ }
.kfl-btn-primary { /* primary button */ }| Method | Description |
|---|---|
KeepFlowLite.show(options) |
Display the cancellation modal |
KeepFlowLite.close() |
Programmatically close the modal |
KeepFlow Lite is great for basic cancellation flows, but if you want to actually reduce churn, you need:
| Feature | Lite (Free) | Pro ($29/mo) |
|---|---|---|
| Cancellation modal | β | β |
| Custom reasons | β | β |
| Feedback collection | β | β |
| Automatic discount offers | β | β |
| Subscription pause | β | β |
| Conditional logic (reason β offer) | β | β |
| Analytics dashboard | β | β |
| Revenue saved tracking | β | β |
| A/B testing | β | β |
| Stripe integration | β | β |
| Anti-gaming (cooldowns) | β | β |
| Setup time | Hours | 5 minutes |
- User clicks "Cancel" β KeepFlow modal appears
- User selects reason β Personalized offer shown automatically
- "Too expensive?" β 20% discount applied via Stripe
- "Not using it?" β Pause subscription for 1 month
- User saved β You keep the revenue
Average result: 15-30% of cancellations saved.
π Try KeepFlow Pro Free for 14 Days β
Contributions are welcome! Please read our contributing guidelines first.
MIT Β© KeepFlow
