Explore ProPro
Ask me anything
Ithy
Sign in

Transitioning from Stripe Checkout Sessions to Stripe Pricing Tables in Python

A Comprehensive Guide to Implementing Promo Codes and Free Trials Without Breaking Existing Code

stripe pricing table implementation screenshot
PRO
OpenAI o1

Key Takeaways

  • Utilize Stripe Pricing Tables to seamlessly integrate promo codes and free trials into your existing payment flow.
  • Embedding the Pricing Table using Stripe's JavaScript requires minimal backend changes and is easier to integrate than the Customer Portal for new subscriptions.
  • Proper setup of webhooks and backend handling ensures a smooth transition without disrupting existing functionality.

Introduction

If you're currently using stripe.checkout.Session.create with a price line item in your Python application and wish to enable features like promo codes and free trials, transitioning to a Stripe Pricing Table is an effective solution. This comprehensive guide will walk you through the step-by-step process of making this transition without breaking your existing codebase. We'll also compare embedding the Pricing Table using Stripe's JavaScript with using the Customer Portal link, helping you choose the option that integrates more seamlessly with your current setup.

Understanding Stripe Pricing Tables

Stripe Pricing Tables offer an embeddable, customizable way to display your products and pricing plans directly on your website. They handle the creation of Checkout Sessions, allowing you to offer promo codes and free trials effortlessly. By embedding a Pricing Table, you centralize your pricing options, simplify subscription management, and enhance the user experience.

Benefits of Using Pricing Tables

  • Enables promo codes and free trials without complex code changes.
  • Offers a seamless and intuitive UI for customers to select plans.
  • Minimizes backend modifications since Stripe handles Checkout Sessions.
  • Provides an out-of-the-box solution for displaying pricing options.

Step-by-Step Transition Guide

Below is a detailed roadmap to transition from stripe.checkout.Session.create to using a Stripe Pricing Table in your Python application.

Step 1: Create Products and Prices in Stripe Dashboard

Begin by setting up your products and pricing options in the Stripe Dashboard.

  1. Access the Products Section: Log in to your Stripe Dashboard and navigate to Products.
  2. Create a New Product: Click Add product and enter the details of your subscription service.
  3. Set Up Pricing: Under the pricing section, configure the price points (e.g., monthly, annual) and set up free trial periods if desired.
  4. Enable Promo Codes: Ensure that your account settings allow the use of promo codes:
    • Navigate to Billing > Coupons and promo codes.
    • Enable Allow promo codes.

Step 2: Create a Pricing Table in Stripe Dashboard

Next, create a Pricing Table that will display these products to your customers.

  1. Navigate to Pricing Tables: In the Stripe Dashboard, go to Products > Pricing tables.
  2. Create a New Pricing Table: Click Create pricing table and select the products and prices you want to include.
  3. Customize the Table: Adjust the appearance and settings of the pricing table as needed, including:
    • Setting the table's name and description.
    • Choosing the features to display for each plan.
    • Configuring payment methods and currencies.
    • Enabling promo codes and adjusting trial settings.
  4. Save the Pricing Table: Once configured, save the pricing table. Stripe will generate a unique pricing_table_id for embedding.

Step 3: Embed the Pricing Table Using Stripe's JavaScript

Embedding the Pricing Table into your frontend is straightforward and requires minimal changes to your existing code.

  1. Add the Stripe Pricing Table Script: Include the Stripe Pricing Table script in the <head> or just before the closing </body> tag of your HTML file:
    <script async src="https://js.stripe.com/v3/pricing-table.js"></script>
  2. Embed the Pricing Table Component: Insert the <stripe-pricing-table> web component where you want the pricing table to appear:
    <stripe-pricing-table
      pricing-table-id="your_pricing_table_id"
      publishable-key="your_publishable_key"
    >
    </stripe-pricing-table>
    Replace your_pricing_table_id with the ID provided by Stripe and your_publishable_key with your actual Stripe publishable API key.
  3. Optional – Pass Client Reference ID: If you need to associate the Checkout Session with a specific user ID from your system, include the client-reference-id attribute:
    <stripe-pricing-table
      pricing-table-id="your_pricing_table_id"
      publishable-key="your_publishable_key"
      client-reference-id="user_id"
    >
    </stripe-pricing-table>

Step 4: Update Backend Logic (Python)

While the Pricing Table handles Checkout Session creation, you may need to make slight adjustments to your backend to handle the new flow.

  1. Remove Direct Checkout Session Creation: Since the Pricing Table handles session creation, you can remove or comment out the code where you call stripe.checkout.Session.create in your backend.
  2. Ensure Webhook Handling is Set Up: Set up webhooks to listen for Stripe events, such as checkout.session.completed, customer.subscription.created, and invoice.payment_succeeded.

    Example using Flask:

    import stripe
    from flask import Flask, request, jsonify
    
    app = Flask(__name__)
    stripe.api_key = 'your_secret_key'
    
    @app.route('/webhook', methods=['POST'])
    def stripe_webhook():
        payload = request.get_data(as_text=True)
        sig_header = request.headers.get('Stripe-Signature')
        endpoint_secret = 'your_webhook_signing_secret'
    
        try:
            event = stripe.Webhook.construct_event(
                payload, sig_header, endpoint_secret
            )
        except ValueError as e:
            # Invalid payload
            print(e)
            return jsonify({'status': 'invalid payload'}), 400
        except stripe.error.SignatureVerificationError as e:
            # Invalid signature
            print(e)
            return jsonify({'status': 'invalid signature'}), 400
    
        # Handle the checkout.session.completed event
        if event['type'] == 'checkout.session.completed':
            session = event['data']['object']
            handle_checkout_session(session)
    
        # Other event types...
        return jsonify({'status': 'success'}), 200
    
    def handle_checkout_session(session):
        # Fulfillment logic, e.g., activate the user's subscription
        print(f"Checkout session completed: {session.id}")
        # Access client_reference_id if needed
        user_id = session.get('client_reference_id')
        # Implement your business logic here
    
    if __name__ == '__main__':
        app.run(port=4242)
  3. Implement Business Logic: In the handle_checkout_session function, implement the logic needed to fulfill the order, such as updating your database to activate the user's subscription.

