Add churn prevention to your subscription app.
Connect Stripe, install the React SDK, launch adaptive cancel flows, recover failed payments, and send the customer signals Churnless needs to protect MRR.
Create keys
Use a browser-safe publishable key in your app and a secret key only from your server.
Connect Stripe
Paste a restricted Stripe key so Churnless can read products, customers, subscriptions, invoices, and payment failures.
Install the SDK
Wrap your app with the provider, then drop the cancel flow where cancellation starts.
Send signals
Track usage, feedback, support, and lifecycle events so the save path can adapt to the customer.
Create the right keys.
Churnless uses two key types. The publishable key can run in the browser. The secret key is only for server-side API calls, MCP, jobs, and customer imports.
Publishable key
Use `fk_pub_...` with the React SDK and pixel. It can start cancel flows and check payment state for known customers.
Secret key
Use `fk_live_...` only on your server. Never expose it to client bundles, mobile apps, or public config.
Stripe restricted key
In Churnless settings, paste a restricted Stripe key with the prefilled least-privilege permissions. Churnless uses read scopes to import customers, products, prices, subscriptions, invoices, and charges, plus limited write scopes for save actions such as pauses, discounts, and cancellation at period end. Start in test mode, run the import, then switch to your live Stripe key when the mapping looks right.
Install the React SDK.
The SDK handles API calls, modal state, lifecycle events, and optional pixel forwarding. Use it anywhere your customer can manage billing.
npm install @furnkey/reactimport { ChurnlessProvider } from "@furnkey/react";
export function AppProviders({ children, customer }) {
return (
<ChurnlessProvider
publishableKey={process.env.NEXT_PUBLIC_CHURNLESS_KEY}
customerId={customer.stripeCustomerId}
productId="prod_adscreator"
trackingConsent={customer.analyticsConsent}
>
{children}
</ChurnlessProvider>
);
}Replace the raw cancel button.
Pass the same customer ID you use in Stripe. Churnless starts a session, asks for the reason, chooses the next best step, and reports the outcome.
import { CancelFlow } from "@furnkey/react";
export function BillingSettings({ customer }) {
return (
<CancelFlow
customerId={customer.stripeCustomerId}
onSaved={() => window.location.reload()}
onCanceled={() => window.location.assign("/goodbye")}
onError={(error) => console.error(error)}
>
{({ show, isLoading }) => (
<button onClick={show} disabled={isLoading}>
{isLoading ? "Loading..." : "Cancel subscription"}
</button>
)}
</CancelFlow>
);
}Block involuntary churn without blocking recovery.
Use the payment wall around authenticated app content. Customers with unresolved failures see a clear path to update payment details; everyone else sees the app.
import { PaymentRecoveryWall } from "@furnkey/react";
export function ProtectedApp({ customer, children }) {
return (
<PaymentRecoveryWall
customerId={customer.stripeCustomerId}
fallback={children}
pollInterval={60000}
/>
);
}Send the product signals that predict churn.
The better the signal history, the better the cancellation path. Track meaningful usage, activation, support friction, billing friction, and feedback.
<script>
window.fk = window.fk || function(){(window.fk.q = window.fk.q || []).push(arguments)};
fk("init", "fk_pub_...", {
customerId: "cus_123",
productId: "prod_adscreator",
consent: true
});
fk("track", "feature_used", {
feature: "campaign_export",
value: 1
});
</script>
<script async src="https://www.getchurnless.com/pixel/v1.js"></script>await fetch("https://www.getchurnless.com/api/v1/events", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-API-Key": process.env.CHURNLESS_API_KEY
},
body: JSON.stringify({
customerId: "cus_123",
productId: "prod_adscreator",
eventType: "feature_used",
eventName: "campaign_exported",
category: "usage",
payload: {
exportCount: 3,
campaignId: "camp_789"
}
})
});Usage
feature_used, project_created, export_completed
Lifecycle
trial_started, activation_completed, team_invited
Friction
support_ticket_opened, error_seen, downgrade_viewed
Use the API and MCP server for automation.
Server-side integrations can import customers, push events, inspect health scores, list cancel sessions, and let internal AI tools query churn context.