Billing SDK/Billing SDK
Cancel SubscriptionCancel Subscription Dialog

Cancel Subscription Dialog

The Cancel Subscription Dialog component provides a comprehensive and user-friendly interface for handling subscription cancellations. It features a two-step confirmation process, loading states, error handling, and full customization options.

src/components/cancel-subscription-dialog-demo.tsx
"use client";

import { CancelSubscriptionDialog } from "@/components/billingsdk/cancel-subscription-dialog";
import { plans } from "@/lib/billingsdk-config";

export function CancelSubscriptionDialogDemo() {
    return(

      <div className="flex flex-1 flex-col justify-center text-center p-4 mx-auto min-h-[300px]">
      <CancelSubscriptionDialog
        title="We're sorry to see you go..."
        description={`Before you cancel, we hope you'll consider upgrading to a ${plans[1].title} plan again.`}
        plan={plans[1]}
        triggerButtonText="Cancel Subscription"
        leftPanelImageUrl="https://framerusercontent.com/images/GWE8vop9hubsuh3uWWn0vyuxEg.webp"
        warningTitle="You will lose access to your account"
        warningText="If you cancel your subscription, you will lose access to your account and all your data will be deleted."
        keepButtonText={`Keep My ${plans[1].title} Plan`}
        continueButtonText="Continue with Cancellation"
        finalTitle="Final Step - Confirm Cancellation"
        finalSubtitle="This action will immediately cancel your subscription"
        finalWarningText="You'll lose access to all Pro features and your data will be permanently deleted after 30 days."
        goBackButtonText="Wait, Go Back"
        confirmButtonText="Yes, Cancel My Subscription"
        onCancel={async (planId) => {
          console.log('Cancelling subscription for plan:', planId);
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve(void 0);
            }, 1000);
          });
        }}
        onKeepSubscription={async (planId) => {
          console.log('Keeping subscription for plan:', planId);
        }}
        onDialogClose={() => {
          console.log('Dialog closed');
        }}
        className="max-w-4xl"
      />
    </div>
    )
}

Installation

npx shadcn@latest add @billingsdk/cancel-subscription-dialog
pnpm dlx shadcn@latest add @billingsdk/cancel-subscription-dialog
npx shadcn@latest add @billingsdk/cancel-subscription-dialog
npx @billingsdk/cli add cancel-subscription-dialog
pnpm dlx @billingsdk/cli add cancel-subscription-dialog
npx @billingsdk/cli add cancel-subscription-dialog

Usage

import { CancelSubscriptionDialog } from "@/components/billingsdk/cancel-subscription-dialog";
import { plans } from "@/lib/billingsdk-config";
<CancelSubscriptionDialog
  title="We're sorry to see you go..."
  description="Before you cancel, let us know what we could do better."
  plan={plans[1]}
  onCancel={async (planId) => {
    // Handle cancellation
    await cancelSubscription(planId);
  }}
/>

Props

PropTypeRequiredDescription
titlestringMain dialog title
descriptionstringDialog description text
planPlanPlan object containing subscription details. The plans array in the lib/billingsdk-config.ts file.
onCancel(planId: string) => Promise<void> | voidCallback when subscription is cancelled
triggerButtonTextstringText for the trigger button (default: "Cancel Subscription")
leftPanelImageUrlstringBackground image URL for left panel
warningTitlestringTitle for warning section
warningTextstringWarning message text
keepButtonTextstringText for keep subscription button
continueButtonTextstringText for continue cancellation button
finalTitlestringTitle for final confirmation step
finalSubtitlestringSubtitle for final confirmation step
finalWarningTextstringFinal warning message
goBackButtonTextstringText for go back button
confirmButtonTextstringText for final confirm button
onKeepSubscription(planId: string) => Promise<void> | voidCallback when user keeps subscription
onDialogClose() => voidCallback when dialog is closed
classNamestringAdditional CSS classes

Theming

The cancel subscription dialog component is styled using the shadcn/ui library. You can customize the colors and fonts by overriding the CSS variables. You can also get the theme from the Theming page.

Example

src/components/cancel-subscription-dialog-demo.tsx
"use client";

import { CancelSubscriptionDialog } from "@/components/billingsdk/cancel-subscription-dialog";
import { plans } from "@/lib/billingsdk-config";

export function CancelSubscriptionDialogDemo() {
    return(

      <div className="flex flex-1 flex-col justify-center text-center p-4 mx-auto min-h-[300px]">
      <CancelSubscriptionDialog
        title="We're sorry to see you go..."
        description={`Before you cancel, we hope you'll consider upgrading to a ${plans[1].title} plan again.`}
        plan={plans[1]}
        triggerButtonText="Cancel Subscription"
        leftPanelImageUrl="https://framerusercontent.com/images/GWE8vop9hubsuh3uWWn0vyuxEg.webp"
        warningTitle="You will lose access to your account"
        warningText="If you cancel your subscription, you will lose access to your account and all your data will be deleted."
        keepButtonText={`Keep My ${plans[1].title} Plan`}
        continueButtonText="Continue with Cancellation"
        finalTitle="Final Step - Confirm Cancellation"
        finalSubtitle="This action will immediately cancel your subscription"
        finalWarningText="You'll lose access to all Pro features and your data will be permanently deleted after 30 days."
        goBackButtonText="Wait, Go Back"
        confirmButtonText="Yes, Cancel My Subscription"
        onCancel={async (planId) => {
          console.log('Cancelling subscription for plan:', planId);
          return new Promise((resolve) => {
            setTimeout(() => {
              resolve(void 0);
            }, 1000);
          });
        }}
        onKeepSubscription={async (planId) => {
          console.log('Keeping subscription for plan:', planId);
        }}
        onDialogClose={() => {
          console.log('Dialog closed');
        }}
        className="max-w-4xl"
      />
    </div>
    )
}