Step 5: Test the Integration Thoroughly

Before deploying to production, ensure that all aspects of the new integration work as expected.

  1. Use Stripe Test Mode: Stripe provides a test environment to simulate transactions without charging real cards.
  2. Test Promo Codes and Free Trials: Verify that promo codes are applied correctly and that free trials initiate as configured.
  3. Check Webhook Events: Use the Stripe Dashboard or CLI to observe webhook event triggers and ensure your backend handles them appropriately.
  4. Validate Customer Experience: Walk through the entire customer journey to confirm a smooth and error-free process.

Comparing Pricing Tables and Customer Portal

Understanding the difference between the Pricing Table and the Customer Portal is crucial for selecting the right tool for your needs.

Stripe Pricing Table

The Pricing Table is designed for onboarding new customers, allowing them to select a subscription plan, apply promo codes, and start free trials.

  • Use Case: Display subscription options to potential customers.
  • Integration Effort: Minimal frontend changes; backend adjustments primarily involve webhook handling.
  • Features Supported: Promo codes, free trials, multiple pricing options.

Stripe Customer Portal

The Customer Portal allows existing customers to manage their subscriptions, including upgrading, downgrading, or canceling their plans.

  • Use Case: Provide account management capabilities to existing subscribers.
  • Integration Effort: Requires generating customer-specific portal links and handling redirects.
  • Features Supported: Subscription management, payment method updates, invoice viewing.

Comparison Table

Feature Pricing Table Customer Portal
Onboarding New Customers Yes No
Managing Existing Subscriptions No Yes
Enabling Promo Codes Yes Yes
Free Trials Support Yes Yes
Integration Complexity Low Moderate
Customization of UI Limited (via Stripe Dashboard) Limited (via Stripe Dashboard)

Which Integrates Easier?

For your specific need of transitioning from stripe.checkout.Session.create to a solution that supports promo codes and free trials for new customers, embedding the Pricing Table is the easier and more appropriate choice. It requires minimal changes to your existing codebase and aligns with your current workflow.

Implementing the Customer Portal (Optional)

If you also want to provide existing customers with the ability to manage their subscriptions, consider integrating the Stripe Customer Portal.

Step 1: Enable the Customer Portal in Stripe Dashboard

  1. Navigate to Billing Settings: In the Stripe Dashboard, go to Settings > Billing > Customer Portal.
  2. Configure Portal Settings: Customize the options available to customers, such as allowing plan upgrades, downgrades, and cancellations.

Step 2: Generate Customer Portal Links in Backend

To redirect a customer to the portal, generate a session link in your Python backend.

import stripe

# Set your secret key
stripe.api_key = 'your_secret_key'

def create_customer_portal_session(customer_id, return_url):
    session = stripe.billing_portal.Session.create(
        customer=customer_id,
        return_url=return_url
    )
    return session.url

# Example usage
customer_id = 'cus_123456789'
return_url = 'https://your-website.com/account'
portal_url = create_customer_portal_session(customer_id, return_url)

# Redirect the customer to portal_url

Step 3: Implement Frontend Redirect

In your frontend, provide a button or link that, when clicked, calls your backend to generate the portal link and then redirects the customer.

<button onclick="redirectToCustomerPortal()">Manage Subscription</button>

<script>
function redirectToCustomerPortal() {
  fetch('/create-portal-session', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({customer_id: 'cus_123456789'})
  })
  .then(response => response.json())
  .then(data => {
    window.location.href = data.url;
  })
  .catch(error => console.error('Error:', error));
}
</script>

Ensure that the /create-portal-session endpoint in your backend calls the create_customer_portal_session function and returns the generated URL.

Ensuring a Smooth Transition

To prevent any disruptions to your existing users and processes, follow these best practices:

Maintain Existing Workflows During Transition

  • Gradually introduce the Pricing Table while keeping the existing stripe.checkout.Session.create flow operational until fully tested.
  • Inform existing users of any changes to the subscription process to manage expectations.

Monitor for Errors and Exceptions

  • Implement logging in your backend to capture any exceptions during webhook processing.
  • Set up alerts for failed payments or subscription creation issues.

Update Documentation and Customer Support

  • Ensure internal documentation reflects the new payment flow and processes.
  • Train customer support teams on the new features and how to assist users with promo codes and trials.

Conclusion

Transitioning from using stripe.checkout.Session.create with a price line item to leveraging Stripe Pricing Tables in your Python application is a strategic move to enhance your payment system with promo codes and free trials. By embedding the Pricing Table using Stripe's JavaScript, you minimize changes to your backend code and provide a seamless user experience. While the Customer Portal is a valuable tool for subscription management, the Pricing Table integrates more easily into your existing code for onboarding new customers. Thorough testing and careful implementation will ensure a smooth transition without disrupting your current operations.

References

  • Stripe Docs: Embeddable Pricing Table
  • Stripe Docs: Subscriptions with Checkout
  • Stripe Docs: Customer Portal
  • Stripe Docs: Setting Up Webhooks
  • Stripe API Reference: Checkout Sessions

Last updated January 24, 2025

AI-assisted research. Sources, methodology and corrections · Source-checked guides and tools · Explore published answers

Ask a follow-up