Payment Form

A complete card-checkout block. The number, expiry and CVC are masked as you type, the card brand is detected live, and the billing country shows circular flags. Accept promo codes to roll the total.

Payment details

Enter your card to complete the purchase. Your details are encrypted end to end.

Total due$49.00

Try KOALA20 for 20% off, or WELCOME10 for $10 off.

Payments are secure and encrypted

Installation#

# One-time setup (tokens + lib helpers)npx koalaui-cli@latest init# Add this component (its dependencies come along)npx koalaui-cli@latest add payment-form

Usage#

usage.tsxTSX
"use client"import { PaymentForm, type PaymentFormData } from "@/components/ui/payment-form"export function Example() {  async function pay(data: PaymentFormData) {    await fetch("/api/checkout", { method: "POST", body: JSON.stringify(data) })  }  return (    <PaymentForm      amount="$49.00"      promoCodes={{ WELCOME10: { amountOff: 10, label: "WELCOME10 · $10 off" } }}      onSubmit={pay}    />  )}

API reference#

PaymentForm

Composes Field, Input, and Select. The masking and brand detection are presentation only; never store an unmasked card number. Forwards all <div> props.

  • amount: display total (e.g. "$49.00"). Shows the summary row and labels the Pay button. When a code is applied, the shown total is the discounted one.
  • promoCodes: Record<string, PaymentPromoCode> keyed by code (matched case-insensitively). Reveals the promo-code row; each code carries a percentOff and/or amountOff (and an optional label). Applying one drops in a subtotal → discount breakdown and rolls the total. Requires a parseable amount.
  • promoHint: caption under the promo input (e.g. "Try KOALA20").
  • defaultCountry: billing country ISO2 (default "US").
  • onSubmit: (data: PaymentFormData) => void | Promise<void>, where PaymentFormData is { cardNumber, expiry, cvc, name, country, promoCode? }.

FAQ#

No. The masking and live brand detection are presentation only, and PaymentForm never touches a network. Wire your `onSubmit` handler to a provider like Stripe, and never store the unmasked card number yourself.