# 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"
/>
);
}
```