Stripe Elements are pre-built, customizable UI components that allow you to securely collect payment information directly within your Next.js application. They handle PCI compliance for you, meaning sensitive card details never touch your servers. This section will explore how to leverage these pre-built Elements for common payment flows.
One of the most straightforward payment flows is a one-time purchase. Stripe Elements provide ready-to-use components like CardElement for collecting credit card details, EmailElement for the customer's email, and AddressElement which can intelligently collect billing address information, often auto-populating from the card details. Integrating these significantly reduces the amount of custom UI you need to build.
import { Elements } from '@stripe/react-stripe-js';
import { loadStripe } from '@stripe/stripe-js';
import CheckoutForm from './CheckoutForm'; // Your custom form component
const stripePromise = loadStripe('YOUR_STRIPE_PUBLIC_KEY');
function MyCheckoutPage() {
return (
<Elements stripe={stripePromise}>
<CheckoutForm />
</Elements>
);
}Within your CheckoutForm component, you'll use the individual Stripe Elements. The CardElement is fundamental for card payments. It aggregates fields like card number, expiry date, and CVC into a single, secure input. You can also include PaymentElement which is a more comprehensive, all-in-one solution that supports multiple payment methods based on your Stripe account's configuration.
import { CardElement, useStripe, useElements } from '@stripe/react-stripe-js';
function CheckoutForm() {
const stripe = useStripe();
const elements = useElements();
const handleSubmit = async (event) => {
event.preventDefault();
if (!stripe || !elements) {
return;
}
const cardElement = elements.getElement(CardElement);
// ... Stripe API calls to create PaymentIntent and confirm payment ...
};
return (
<form onSubmit={handleSubmit}>
<CardElement />
<button type="submit" disabled={!stripe}>Pay</button>
</form>
);
}For more complex scenarios, such as subscriptions or recurring payments, Stripe Elements can be adapted. While the core CardElement remains the same for collecting initial payment details, the backend logic will involve creating a Customer and attaching a PaymentMethod to them. Subsequent payments can then be charged using this saved PaymentMethod, often without needing to re-prompt the user for card details if they've given consent.
graph TD
A[Customer Initiates Payment] --> B{Stripe Elements Collect Card Details};
B --> C[Client-side Tokenization/PaymentMethod Creation];
C --> D[Next.js Backend Creates PaymentIntent/Customer];
D --> E{Stripe Processes Payment};
E -- Success --> F[Order Confirmation to Customer];
E -- Failure --> G[Error Message to Customer];
Beyond basic card payments, Stripe Elements support a wide array of alternative payment methods like SEPA Direct Debit, iDEAL, Bancontact, and more, all through a unified integration. The PaymentElement is particularly powerful here, dynamically displaying the appropriate fields for the selected payment method. This broadens your reach and caters to diverse customer preferences without requiring extensive custom development for each method.