python

Can You Supercharge Your FastAPI App with Stripe for Seamless Payments?

Empowering Your FastAPI with Stripe: A Seamless Payment Integration Adventure

Can You Supercharge Your FastAPI App with Stripe for Seamless Payments?

Imagine the scene: You’re sitting at your computer, coffee within reach, and you’ve got this brilliant idea for a web application. Of course, no modern app is complete without payment processing. Enter Stripe—a treasure trove for handling online payments. But how do you marry Stripe with FastAPI, your go-to for building fast and efficient web APIs? It’s not only possible but also simpler than you might think.

First things first, setting up your Stripe account is a breeze. Just hop over to Stripe’s website and sign up. You’ll find your API keys in the dashboard once you’re logged in. These keys are like the magic incantations that allow your app to talk to Stripe. During development, use the test API keys—no one wants to accidentally charge real customers while testing!

Next up, let’s get your development environment ready. Fire up your terminal and run:

pip install fastapi uvicorn python-dotenv stripe

Voila! FastAPI, Uvicorn (for running the server), and the Stripe library are installed. Your toolkit is nearly complete.

Now, it’s another good habit to stash sensitive stuff like API keys in environment variables. Create a file .env in your project’s root directory and add this:

STRIPE_PUBLISHABLE_KEY=pk_test_PUBLIC_KEY_HERE
STRIPE_SECRET_KEY=pk_test_SECRET_KEY_HERE

These will be your shields, protecting your secrets from prying eyes.

Alright, it’s time to get our hands dirty with some code. Start by setting up a basic FastAPI app and configuring it to use Stripe. Here’s a snippet to kick things off:

import os
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
import stripe

# Load environment variables
stripe.api_key = os.environ['STRIPE_SECRET_KEY']
YOUR_DOMAIN = os.environ['YOUR_DOMAIN']

# Initialize FastAPI app
app = FastAPI()

# CORS configuration
origins = ["*"]
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

With your FastAPI app initialized, let’s move to the heart of the integration—creating a checkout session. This session will transport your user to Stripe’s secure checkout page, where they can safely input their payment details.

Here’s a quick-and-dirty version of how you can set this up:

from pydantic import BaseModel

class Item(BaseModel):
    price: int
    quantity: int

@app.post("/create-checkout-session")
async def create_checkout_session(item: Item):
    try:
        checkout_session = stripe.checkout.Session.create(
            payment_method_types=["card"],
            line_items=[
                {
                    "price_data": {
                        "currency": "usd",
                        "unit_amount": item.price,
                        "product_data": {
                            "name": "Your Product",
                        },
                    },
                    "quantity": item.quantity,
                },
            ],
            mode="payment",
            success_url=YOUR_DOMAIN + "/success",
            cancel_url=YOUR_DOMAIN + "/cancel",
        )
        return {"id": checkout_session.id}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

That’s it! Your FastAPI app now knows how to create a Stripe checkout session. Now, let’s make sure everything is working by running your app. Head to your project directory and run:

uvicorn main:app --reload

This command will spin up your server on port 8000, so you can now access your app at http://127.0.0.1:8000.

But what about the frontend, you ask? Good question. You’ll need to add a button that redirects the user to Stripe’s checkout page. Here’s a small HTML snippet that does exactly that:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Payment Page</title>
</head>
<body>
    <button id="checkout-button">Checkout</button>

    <script>
        const checkoutButton = document.getElementById('checkout-button');
        checkoutButton.addEventListener('click', async () => {
            const response = await fetch('/create-checkout-session', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    price: 1000, // Price in cents
                    quantity: 1,
                }),
            });

            const session = await response.json();
            const stripe = Stripe('YOUR_PUBLISHABLE_STRIPE_API_KEY');
            stripe.redirectToCheckout({ sessionId: session.id });
        });
    </script>
</body>
</html>

Replace the placeholder YOUR_PUBLISHABLE_STRIPE_API_KEY with your actual Stripe publishable API key. And boom! Your frontend is now ready to handle payments.

But what happens after the payment? Stripe will redirect the user to your specified success or cancel URLs. You can handle these URL routes in FastAPI to display grateful or apologetic messages.

