Stripe Payment Element — Building Secure Payment Forms with Pre-Built UI
In this tutorial, you will learn about Stripe Payment Element. We cover key concepts, practical examples, and best practices to help you master this topic.
The Stripe Payment Element is a pre-built UI component that renders a dynamic payment form supporting cards, wallets, bank transfers, and local payment methods based on the customer's location and device.
What You'll Learn
- How to set up Stripe Payment Element
- How to customize the payment form appearance
- How to handle payment confirmation and errors
Why It Matters
Building a custom payment form requires PCI SAQ Compliance, handling multiple payment methods, and managing complex validation. The Payment Element handles all of this automatically, reducing integration time from weeks to hours while maintaining full Stripe compliance.
Real-World Use
DodaTech's checkout page uses Payment Element with Apple Pay, Google Pay, and card support. The element automatically shows Apple Pay on Safari iOS devices, Google Pay on Android Chrome, and a card form on desktop. No code changes were needed when Stripe added SEPA support.
import stripe
from flask import Flask, render_template, jsonify, request
stripe.api_key = 'sk_test_...'
@app.route('/create-payment-intent', methods=['POST'])
def create_payment_intent():
intent = stripe.PaymentIntent.create(
amount=2999, # $29.99
currency='usd',
automatic_payment_methods={'enabled': True}
)
return jsonify({'clientSecret': intent.client_secret})
// Client-side code
const stripe = Stripe('pk_test_...');
async function initialize() {
const response = await fetch('/create-payment-intent', { method: 'POST' });
const { clientSecret } = await response.json();
const appearance = {
theme: 'stripe',
variables: {
colorPrimary: '#2563eb',
colorBackground: '#ffffff',
colorText: '#1f2937',
borderRadius: '8px'
}
};
const elements = stripe.elements({ appearance, clientSecret });
const paymentElement = elements.create('payment');
paymentElement.mount('#payment-element');
}
async function handleSubmit(e) {
e.preventDefault();
const { error } = await stripe.confirmPayment({
elements,
confirmParams: {
return_url: 'https://dodatech.com/checkout/complete'
}
});
if (error) {
showError(error.message);
}
}
Custom Fonts and Themes
const appearance = {
theme: 'night',
labels: 'floating',
variables: {
fontFamily: '"Inter", system-ui, sans-serif',
colorPrimary: '#2563eb',
colorBackground: '#1f2937',
colorText: '#f9fafb',
borderRadius: '8px'
},
rules: {
'.Label': { fontWeight: '600' },
'.Input': { border: '1px solid #374151' },
'.Tab': { border: '1px solid #374151' }
}
};
const elements = stripe.elements({ appearance, clientSecret });
Common Mistakes
1. Not Using Automatic Payment Methods
Manual payment method configuration misses newly supported methods. Enable automatic_payment_methods for future-proof integration.
2. Storing clientSecret on the Client
The clientSecret should be fetched from your server at checkout time, not embedded in JavaScript bundles.
3. Ignoring the return_url
After payment confirmation, the customer is redirected to the return_url. This page must handle both successful and failed payments.
4. Not Handling Payment Method Changes
When the customer changes payment methods, re-fetch the clientSecret if the amount changes.
5. Skipping Loading States
The Payment Element takes time to load. Show a loading state while elements.mount() is pending.
Practice Questions
- What is the Stripe Payment Element?
- How does automatic_payment_methods work?
- How do you customize the Payment Element appearance?
- What happens after confirmPayment succeeds?
- How do you handle payment errors?
Answers
- A pre-built UI component for secure payment forms. 2. It dynamically shows available payment methods based on the customer. 3. Using the appearance object with theme, variables, and rules. 4. The customer is redirected to the return_url. 5. The error object from confirmPayment contains the error message.
Challenge
Build a complete payment page with Payment Element that supports cards and wallets, handles the redirect to a confirmation page, displays payment success or failure, and works on mobile and desktop.
FAQ
Mini Project
Build a subscription checkout page that: creates a PaymentIntent or SetupIntent on the server, renders Payment Element on the client with custom branding, handles the post-payment redirect, and displays a confirmation page with subscription details.
What's Next
- Learn about Stripe Embedded Checkout for quick integration
- Explore SetupIntent for saving payment methods
- Continue to subscription management with trials and proration
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro