Integrating Stripe Payments in Flask

In today’s digital age, online payment processing is a crucial aspect of many web applications. Stripe is a popular and powerful payment gateway that allows businesses to accept payments securely and easily. Flask, on the other hand, is a lightweight and flexible web framework in Python. Combining Stripe with Flask enables developers to quickly implement payment functionality in their web applications. This blog post will guide you through the process of integrating Stripe payments in a Flask application. We’ll cover the core concepts, typical usage scenarios, common pitfalls, and best practices to help you develop a deep understanding and apply this integration effectively in real - world situations.

Table of Contents

  1. Core Concepts
  2. Setting Up the Flask Application
  3. Integrating Stripe
  4. Typical Usage Scenarios
  5. Common Pitfalls
  6. Best Practices
  7. Conclusion
  8. References

Core Concepts

Stripe

  • Payment Intents: A PaymentIntent guides you through the process of collecting a payment from a customer. It tracks the lifecycle of the payment, from creation to capture, and helps handle different payment methods and scenarios such as 3D Secure authentication.
  • API Keys: Stripe provides two types of API keys: publishable keys and secret keys. The publishable key is used on the client - side to interact with Stripe.js and create payment elements. The secret key is used on the server - side to communicate with the Stripe API and perform actions like creating PaymentIntents.

Flask

  • Routes: Flask uses routes to map URLs to Python functions. When a user visits a specific URL, the corresponding function is executed.
  • Request and Response: The request object in Flask is used to access incoming data such as form data or JSON payloads. The response is what the server sends back to the client, which can be HTML, JSON, or other types of data.

Setting Up the Flask Application

First, make sure you have Flask installed. If not, you can install it using pip:

pip install flask

Here is a basic Flask application structure:

from flask import Flask

app = Flask(__name__)

@app.route('/')
def index():
    return "Welcome to the Flask - Stripe integration app!"

if __name__ == '__main__':
    app.run(debug=True)

In this code:

  • We import the Flask class from the flask module.
  • Create an instance of the Flask class named app.
  • Define a route for the root URL (/). When a user visits this URL, the index function is called, which returns a simple welcome message.
  • Finally, we run the application in debug mode if the script is executed directly.

Integrating Stripe

Installing the Stripe Python Library

Install the Stripe Python library using pip:

pip install stripe

Server - Side Integration

import stripe
from flask import Flask, request, jsonify

# Set your Stripe API keys
stripe.api_key = "YOUR_SECRET_KEY"

app = Flask(__name__)

@app.route('/create-payment-intent', methods=['POST'])
def create_payment_intent():
    try:
        data = request.get_json()
        amount = data.get('amount')
        currency = data.get('currency', 'usd')

        # Create a PaymentIntent
        intent = stripe.PaymentIntent.create(
            amount=amount,
            currency=currency
        )

        return jsonify({
            'clientSecret': intent.client_secret
        })
    except Exception as e:
        return jsonify(error=str(e)), 403

if __name__ == '__main__':
    app.run(debug=True)

In this code:

  • We import the stripe library and necessary Flask modules.
  • Set the Stripe secret key.
  • Define a route /create - payment - intent that accepts POST requests.
  • Inside the route function, we retrieve the amount and currency from the JSON data sent by the client.
  • Create a PaymentIntent using the Stripe API.
  • Return the client_secret of the PaymentIntent to the client in JSON format.

Client - Side Integration

We’ll use Stripe.js to handle the payment form on the client - side. Here is an example HTML file:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
    <title>Stripe Payment</title>
    <script src="https://js.stripe.com/v3/"></script>
</head>

<body>
    <form id="payment - form">
        <div id="payment - element"></div>
        <button id="submit">Pay</button>
    </form>

    <script>
        const stripe = Stripe('YOUR_PUBLISHABLE_KEY');
        const elements = stripe.elements();

        const paymentElement = elements.create('payment');
        paymentElement.mount('#payment - element');

        const form = document.getElementById('payment - form');
        form.addEventListener('submit', async (event) => {
            event.preventDefault();

            const { clientSecret } = await fetch('/create - payment - intent', {
                method: 'POST',
                headers: {
                    'Content - Type': 'application/json'
                },
                body: JSON.stringify({ amount: 1000, currency: 'usd' })
            }).then((r) => r.json());

            const { error } = await stripe.confirmPayment({
                elements,
                clientSecret,
                confirmParams: {
                    return_url: 'https://your - website.com/success'
                }
            });

            if (error) {
                console.log(error.message);
            } else {
                console.log('Payment successful!');
            }
        });
    </script>
</body>

</html>

In this HTML code:

  • We include the Stripe.js library.
  • Create a Stripe instance using the publishable key.
  • Create a PaymentElement and mount it to the payment - element div.
  • When the form is submitted, we make a POST request to the /create - payment - intent route on the server to get the client_secret.
  • Then we use the client_secret to confirm the payment using stripe.confirmPayment.

Typical Usage Scenarios

  • E - commerce Websites: Accept payments for products or services. Customers can add items to a cart, and when they proceed to checkout, the application uses Stripe to process the payment.
  • Subscription - Based Services: Charge customers on a recurring basis. Stripe provides features for managing subscriptions, such as creating plans, handling trial periods, and renewals.
  • Donation Platforms: Allow users to make one - time or recurring donations. The integration makes it easy for donors to contribute securely.

Common Pitfalls

  • Exposing Secret Keys: Never expose your Stripe secret key on the client - side. The secret key should only be used on the server - side to communicate with the Stripe API. If the secret key is compromised, attackers can perform unauthorized actions on your Stripe account.
  • Incorrect Amount or Currency: Make sure the amount and currency values are correctly set on both the client - side and server - side. Incorrect values can lead to payment failures or incorrect charges.
  • Lack of Error Handling: Failing to handle errors properly on both the client - side and server - side can result in a poor user experience. For example, if a PaymentIntent creation fails on the server, the client should be informed with a meaningful error message.

Best Practices

  • Use Webhooks: Stripe webhooks allow your application to receive real - time notifications about payment events such as successful payments, refunds, or disputes. Use webhooks to update your application’s database and perform other necessary actions.
  • Test in a Sandbox Environment: Stripe provides a sandbox environment where you can test your payment integration without using real money. This helps you catch any issues before going live.
  • Keep API Keys Secure: Store your Stripe API keys securely, preferably using environment variables. In a Flask application, you can use the os module to access environment variables:
import os
stripe.api_key = os.getenv('STRIPE_SECRET_KEY')

Conclusion

Integrating Stripe payments in a Flask application is a powerful way to add payment functionality to your web projects. By understanding the core concepts, following the steps for integration, and being aware of common pitfalls and best practices, you can create a secure and reliable payment system. Whether you’re building an e - commerce site, a subscription service, or a donation platform, this integration can help you accept payments smoothly and efficiently.

References