@app.get("/success")
async def success():
    return {"message": "Payment successful!"}

@app.get("/cancel")
async def cancel():
    return {"message": "Payment cancelled."}

Now, if you fancy more control over the payment process, consider setting up a custom checkout page. This approach is trickier but offers full control over design and functionality.

First, you’ll need an endpoint to create a payment intent:

@app.post("/create-payment-intent")
async def create_payment_intent(item: Item):
    try:
        payment_intent = stripe.PaymentIntent.create(
            amount=item.price * item.quantity,
            currency="usd",
            payment_method_types=["card"],
        )
        return {"client_secret": payment_intent.client_secret}
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))

On the frontend, use Stripe’s JavaScript library to confirm the payment with the client secret:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Custom Payment Page</title>
    <script src="https://js.stripe.com/v3/"></script>
</head>
<body>
    <form id="payment-form">
        <label for="card-element">Credit or debit card</label>
        <div id="card-element"></div>

        <button id="submit">Submit Payment</button>
        <p id="payment-status"></p>
    </form>

    <script>
        const stripe = Stripe('YOUR_PUBLISHABLE_STRIPE_API_KEY');
        const elements = stripe.elements();
        const cardElement = elements.create('card');
        cardElement.mount('#card-element');

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

            const response = await fetch('/create-payment-intent', {
                method: 'POST',
                headers: {
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify({
                    price: 1000,
                    quantity: 1,
                }),
            });

            const { client_secret } = await response.json();

            stripe.confirmCardPayment(client_secret, {
                payment_method: {
                    card: cardElement,
                    billing_details: {
                        name: 'Jenny Rosen',
                    },
                },
            }).then((result) => {
                if (result.error) {
                    document.getElementById('payment-status').textContent = result.error.message;
                } else {
                    if (result.paymentIntent.status === 'succeeded') {
                        document.getElementById('payment-status').textContent = 'Payment succeeded!';
                    }
                }
            });
        });
    </script>
</body>
</html>

Sure, this is just scratching the surface, but it illustrates the basic structure for a custom checkout process. Of course, you’ll need to handle errors and other edge cases more carefully in a real-world app.

The gist is that integrating Stripe with FastAPI doesn’t have to be a headache. Whether you use Stripe’s built-in checkout or create a custom flow, these steps provide a solid roadmap for getting started. So go forth, build cool stuff, and let the payments flow effortlessly!

Keywords: FastAPI, Stripe integration, online payments, web application development, FastAPI Stripe tutorial, payment processing API, Python Stripe library, create checkout session, backend development FastAPI, secure online payments



Similar Posts
Blog Image
TensorFlow vs. PyTorch: Which Framework is Your Perfect Match?

Navigating the Deep Learning Battlezone: TensorFlow vs. PyTorch in the AI Arena

Blog Image
Mastering Python Data Compression: A Comprehensive Guide to Libraries and Best Practices

Discover Python's data compression libraries: zlib, gzip, bz2, lzma, and zipfile. Learn their strengths, use cases, and code examples for efficient data storage and transmission. Optimize your projects now!

Blog Image
Could FastAPI and Celery Be Your Secret Sauce for Super Smooth Web Apps?

Celery and FastAPI: The Dynamic Duo for Efficient Background Task Management

Blog Image
Python's Secrets: Customizing and Overloading Operators with Python's __op__ Methods

Python's magic methods allow customizing operator behavior in classes. They enable addition, comparison, and exotic operations like matrix multiplication. These methods make objects behave like built-in types, enhancing flexibility and expressiveness in Python programming.

Blog Image
**Python Libraries That Accelerate Scientific Computing: NumPy, SciPy, Pandas and Dask Performance Guide**

Discover Python's powerful scientific computing libraries: NumPy, SciPy, Pandas & more. Learn efficient data analysis, visualization & machine learning tools. Master scientific Python today!

Blog Image
Building a Social Media Platform with NestJS and TypeORM

NestJS and TypeORM combine to create robust social media platforms. Key features include user authentication, posts, comments, and real-time interactions. Scalability, security, and unique user experiences are crucial for success.