Recovery Bar
Display a banner to customers with failed payments, prompting them to update their payment method directly from your site.
The Recovery Bar is a non-intrusive banner that appears at the top of your site when a customer has a failed payment. It prompts them to update their payment method without leaving your application, significantly improving recovery rates compared to email-only dunning.
How It Works
When the Recovery Bar loads, it calls the LostChurn API with the customer's ID to check their payment status. If the customer has an active failed payment in recovery, the bar renders with a message and a call-to-action button. If there are no issues, nothing is rendered.
Clicking the call-to-action opens a hosted payment update form (powered by your payment processor's secure elements) in a modal or redirects to a hosted page, depending on your configuration.
Quick Start
Script Tag
<!-- Add before closing </body> tag -->
<script
src="https://cdn.lostchurn.com/widgets/v1/lostchurn.js"
data-publishable-key="lc_pub_your_key"
data-widget="recovery-bar"
data-customer-id="cus_abc123"
async
></script>React
import { LostChurnProvider, RecoveryBar } from "@lostchurn/react";
function App() {
return (
<LostChurnProvider publishableKey="lc_pub_your_key">
<RecoveryBar customerId="cus_abc123" />
<main>{/* your app content */}</main>
</LostChurnProvider>
);
}JavaScript SDK
import { LostChurn } from "@lostchurn/js";
const lc = new LostChurn("lc_pub_your_key");
lc.mount("recovery-bar", {
customerId: "cus_abc123",
container: document.body, // prepends to body
});Configuration Options
| Option | Type | Default | Description |
|---|---|---|---|
customerId | string | Required | The customer's payment processor ID (e.g., cus_abc123) |
position | "top" | "bottom" | "top" | Where the bar appears on the page |
dismissible | boolean | true | Whether the customer can dismiss the bar |
dismissDuration | number | 86400 | Seconds before a dismissed bar reappears (default: 24 hours) |
message | string | Auto-generated | Custom message text. If omitted, LostChurn generates a contextual message based on the decline reason |
ctaText | string | "Update Payment Method" | Text for the call-to-action button |
ctaUrl | string | Hosted form | URL to redirect to when the CTA is clicked. If omitted, opens the LostChurn hosted payment update modal |
theme | "light" | "dark" | "auto" | "auto" | Color scheme. "auto" follows the user's system preference |
onShow | function | -- | Callback fired when the bar becomes visible |
onDismiss | function | -- | Callback fired when the customer dismisses the bar |
onCtaClick | function | -- | Callback fired when the CTA button is clicked |
onRecovery | function | -- | Callback fired when the payment is successfully recovered |
React Props Example
<RecoveryBar
customerId="cus_abc123"
position="top"
dismissible={true}
dismissDuration={43200}
ctaText="Fix Payment"
theme="light"
onRecovery={() => {
toast.success("Payment recovered! Thank you.");
}}
/>Script Tag Configuration
For the script tag integration, pass configuration as data- attributes or via a global config object:
<script>
window.LostChurnConfig = {
publishableKey: "lc_pub_your_key",
widget: "recovery-bar",
customerId: "cus_abc123",
position: "top",
dismissible: true,
ctaText: "Fix Payment",
theme: "light",
};
</script>
<script src="https://cdn.lostchurn.com/widgets/v1/lostchurn.js" async></script>Dynamic Customer ID
If the customer ID is not available at page load (e.g., it depends on authentication state), you can set it dynamically:
React
function App() {
const { user } = useAuth();
return (
<LostChurnProvider publishableKey="lc_pub_your_key">
{user?.stripeCustomerId && (
<RecoveryBar customerId={user.stripeCustomerId} />
)}
</LostChurnProvider>
);
}JavaScript SDK
const lc = new LostChurn("lc_pub_your_key");
// Mount later when customer ID is available
auth.onReady((user) => {
lc.mount("recovery-bar", {
customerId: user.stripeCustomerId,
});
});Payment Update Flow
When a customer clicks the call-to-action, LostChurn handles the payment update flow securely:
- A modal opens with your payment processor's secure payment element (e.g., Stripe Elements).
- The customer enters their new card details directly into the processor's iframe -- LostChurn never sees the raw card data.
- On successful update, LostChurn immediately triggers a retry of the failed payment.
- The
onRecoverycallback fires when the retry succeeds, so you can show a success message in your UI.
The payment update modal uses your payment processor's hosted fields, so the customer's card details never pass through LostChurn's servers. This keeps you and LostChurn out of PCI scope.
Behavior Rules
| Scenario | Behavior |
|---|---|
| Customer has no failed payments | Bar is not rendered |
| Customer has multiple failed payments | Bar shows the most recent failure |
| Customer dismisses the bar | Bar reappears after dismissDuration seconds |
| Payment is recovered while bar is visible | Bar auto-hides and onRecovery fires |
| Customer is not authenticated | Bar is not rendered (no customer ID) |
Next Steps
- Cancel Flow Widget -- embed cancellation flows in your app
- Customization -- theme the Recovery Bar to match your brand
- Widgets Overview -- all available widgets