Payment Card Input

Commerce

Credit card payment form fields.

Preview

Usage

example.jsx
import { PaymentCardInput } from "@/components/ui/payment-card-input";

export default function Example() {
  return <PaymentCardInput />;
}

Source Code

Copy this file into components/ui/payment-card-input.jsx in your project.

payment-card-input.jsx
"use client";

import { forwardRef, useState } from "react";
import { cn } from "@/lib/utils";

const PaymentCardInput = forwardRef(({ className, onSubmit, ...props }, ref) => {
  const [form, setForm] = useState({ number: "", expiry: "", cvc: "", name: "" });
  const update = (k) => (e) => setForm({ ...form, [k]: e.target.value });
  const handleSubmit = (e) => { e.preventDefault(); onSubmit?.(form); };

  const inputCn = "flex h-10 w-full rounded-md border bg-background px-3 py-2 text-sm font-mono focus:outline-none focus:ring-2 focus:ring-ring";

  return (
    <form ref={ref} onSubmit={handleSubmit} className={cn("space-y-4", className)} {...props}>
      <div className="rounded-lg border p-4">
        <div className="space-y-2">
          <label className="text-sm font-medium">Card Number</label>
          <input type="text" placeholder="4242 4242 4242 4242" value={form.number} onChange={update("number")} maxLength={19} className={inputCn} />
        </div>
        <div className="mt-4 grid grid-cols-2 gap-4">
          <div className="space-y-2">
            <label className="text-sm font-medium">Expiry</label>
            <input type="text" placeholder="MM/YY" value={form.expiry} onChange={update("expiry")} maxLength={5} className={inputCn} />
          </div>
          <div className="space-y-2">
            <label className="text-sm font-medium">CVC</label>
            <input type="text" placeholder="123" value={form.cvc} onChange={update("cvc")} maxLength={4} className={inputCn} />
          </div>
        </div>
        <div className="mt-4 space-y-2">
          <label className="text-sm font-medium">Name on Card</label>
          <input type="text" value={form.name} onChange={update("name")} className={inputCn} />
        </div>
      </div>
      <button type="submit" className="inline-flex h-10 w-full items-center justify-center rounded-md bg-primary text-sm font-medium text-primary-foreground hover:bg-primary/90">Pay Now</button>
    </form>
  );
});
PaymentCardInput.displayName = "PaymentCardInput";

export { PaymentCardInput };

Quick Install

Make sure you have the cn() utility set up. It requires clsx and tailwind-merge.

npm install clsx tailwind-merge