Stripe Checkout Session: Hosted Payment Pages for Quick Integration
In this tutorial, you will learn about Stripe Checkout Session: Hosted Payment Pages for Quick Integration. We cover key concepts, practical examples, and best practices to help you master this topic.
Stripe Checkout Session creates a hosted payment page that handles the entire checkout flow — card entry, 3D Secure, address collection, and redirect back to your app.
What You'll Learn
How to create Checkout Sessions for one-time and subscription payments, customize branding, handle success/cancel URLs, collect customer information, and fulfill orders via Webhook.
Why It Matters
Checkout Sessions eliminate the need to build and maintain a payment form UI. DodaTech uses Checkout for all customer-facing payments, reducing frontend payment code by 80%.
Real-World Use
A customer clicks "Subscribe" on dodatech.com/pricing. The server creates a Checkout Session, redirects the customer to checkout.stripe.com, they enter card details, and are redirected back on completion.
flowchart LR
A["User Clicks\nSubscribe"] --> B["Server Creates\nCheckout Session"]
B --> C["Redirect to\ncheckout.stripe.com"]
C --> D["Customer\nPays"]
D --> E["Redirect Back\nSuccess URL"]
D --> F["Webhook\ncheckout.session.completed"]
F --> G["Fulfill\nOrder"]
style A fill:#dbeafe,stroke:#2563eb
style B fill:#6772e5,color:#fff
style C fill:#fef3c7,stroke:#d97706
style F fill:#bbf7d0,stroke:#16a34a
Creating a One-Time Payment Session
import stripe
stripe.api_key = os.environ["STRIPE_SECRET_KEY"]
def create_checkout_session_one_time(price_id, customer_email):
session = stripe.checkout.Session.create(
success_url="https://dodatech.com/success?session_id={CHECKOUT_SESSION_ID}",
cancel_url="https://dodatech.com/pricing",
mode="payment",
line_items=[{
"price": price_id,
"quantity": 1
}],
customer_email=customer_email,
metadata={"source": "pricing_page"}
)
print(f"Checkout Session: {session.id}")
print(f"URL: {session.url}")
print(f"Mode: {session.mode}")
return session.url
url = create_checkout_session_one_time("price_123abc", "alice@example.com")
# Expected output:
# Checkout Session: cs_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
# URL: https://checkout.stripe.com/c/pay/cs_test_a1b2c...
Subscription Checkout
def create_checkout_session_subscription(price_id, customer_email):
session = stripe.checkout.Session.create(
success_url="https://dodatech.com/success?session_id={CHECKOUT_SESSION_ID}",
cancel_url="https://dodatech.com/pricing",
mode="subscription",
line_items=[{
"price": price_id,
"quantity": 1
}],
customer_email=customer_email,
subscription_data={
"metadata": {"plan_tier": "pro"},
"trial_period_days": 14
},
allow_promotion_codes=True,
automatic_tax={"enabled": True}
)
print(f"Subscription checkout: {session.id}")
print(f"Free trial: 14 days")
return session.url
Custom Branding
# Configure in Stripe Dashboard:
# Settings > Branding
# - Icon: 128x128 PNG
# - Logo: up to 512px wide
# - Primary color: hex code
# - Background color
# These apply automatically to all Checkout Sessions
# No code changes needed
session = stripe.checkout.Session.create(
success_url="https://dodatech.com/success",
cancel_url="https://dodatech.com/pricing",
mode="subscription",
line_items=[{"price": "price_123", "quantity": 1}],
# Stripe applies your branding automagically
)
Customer Information Collection
def create_session_with_customer_info(price_id):
session = stripe.checkout.Session.create(
success_url="https://dodatech.com/success",
cancel_url="https://dodatech.com/pricing",
mode="subscription",
line_items=[{"price": price_id, "quantity": 1}],
phone_number_collection={"enabled": True},
shipping_address_collection={
"allowed_countries": ["US", "CA", "GB", "DE", "FR"]
},
billing_address_collection="required",
metadata={"source": "enterprise_page"}
)
print(f"Session with address collection: {session.id}")
return session
Common Mistakes
1. Hardcoding Success/Cancel URLs
Always include {CHECKOUT_SESSION_ID} in the success URL. Stripe replaces it with the session ID, letting your success page verify and display order details.
2. Using mode="payment" for Subscriptions
Setting mode="payment" creates a one-time charge, not a subscription. Use mode="subscription" with recurring prices.
3. Forgetting to Listen for Webhooks
The redirect might not reach your app (ad blocker, browser crash). Always use webhooks to fulfill orders, not the redirect callback.
4. Not Testing the Full Flow
Test the complete flow: create session, go through checkout, verify webhook fires, check fulfillment. Don't assume it works — test each step.
5. Ignoring Payment Method Options
By default, Checkout shows all enabled methods. Limit to relevant methods with payment_method_types to reduce confusion.
Practice Questions
- What is the difference between Checkout Session and PaymentIntent?
- How do you handle order fulfillment when the customer may not return after redirect?
- What happens if the customer closes the browser during checkout?
- How do you add a trial period to a subscription?
Answers:
- Checkout Session creates a hosted payment page that returns a PaymentIntent or Subscription behind the scenes. PaymentIntent is the raw API without a UI.
- Use webhooks (
checkout.session.completed) for fulfillment. Don't rely on the success redirect. The webhook fires regardless of redirect. - The payment may still complete. Stripe sends the webhook. Your system should handle incomplete sessions gracefully.
- Set
subscription_data.trial_period_dayson the Checkout Session. The card isn't charged until the trial ends.
Challenge: Build a complete subscription checkout: create a price in Stripe Dashboard, build a Checkout Session with 14-day trial and promotion codes, redirect customer, verify webhook handling, and redirect to success page with session details.
FAQ
Mini Project
Build a complete subscription purchase flow: create a price in Stripe Dashboard, build a Checkout Session with 14-day trial, redirect customer, handle success/cancel URLs, implement webhook fulfillment for checkout.session.completed, and verify end-to-end with test cards.
What's Next
Subscriptions — manage recurring billing and subscription lifecycle.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro