LostChurn Docs
Widgets

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

OptionTypeDefaultDescription
customerIdstringRequiredThe customer's payment processor ID (e.g., cus_abc123)
position"top" | "bottom""top"Where the bar appears on the page
dismissiblebooleantrueWhether the customer can dismiss the bar
dismissDurationnumber86400Seconds before a dismissed bar reappears (default: 24 hours)
messagestringAuto-generatedCustom message text. If omitted, LostChurn generates a contextual message based on the decline reason
ctaTextstring"Update Payment Method"Text for the call-to-action button
ctaUrlstringHosted formURL 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
onShowfunction--Callback fired when the bar becomes visible
onDismissfunction--Callback fired when the customer dismisses the bar
onCtaClickfunction--Callback fired when the CTA button is clicked
onRecoveryfunction--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:

  1. A modal opens with your payment processor's secure payment element (e.g., Stripe Elements).
  2. The customer enters their new card details directly into the processor's iframe -- LostChurn never sees the raw card data.
  3. On successful update, LostChurn immediately triggers a retry of the failed payment.
  4. The onRecovery callback 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

ScenarioBehavior
Customer has no failed paymentsBar is not rendered
Customer has multiple failed paymentsBar shows the most recent failure
Customer dismisses the barBar reappears after dismissDuration seconds
Payment is recovered while bar is visibleBar auto-hides and onRecovery fires
Customer is not authenticatedBar is not rendered (no customer ID)

Next Steps

On this page