Payment ProcessingPayment Method Manager
Payment Method Manager
The Payment Method Manager component provides a PCI-compliant UI for managing billing payment methods. Uses redirect-to-gateway approach for secure add/edit operations with no direct handling of sensitive data.
Payment Methods
Manage your saved payment methods for quick and secure transactions.
Credit Card
Last 4:•••• 1234
Expiry:12/25
ACH Account
Last 4:•••• 5678
Routing:123456789
Credit Card
Last 4:•••• 4321
Expiry:11/27
"use client"
import React, { useState } from "react";
import { PaymentMethodManager, PaymentMethod } from "@/components/billingsdk/payment-method-manager";
const initialMethods: PaymentMethod[] = [
{
id: "pm1",
type: "credit",
last4: "1234",
expiry: "12/25",
isDefault: true,
},
{
id: "pm2",
type: "ach",
last4: "5678",
expiry: undefined,
isDefault: false,
routing: "123456789",
},
{
id: "pm3",
type: "credit",
last4: "4321",
expiry: "11/27",
isDefault: false,
},
];
export function PaymentMethodManagerDemo() {
const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>(initialMethods);
const handleAdd = (method: PaymentMethod) => {
setPaymentMethods((prev) => [...prev, method]);
};
const handleEdit = (updated: PaymentMethod) => {
setPaymentMethods((prev) => prev.map((pm) => pm.id === updated.id ? updated : pm));
};
const handleRemove = (id: string) => {
setPaymentMethods((prev) => prev.filter((pm) => pm.id !== id));
};
const handleSetDefault = (id: string) => {
setPaymentMethods((prev) => prev.map((pm) => ({ ...pm, isDefault: pm.id === id })));
};
const handleRedirect = (type: 'add' | 'edit', methodId?: string) => {
console.log("Redirecting...", { type, methodId });
};
return (
<PaymentMethodManager
paymentMethods={paymentMethods}
onAdd={handleAdd}
onEdit={handleEdit}
onRemove={handleRemove}
onSetDefault={handleSetDefault}
onRedirect={handleRedirect}
className="w-full"
/>
);
}
Installation
npx shadcn@latest add @billingsdk/payment-method-manager
pnpm dlx shadcn@latest add @billingsdk/payment-method-manager
npx shadcn@latest add @billingsdk/payment-method-manager
Usage
import { PaymentMethodManager, type PaymentMethod } from "@/components/billingsdk/payment-method-manager";
const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>([
{
id: 'pm_1',
type: 'credit',
last4: '4242',
expiry: '12/25',
isDefault: true,
},
{
id: 'pm_2',
type: 'ach',
last4: '1234',
isDefault: false,
routing: '021000021',
},
]);
<PaymentMethodManager
className="max-w-4xl mx-auto"
paymentMethods={paymentMethods}
onAdd={(method) => setPaymentMethods([...paymentMethods, method])}
onEdit={(method) => setPaymentMethods(paymentMethods.map(pm => pm.id === method.id ? method : pm))}
onRemove={(id) => setPaymentMethods(paymentMethods.filter(pm => pm.id !== id))}
onSetDefault={(id) => setPaymentMethods(paymentMethods.map(pm => ({ ...pm, isDefault: pm.id === id })))}
onRedirect={(type, methodId) => {
// Redirect to payment gateway (e.g., Stripe, Razorpay)
console.log("Redirecting to gateway:", { type, methodId });
}}
/>
Props
Prop | Type | Required | Description |
---|---|---|---|
className | string | ❌ | Additional CSS classes for styling |
paymentMethods | PaymentMethod[] | ✅ | Array of payment methods to display |
onAdd | (method: PaymentMethod) => void | ❌ | Callback when a new payment method is added |
onEdit | (method: PaymentMethod) => void | ❌ | Callback when a payment method is edited |
onRemove | (id: string) => void | ❌ | Callback when a payment method is removed |
onSetDefault | (id: string) => void | ❌ | Callback to set a payment method as default |
onRedirect | (type: 'add' | 'edit', methodId?: string) => void | ✅ | Callback to redirect to payment gateway for PCI-compliant add/edit operations |
PaymentMethod Interface
interface PaymentMethod {
id: string;
type: 'credit' | 'ach';
last4: string;
expiry?: string; // Required for credit cards (MM/YY format)
isDefault: boolean;
routing?: string; // Required for ACH accounts
}
Theming
The Payment Method Manager 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
"use client"
import React, { useState } from "react";
import { PaymentMethodManager, PaymentMethod } from "@/components/billingsdk/payment-method-manager";
const initialMethods: PaymentMethod[] = [
{
id: "pm1",
type: "credit",
last4: "1234",
expiry: "12/25",
isDefault: true,
},
{
id: "pm2",
type: "ach",
last4: "5678",
expiry: undefined,
isDefault: false,
routing: "123456789",
},
{
id: "pm3",
type: "credit",
last4: "4321",
expiry: "11/27",
isDefault: false,
},
];
export function PaymentMethodManagerDemo() {
const [paymentMethods, setPaymentMethods] = useState<PaymentMethod[]>(initialMethods);
const handleAdd = (method: PaymentMethod) => {
setPaymentMethods((prev) => [...prev, method]);
};
const handleEdit = (updated: PaymentMethod) => {
setPaymentMethods((prev) => prev.map((pm) => pm.id === updated.id ? updated : pm));
};
const handleRemove = (id: string) => {
setPaymentMethods((prev) => prev.filter((pm) => pm.id !== id));
};
const handleSetDefault = (id: string) => {
setPaymentMethods((prev) => prev.map((pm) => ({ ...pm, isDefault: pm.id === id })));
};
const handleRedirect = (type: 'add' | 'edit', methodId?: string) => {
console.log("Redirecting...", { type, methodId });
};
return (
<PaymentMethodManager
paymentMethods={paymentMethods}
onAdd={handleAdd}
onEdit={handleEdit}
onRemove={handleRemove}
onSetDefault={handleSetDefault}
onRedirect={handleRedirect}
className="w-full"
/>
);
}
Credits
- Created by @guglxni