# Payment Failure URL: /docs/components/payment-failure A payment failure card that explains why a payment could not be processed, with actions to retry, go home, or contact support. *** title: Payment Failure description: A payment failure card that explains why a payment could not be processed, with actions to retry, go home, or contact support. ------------------------------------------------------------------------------------------------------------------------------------------- ```tsx title="src/components/payment-failure-demo.tsx" "use client"; import React, { useState } from "react"; import { useRouter } from "next/navigation"; import { PaymentFailure } from "@/registry/billingsdk/payment-failure"; export function PaymentFailureDemo() { const [isRetrying, setIsRetrying] = useState(false); const router = useRouter(); const handleRetry = async () => { setIsRetrying(true); try { // TODO: your actual retry logic (redirect to payment, call API, etc.) await new Promise((resolve) => setTimeout(resolve, 1500)); // e.g. router.push("/checkout"); } finally { setIsRetrying(false); } }; return (
router.push("/")} onTertiary={() => router.push("/support")} reasons={[ "Insufficient funds in your account", "Incorrect card details or expired card", "Card declined by your bank", "Network connection issues", ]} // Optional overrides: // title="Payment declined" // subtitle="Your bank declined the transaction." // retryButtonText="Retry Payment" // secondaryButtonText="Go Home" // tertiaryButtonText="Contact Support" />
); } ```
## Installation `bash npx shadcn@latest add @billingsdk/payment-failure ` `bash pnpm dlx shadcn@latest add @billingsdk/payment-failure ` `bash yarn dlx shadcn@latest add @billingsdk/payment-failure ` `bash bunx shadcn@latest add @billingsdk/payment-failure ` `bash npx @billingsdk/cli add payment-failure ` `bash pnpm dlx @billingsdk/cli add payment-failure ` `bash yarn dlx @billingsdk/cli add payment-failure ` `bash bunx @billingsdk/cli add payment-failure ` ## Usage ```tsx import { PaymentFailure } from "@/components/billingsdk/payment-failure"; ``` ```tsx // Controlled usage (recommended) const [isRetrying, setIsRetrying] = useState(false); async function handleRetry() { setIsRetrying(true); // Add your retry logic here (e.g., redirect to checkout or re-initiate payment) await new Promise((resolve) => setTimeout(resolve, 1500)); setIsRetrying(false); } router.push("/")} onTertiary={() => router.push("/support")} />; ``` ## Customizing text ```tsx console.log("retry")} onSecondary={() => router.push("/")} onTertiary={() => router.push("/support")} /> ``` ## Props | Prop | Type | Required | Description | | --------------------- | ------------ | -------- | ---------------------------------------------------------------------------- | | `title` | `string` | ❌ | Optional heading (default: `"Payment Failed"`) | | `subtitle` | `string` | ❌ | Optional subtext (default: `"We couldn't process your payment."`) | | `message` | `string` | ❌ | Additional explanatory message displayed under the reasons list | | `reasons` | `string[]` | ❌ | List of possible failure reasons (defaults to common payment failure causes) | | `isRetrying` | `boolean` | ❌ | Shows loading state and disables retry button | | `retryButtonText` | `string` | ❌ | Primary action label (default: `"Try Again"`) | | `secondaryButtonText` | `string` | ❌ | Secondary button label (default: `"Home"`) | | `tertiaryButtonText` | `string` | ❌ | Tertiary button label (default: `"Support"`) | | `onRetry` | `() => void` | ❌ | Callback fired when user presses retry | | `onSecondary` | `() => void` | ❌ | Callback fired when user presses the secondary action | | `onTertiary` | `() => void` | ❌ | Callback fired when user presses tertiary action | | `className` | `string` | ❌ | Additional classes for styling / layout | ## Theming This dialog inherits BillingSDK theme tokens via `getThemeStyles`, remaining consistent with other components. Colors adapt to light/dark modes and active theme. ## Example ```tsx title="src/components/payment-failure-demo.tsx" "use client"; import React, { useState } from "react"; import { useRouter } from "next/navigation"; import { PaymentFailure } from "@/registry/billingsdk/payment-failure"; export function PaymentFailureDemo() { const [isRetrying, setIsRetrying] = useState(false); const router = useRouter(); const handleRetry = async () => { setIsRetrying(true); try { // TODO: your actual retry logic (redirect to payment, call API, etc.) await new Promise((resolve) => setTimeout(resolve, 1500)); // e.g. router.push("/checkout"); } finally { setIsRetrying(false); } }; return (
router.push("/")} onTertiary={() => router.push("/support")} reasons={[ "Insufficient funds in your account", "Incorrect card details or expired card", "Card declined by your bank", "Network connection issues", ]} // Optional overrides: // title="Payment declined" // subtitle="Your bank declined the transaction." // retryButtonText="Retry Payment" // secondaryButtonText="Go Home" // tertiaryButtonText="Contact Support" />
); } ```