Skip to content

Creating Checkout Session — Accept Payments with Stripe Checkout

DodaTech Updated 2026-06-28 4 min read

In this tutorial, you will learn about Creating Checkout Session. We cover key concepts, practical examples, and best practices to help you master this topic.

Stripe Checkout Session is a hosted payment page that handles the entire checkout flow, redirecting customers to Stripe's PCI-compliant page and back to your site after payment.

What You'll Learn

By the end of this lesson you will understand how to create Checkout Sessions, configure products and prices, handle payment success and cancellation, and customize the checkout experience.

Why It Matters

Building a payment form that handles cards, digital wallets, international payment methods, and PCI Compliance is extremely complex. Checkout Session handles all of this with a single API call.

Real-World Use

DodaZIP uses Checkout Sessions for all subscription payments. Users click "Subscribe" on the website, get redirected to Stripe's hosted page, enter payment details on Stripe's servers, and return to DodaZIP after payment.

flowchart LR
    U[User] --> B[Backend: Create Session]
    B --> S[Stripe: Checkout Session]
    S --> U[Redirect to Checkout]
    U --> P[Pay on Stripe Page]
    P --> SUC[/success URL]
    P --> CAN[/cancel URL]
    S --> W[Webhook: confirm]
    style S fill:#6772e5,color:#fff

Creating a Checkout Session

The server creates a Checkout Session with line items, mode, and URLs. Stripe returns a URL to redirect the customer.

import stripe
import os

stripe.api_key = os.environ.get("STRIPE_SECRET_KEY", "sk_test_placeholder")

def create_checkout_session(price_id, customer_email=None):
    session = stripe.checkout.Session.create(
        line_items=[{"price": price_id, "quantity": 1}],
        mode="payment",
        success_url="https://example.com/success?session_id={CHECKOUT_SESSION_ID}",
        cancel_url="https://example.com/cancel",
        customer_email=customer_email,
    )
    return session.url

os.environ["STRIPE_SECRET_KEY"] = "sk_test_4eC39HqLyjWDarjtT1zdp7dc"
stripe.api_key = "sk_test_placeholder"

class MockSession:
    url = "https://checkout.stripe.com/c/pay/cs_test_abc123"

stripe.checkout.Session.create = lambda **kwargs: MockSession()

url = create_checkout_session("price_1QqXxY", "alice@example.com")
print(f"Redirect customer to: {url}")

Expected output:

Redirect customer to: https://checkout.stripe.com/c/pay/cs_test_abc123

One-Time vs Recurring

Set mode to payment for one-time purchases or subscription for recurring payments.

# session_modes.py
# One-time vs subscription sessions

def create_one_time_session(price_id):
    print("Creating one-time payment session...")
    session = {
        "url": f"https://checkout.stripe.com/pay/cs_test_one_time",
        "mode": "payment",
        "amount": 1999,
        "currency": "usd"
    }
    print(f"  Mode: {session['mode']}")
    print(f"  Amount: ${session['amount'] / 100:.2f}")
    return session

def create_subscription_session(price_id):
    print("Creating subscription session...")
    session = {
        "url": f"https://checkout.stripe.com/pay/cs_test_sub",
        "mode": "subscription",
        "amount": 1999,
        "currency": "usd",
        "interval": "month"
    }
    print(f"  Mode: {session['mode']}")
    print(f"  Amount: ${session['amount'] / 100:.2f}/{session['interval']}")
    return session

create_one_time_session("price_1")
print()
create_subscription_session("price_2")

Customizing Checkout

Add custom fields, promo codes, tax IDs, and shipping address collection.

# customize_checkout.py
# Checkout Session customization

def create_customized_session():
    print("Creating customized checkout session...")
    
    session_config = {
        "line_items": [{"price": "price_1", "quantity": 1}],
        "mode": "payment",
        "success_url": "https://example.com/success",
        "cancel_url": "https://example.com/cancel",
        "customer_creation": "always",
        "payment_method_types": ["card", "ideal", "sepa_debit"],
        "shipping_address_collection": {"allowed_countries": ["US", "CA", "GB"]},
        "phone_number_collection": {"enabled": True},
        "allow_promotion_codes": True,
        "tax_id_collection": {"enabled": True},
        "custom_fields": [
            {"key": "gift_note", "label": {"type": "custom", "custom": "Gift Note"}, "type": "text"}
        ]
    }
    
    for key, value in session_config.items():
        print(f"  {key}: {value}")
    
    return "https://checkout.stripe.com/c/pay/cs_test_custom"

print(f"Session URL: {create_customized_session()}")

Common Mistakes

  1. Not using HTTPS for success/cancel URLs: Stripe requires HTTPS URLs for live mode. HTTP URLs work only in test mode.

  2. Storing price amounts instead of price IDs: Always reference Stripe Price IDs. Hardcoding amounts breaks when prices change.

  3. Forgetting to include the session_id parameter: The success URL should include CHECKOUT_SESSION_ID for post-purchase processing.

  4. Not handling the cancel case gracefully: The cancel URL should return users to your site, not leave them on Stripe's page.

  5. Setting mode incorrectly: Using mode=payment for a recurring product causes an error. Match the mode to the price type.

Practice Questions

  1. What is a Checkout Session? A Stripe-hosted payment page that handles the entire checkout flow and redirects back to your site.

  2. What is the difference between mode=payment and mode=subscription? Payment processes a one-time charge. Subscription creates a recurring payment schedule.

  3. How do you pass customer information to Checkout? Use the customer_email parameter, or create a Customer first and pass customer ID.

  4. Why does the success URL include CHECKOUT_SESSION_ID? So your frontend can notify your backend which session completed for post-purchase actions.

  5. Challenge: Create a Checkout Session for a SaaS product with a 14-day free trial, monthly subscription, and promo code support.

FAQ

Does Checkout Session handle taxes?

Yes. Enable Stripe Tax in the dashboard and Checkout automatically calculates and collects taxes.

Can I customize the Checkout appearance?

Yes. Configure branding in the Stripe dashboard under Settings > Branding.

What payment methods does Checkout support?

Credit cards, Apple Pay, Google Pay, and 40+ local payment methods based on customer location.

How does Checkout handle failed payments?

Stripe displays an error message on the Checkout page and lets the customer try a different payment method.

Can I use Checkout for mobile apps?

Yes. Stripe Checkout works on mobile browsers. For native apps, use Stripe mobile SDKs.

Mini Project

Create a Checkout Session endpoint in Python that accepts a price ID and customer email, creates the session, and returns the checkout URL.

import json

def create_checkout_endpoint(event, context):
    body = json.loads(event.get("body", "{}"))
    
    price_id = body.get("price_id")
    email = body.get("email")
    
    if not price_id:
        return {"statusCode": 400, "body": json.dumps({"error": "price_id required"})}
    
    session_url = f"https://checkout.stripe.com/pay/cs_test_{price_id}"
    
    return {
        "statusCode": 200,
        "body": json.dumps({
            "url": session_url,
            "price_id": price_id,
            "customer_email": email
        })
    }

event = {"body": json.dumps({"price_id": "price_1QqXxY", "email": "alice@example.com"})}
print(json.loads(create_checkout_endpoint(event, None)["body"]))

What's Next

Next: Payment Intents for custom payment flows.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro