Payment
The payment step of a checkout, with wallets, cards, PayPal and Pay in 4. Handles card validation, declines, 3-D Secure and slow banks.
Payment is the last step of a checkout. Wrap the parts in Payment with the order total and an onPay callback, then place ExpressCheckout, PaymentMethods, BillingAddress, PayButton and PaymentStatus where they fit your layout. Payment owns the state between them, so the button label follows the chosen method: “Pay $123.45” for a card, “Continue to PayPal”, “Pay $30.87 today” for Pay in 4.
The card form detects the brand from the first digits and swaps its mark only when the brand changes. It groups digits as you type, 4-6-5 for American Express, writes the expiry as MM/YY with the slash added for you, and accepts “1/27”, “0127” and pasted numbers with spaces or dashes. Each field is checked on blur or once it’s complete, then live, so an error clears the moment it’s fixed. Focus moves from number to expiry to security code only when the field before it is complete, valid and the next one is empty.
onPay gets a typed request with the card details or saved card, the amount, the billing choice and a fresh idempotency key. Return nothing or { status: "succeeded" } to finish: the button shows a check, holds for 700 ms and calls onComplete. Return { status: "declined", code } and the error appears above the methods with copy written for that code, focus moves to it, the card stays filled in and “Try another card” clears it. Return { status: "requires_action" } to open the “Confirm with your bank” dialog, where renderChallenge mounts your 3-D Secure step.
While a payment runs the button can’t be pressed twice, the methods are inert, leaving the page asks for confirmation, and after three seconds the status line says “Confirming with your bank…”. Saved cards that have expired show as disabled, and declineMessage gives the same copy for your own error screens.
HextaUI Pro'yu alın
Tek bir ödeme, gelecekte eklenecekler dahil tüm blokların kilidini açar. Fiyatları görün.
Pro registry'yi components.json dosyasına ekleyin
components.json Token'ınızı ekleyin
Hesap sayfanızda bir token oluşturun ve
.env.localdosyasınaHEXTAUI_PRO_TOKENolarak ekleyin.Bloğu ekleyin
pnpm dlx shadcn@latest add @hextaui-pro/payment
Stripe PaymentIntent
Create a PaymentIntent with the request’s idempotency key, confirm it with Stripe and return a declined result with Stripe’s decline code. In production, collect the card with Stripe Elements so raw card numbers never reach your server; the card form here is a visual reference that matches it.
PayPal redirect
Create a PayPal order on your server and send the shopper to its approval URL. The button keeps its processing state while the page leaves, and PayPal-Request-Id stops a double order if the request is retried.
Shopify checkout handoff
Use the payment step as a branded front for Shopify’s checkout. Shop Pay opens checkoutUrl with payment=shop_pay, and PayPal hands off to the same URL.
Yapı
Dıştan içe doğru birleştirdiğiniz parçalar.
| Parça | Açıklama |
|---|---|
Payment | Holds the method, card fields, billing choice and payment state, and renders the bank dialog. |
ExpressCheckout | A row of equal wallet buttons for the wallets you pass, with an “or pay another way” divider. |
PaymentMethods | Saved cards, the card form, PayPal and Pay in 4 as radio cards, with the decline message above them. |
BillingAddress | The “Billing address same as shipping” checkbox and the billing form it reveals. |
PayButton | The full-width pay button. Its label follows the method and it shows processing, waiting and paid. |
PaymentStatus | A line under the button with reassurance or progress, and the live region for screen readers. |
declineMessage, PaymentDeclinedError | Copy for each decline code, and an error you can throw from onPay with a code. |
| Prop | Tür | Varsayılan |
|---|---|---|
totalThe amount to charge, shown on the button. | Money | – |
onPayRuns the payment. Throwing shows the error’s message at the payment section. | (request: PaymentRequest) => Promise<PaymentResult | void> | PaymentResult | void | – |
onCompleteCalled after the success check has held. | (request: PaymentRequest, result: PaymentResult) => void | – |
validateRuns before onPay. Return false to stop, for example when your billing form has errors. | (request: PaymentRequest) => boolean | – |
methodsMethods listed after any saved cards, in order. | ("card" | "paypal" | "bnpl" | "apple_pay" | "google_pay")[] | ["card", "paypal", "bnpl"] |
savedCardsCards on file. Expired ones are shown but can’t be picked. | SavedCard[] | – |
methodThe selected method, controlled. Saved cards use "saved:<id>". | string | – |
defaultMethodThe first usable saved card, or the first method. | string | – |
onMethodChangeCalled when the shopper picks another method. | (method: string) => void | – |
sameAsShippingWhether billing matches shipping, controlled. | boolean | – |
defaultSameAsShippingThe starting value of the billing checkbox. | boolean | true |
onSameAsShippingChangeCalled when the billing checkbox changes. | (same: boolean) => void | – |
bnplHow many payments Pay in 4 splits into, and its name. | { installments?: number; title?: string } | { installments: 4 } |
renderChallengeContent of the “Confirm with your bank” dialog. Call complete with the final result. | (challenge: { action, amount, complete, cancel }) => ReactNode | – |
successDelayHow long the paid state holds before onComplete, in ms. | number | 700 |
slowAfterWhen the status line switches to “Confirming with your bank…”, in ms. | number | 3000 |
todayThe date expiry checks use. The browser’s date by default. | Date | – |
localeLocale for amounts. | Intl.LocalesArgument | "en-US" |
labelsEvery user-facing string. | Partial<PaymentLabels> | – |
ExpressCheckout
Works inside Payment or on its own.
| Prop | Tür | Varsayılan |
|---|---|---|
methodsWallets to show, in order. Only these render. | ("apple_pay" | "google_pay" | "shop_pay" | "paypal")[] | – |
onExpressOpens the wallet. The button shows a spinner until it settles. | (method: ExpressMethod) => Promise<PaymentResult | void> | PaymentResult | void | – |
dividerShow the “or pay another way” divider. | boolean | true |
labelsButton names, divider and group label. | Partial<ExpressCheckoutLabels> | – |
| Prop | Tür | Varsayılan |
|---|---|---|
billingAddressYour billing form, revealed when the checkbox is cleared. Its first field gets focus. | ReactNode | – |
PayButton
Also takes Button props. Children replace the automatic label.
| Prop | Tür | Varsayılan |
|---|
| Prop | Tür | Varsayılan |
|---|---|---|
methodWhat the shopper chose. card adds card, saved_card adds savedCard, bnpl adds installments, express adds express. | "card" | "saved_card" | "paypal" | "bnpl" | "apple_pay" | "google_pay" | "express" | – |
amountThe total. | Money | – |
idempotencyKeyNew for every attempt. Send it to your payment provider. | string | – |
billingSameAsShippingThe billing checkbox. | boolean | – |
| Prop | Tür | Varsayılan |
|---|---|---|
statusWhat happened. | "succeeded" | "requires_action" | "declined" | – |
codeinsufficient_funds, expired_card, incorrect_cvc, card_declined, processing_error or authentication_failed. | DeclineCode | string | – |
messageOverrides the copy for the code. | string | – |
| Tuş | Action |
|---|---|
| ↑↓ | Move between payment methods. |
| Tab | Move from the chosen method into its card fields. |
| Enter | Pay from any card field. |
| Esc | Close the bank dialog, which cancels that attempt. |
- Methods are a radio group, and each card field has a visible label, its own error message and autocomplete tokens (cc-number, cc-exp, cc-csc, cc-name) so browsers can fill them.
- A decline is announced as an alert and takes focus, so screen reader users hear what went wrong and land next to “Try another card”.
- Processing, waiting for the bank and success are announced through a polite live region. The detected brand is read with the card number field.
- The button keeps its size through every state, inputs are 16px on touch screens, and with reduced motion the reveals and icon swaps change without moving.
Şunlarla geliştirildi
Payment bloğunun yapıldığı ücretsiz HextaUI bileşenleri. Her biri tek başına yüklenir.
Kod
8 dosya, components/blocks/payment konumuna eklendi.