usePaymentElement()
The usePaymentElement()
hook is used to control the payment form rendered by the <PaymentElementForm />
component. It provides the necessary state and methods to submit payment details to a payment provider like Stripe.
This hook must be used within a component that is a descendant of the <PaymentElementProvider />
component. It is typically used in a checkout flow that prompts a user to add a new payment method, or for adding a new payment method outside of a checkout.
Payment element components
The usePaymentElement()
hook works in conjunction with the <PaymentElementProvider />
and <PaymentElementForm />
components.
<PaymentElementProvider />
This provider component sets up the context for the payment element. It fetches all the necessary data from the payment provider (e.g., Stripe) and makes it available to its children.
- Name
checkout?
- Type
CommerceCheckoutResource
- Description
An optional checkout resource object. When provided, the payment element is scoped to the specific checkout session.
- Name
for?
- Type
'user' | 'org'
- Description
Specifies whether the payment method is being added for a user or an organization. Defaults to
'user'
.
- Name
stripeAppearance?
- Type
object
- Description
An optional object to customize the appearance of the Stripe Payment Element. This allows you to match the form's styling to your application's theme.
- Name
paymentDescription?
- Type
string
- Description
An optional description to display to the user within the payment element UI.
<PaymentElementForm />
This component renders the actual payment form from the provider (e.g., the Stripe Payment Element). It should be rendered as a child of <PaymentElementProvider />
.
- Name
fallback?
- Type
ReactNode
- Description
Optional fallback content, such as a loading skeleton, to display while the payment form is being initialized.
Parameters
The usePaymentElement()
hook does not accept any parameters. It derives its state and configuration from the nearest <PaymentElementProvider />
.
Returns
- Name
submit
- Type
() => Promise<{ data: { gateway: 'stripe'; paymentToken: string } | null; error: PaymentElementError | null}>
- Description
A function that submits the payment form data to the payment provider. It returns a promise that resolves with either a
data
object containing a payment token on success, or anerror
object on failure.
- Name
reset
- Type
() => Promise<void>
- Description
A function that resets the payment form to its initial, empty state.
- Name
isFormReady
- Type
boolean
- Description
Returns
true
when the payment form UI has been rendered and is ready for user input. This is useful for disabling a submit button until the form is interactive.
- Name
isProviderReady
- Type
boolean
- Description
Returns
true
when the underlying payment provider (e.g., Stripe.js) has been fully initialized.
- Name
provider
- Type
{ name: 'stripe' } | undefined
- Description
An object containing information about the initialized payment provider. It is
undefined
untilisProviderReady
istrue
.
Examples
The following example shows the basic structure for adding a new payment method. A parent component, <AddPaymentMethodView />
, sets up the provider and renders the form. A child component, <PaymentForm />
, uses the usePaymentElement()
hook to handle the form submission.
import { PaymentElementProvider, PaymentElementForm } from '@clerk/nextjs'
import { PaymentForm } from './PaymentForm'
import { PaymentFormSkeleton } from './PaymentFormSkeleton'
export function AddPaymentMethodView() {
// The provider configures the payment context for a user.
return (
<PaymentElementProvider for="user">
<h2>Add a new payment method</h2>
<p>Your payment details will be saved securely for future purchases.</p>
{/* The form component renders the payment UI */}
<PaymentElementForm fallback={<PaymentFormSkeleton />}>
{/* The child component handles form interaction */}
<PaymentForm />
</PaymentElementForm>
</PaymentElementProvider>
)
}
import { usePaymentElement } from '@clerk/nextjs'
import { useState } from 'react'
export function PaymentForm() {
// The hook provides the state and methods to control the form.
const { submit, isFormReady, isProviderReady } = usePaymentElement()
const [isSubmitting, setIsSubmitting] = useState(false)
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!isFormReady) {
return
}
setIsSubmitting(true)
setError(null)
const { data, error } = await submit()
// Usually a validation error from stripe that you can ignore
if (error) {
setIsSubmitting(false)
return
}
console.log('Payment token created:', data.paymentToken)
setIsSubmitting(false)
}
return (
<form onSubmit={handleSubmit}>
{/* The actual payment fields are rendered by <PaymentElementForm> */}
<button type="submit" disabled={!isFormReady || !isProviderReady || isSubmitting}>
{isSubmitting ? 'Creating token...' : 'Create token'}
</button>
</form>
)
}
Use PaymentElement in a checkout flow
Prompt users to add a new payment method during checkout
Use PaymentElement outside of a checkout flow
Add a new payment method outside of a checkout flow
Feedback
Last updated on