Learn how to integrate Stripe API with Python: set up your account, install the library, create payments, handle subscriptions, webhooks, errors, and go live securely.
Book a call with an Expert
Starting a new venture? Need to upgrade your web app? RapidDev builds application with your growth in mind.
How to Use Stripe API with Python
Step 1: Set Up a Stripe Account
Before you can use the Stripe API, you need to create a Stripe account:
Step 2: Install the Stripe Python Library
Install the Stripe Python library using pip:
pip install stripe
Step 3: Configure Your API Keys
In your Python script, import the Stripe library and configure it with your Secret Key:
import stripe
# Set your secret key
stripe.api_key = "sk_test_your_test\_key"
# Optionally set API version (recommended)
stripe.api\_version = "2023-10-16"
Always use your test keys for development and testing. Replace with live keys only in production.
Step 4: Basic Operations with Stripe API
Creating a Customer
def create\_customer(email, name):
try:
customer = stripe.Customer.create(
email=email,
name=name,
description="New customer"
)
print(f"Success: Created customer with ID: {customer.id}")
return customer
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None
# Example usage
new_customer = create_customer("[email protected]", "John Doe")
Creating a Payment Method
def create_payment_method(card_number, exp_month, exp\_year, cvc):
try:
payment\_method = stripe.PaymentMethod.create(
type="card",
card={
"number": card\_number,
"exp_month": exp_month,
"exp_year": exp_year,
"cvc": cvc,
}
)
print(f"Success: Created payment method with ID: {payment\_method.id}")
return payment\_method
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None
# Example usage with test card
payment_method = create_payment\_method(
"4242424242424242", # Test card number
12, # Expiration month
2025, # Expiration year
"123" # CVC
)
Step 5: Creating and Processing Payments
Creating a Payment Intent
def create_payment_intent(amount, currency, customer_id=None, payment_method\_id=None):
try:
params = {
"amount": amount, # Amount in cents
"currency": currency,
"payment_method_types": ["card"],
}
if customer\_id:
params["customer"] = customer\_id
if payment_method_id:
params["payment_method"] = payment_method\_id
params["confirm"] = True
params["return\_url"] = "https://yourwebsite.com/return"
payment\_intent = stripe.PaymentIntent.create(\*\*params)
print(f"Success: Created payment intent with ID: {payment\_intent.id}")
return payment\_intent
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None
# Example usage
payment_intent = create_payment\_intent(2000, "usd") # $20.00
Confirming a Payment Intent
def confirm_payment_intent(payment_intent_id, payment_method_id):
try:
payment\_intent = stripe.PaymentIntent.confirm(
payment_intent_id,
payment_method=payment_method\_id
)
if payment\_intent.status == "succeeded":
print("Payment succeeded!")
elif payment_intent.status == "requires_action":
print("Additional authentication required.")
print(f"Client secret: {payment_intent.client_secret}")
else:
print(f"Payment status: {payment\_intent.status}")
return payment\_intent
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None
# Example usage
confirmed_intent = confirm_payment_intent("pi_123456789", "pm\_987654321")
Step 6: Handling Subscriptions
Creating a Product and Price
def create_product_and_price(product_name, price\_amount, currency, interval="month"):
try:
# Create a product
product = stripe.Product.create(
name=product\_name,
description=f"{product\_name} subscription"
)
# Create a price for the product
price = stripe.Price.create(
product=product.id,
unit_amount=price_amount, # Amount in cents
currency=currency,
recurring={"interval": interval}
)
print(f"Created product {product.id} with price {price.id}")
return product, price
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None, None
# Example usage
product, price = create_product_and\_price("Premium Plan", 1999, "usd") # $19.99/month
Creating a Subscription
def create_subscription(customer_id, price\_id):
try:
subscription = stripe.Subscription.create(
customer=customer\_id,
items=[{"price": price\_id}],
payment_behavior="default_incomplete",
payment_settings={"save_default_payment_method": "on\_subscription"},
expand=["latest_invoice.payment_intent"]
)
print(f"Created subscription with ID: {subscription.id}")
client_secret = subscription.latest_invoice.payment_intent.client_secret
print(f"Client secret for payment: {client\_secret}")
return subscription
except stripe.error.StripeError as e:
print(f"Error: {e}")
return None
# Example usage
subscription = create_subscription("cus_123456789", "price\_987654321")
Step 7: Handling Webhooks
Webhooks allow Stripe to notify your application when events happen in your account.
from flask import Flask, request, jsonify
import stripe
import os
app = Flask(**name**)
stripe.api_key = "sk_test_your_test\_key"
webhook_secret = "whsec_your_webhook_secret"
@app.route('/webhook', methods=['POST'])
def webhook():
payload = request.data
sig\_header = request.headers.get('Stripe-Signature')
try:
event = stripe.Webhook.construct\_event(
payload, sig_header, webhook_secret
)
except ValueError as e:
# Invalid payload
return jsonify({'error': str(e)}), 400
except stripe.error.SignatureVerificationError as e:
# Invalid signature
return jsonify({'error': str(e)}), 400
# Handle the event
if event.type == 'payment\_intent.succeeded':
payment\_intent = event.data.object
print(f"Payment succeeded for amount {payment\_intent.amount}!")
# Fulfill the order
elif event.type == 'customer.subscription.created':
subscription = event.data.object
print(f"Subscription created: {subscription.id}")
elif event.type == 'invoice.payment\_failed':
invoice = event.data.object
print(f"Payment failed for invoice {invoice.id}")
# Notify the customer
# Add more event handlers as needed
return jsonify({'status': 'success'}), 200
if **name** == '**main**':
app.run(port=4242)
Step 8: Error Handling
Proper error handling is crucial when working with payment APIs:
def process_payment_with_error_handling(amount, currency, payment_method_id):
try:
payment\_intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
payment_method=payment_method\_id,
confirm=True
)
return payment\_intent
except stripe.error.CardError as e:
# Card was declined
err = e.error
print(f"Card error: {err.code}: {err.message}")
return {"error": err.message}
except stripe.error.RateLimitError as e:
# Too many requests made to the API too quickly
print(f"Rate limit error: {e}")
return {"error": "Rate limit exceeded, please try again later"}
except stripe.error.InvalidRequestError as e:
# Invalid parameters were supplied to Stripe's API
print(f"Invalid request error: {e}")
return {"error": "Invalid request parameters"}
except stripe.error.AuthenticationError as e:
# Authentication with Stripe's API failed
print(f"Authentication error: {e}")
return {"error": "Authentication with Stripe failed"}
except stripe.error.APIConnectionError as e:
# Network communication with Stripe failed
print(f"API connection error: {e}")
return {"error": "Network error, could not connect to Stripe"}
except stripe.error.StripeError as e:
# Generic Stripe error
print(f"Stripe error: {e}")
return {"error": "Payment processing failed"}
except Exception as e:
# Something else happened, completely unrelated to Stripe
print(f"Unexpected error: {e}")
return {"error": "An unexpected error occurred"}
# Example usage
result = process_payment_with_error_handling(2000, "usd", "pm_card_visa")
Step 9: Testing Your Integration
Stripe provides test cards and other tools to help you test your integration:
def test_different_card\_scenarios():
# Test successful payment
print("Testing successful payment...")
process_payment_with_error_handling(2000, "usd", "pm_card_visa")
# Test card declined
print("\nTesting declined card...")
process_payment_with_error_handling(2000, "usd", "pm_card_declined")
# Test insufficient funds
print("\nTesting insufficient funds...")
process_payment_with_error_handling(2000, "usd", "pm_card_insufficient\_funds")
# Test card requiring authentication
print("\nTesting card requiring authentication...")
process_payment_with_error_handling(2000, "usd", "pm_card_threeDSecure2Required")
# Run the tests
test_different_card\_scenarios()
Step 10: Going to Production
When you're ready to accept real payments:
import os
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
filename='stripe\_payments.log'
)
# Use environment variables for API keys
if os.environ.get('ENVIRONMENT') == 'production':
stripe.api_key = os.environ.get('STRIPE_LIVE_SECRET_KEY')
logging.info("Using LIVE Stripe API key")
else:
stripe.api_key = os.environ.get('STRIPE_TEST_SECRET_KEY')
logging.info("Using TEST Stripe API key")
def create_payment(amount, currency, payment_method_id, customer_email):
try:
# Log the attempt but never log full card details
logging.info(f"Processing payment for {customer\_email}, amount: {amount} {currency}")
payment\_intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
payment_method=payment_method\_id,
confirm=True,
receipt_email=customer_email
)
logging.info(f"Payment succeeded: {payment\_intent.id}")
return payment\_intent
except Exception as e:
logging.error(f"Payment failed: {str(e)}")
raise
Step 11: Advanced Features - Connect
If you're building a marketplace or platform that needs to split payments between different parties:
def create_connect_account(email, country):
try:
account = stripe.Account.create(
type="express",
country=country,
email=email,
capabilities={
"card\_payments": {"requested": True},
"transfers": {"requested": True}
}
)
print(f"Created Connect account: {account.id}")
# Generate an account link for onboarding
account\_link = stripe.AccountLink.create(
account=account.id,
refresh\_url="https://example.com/reauth",
return\_url="https://example.com/return",
type="account\_onboarding"
)
print(f"Onboarding URL: {account\_link.url}")
return account, account\_link.url
except stripe.error.StripeError as e:
print(f"Error creating Connect account: {e}")
return None, None
# Create a payment that sends a portion to a connected account
def create_split_payment(amount, currency, payment_method, platform_fee, connected_account_id):
try:
payment\_intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
payment_method=payment_method,
confirm=True,
application_fee_amount=platform\_fee,
transfer\_data={
"destination": connected_account_id
}
)
print(f"Created split payment: {payment\_intent.id}")
print(f"Amount to connected account: {amount - platform\_fee}")
print(f"Platform fee: {platform\_fee}")
return payment\_intent
except stripe.error.StripeError as e:
print(f"Error creating split payment: {e}")
return None
# Example usage
connected_account, onboarding_url = create_connect_account("[email protected]", "US")
split_payment = create_split_payment(2000, "usd", "pm_card_visa", 200, "acct_123456")
Step 12: Advanced Features - Strong Customer Authentication (SCA)
For European customers, you need to handle Strong Customer Authentication (SCA) requirements:
def create_payment_intent_with_sca_handling(amount, currency, customer_id, payment_method_id):
try:
# Create a PaymentIntent with the order amount and currency
intent = stripe.PaymentIntent.create(
amount=amount,
currency=currency,
customer=customer\_id,
payment_method=payment_method\_id,
confirmation\_method="manual",
confirm=True,
return\_url="https://example.com/return"
)
if intent.status == "requires\_action":
# Tell the client to handle the action
return {
"requires\_action": True,
"payment_intent_client_secret": intent.client_secret
}
elif intent.status == "succeeded":
# The payment didn't need any additional actions and completed!
return {"success": True}
else:
# Invalid status
return {"error": f"Invalid PaymentIntent status: {intent.status}"}
except stripe.error.CardError as e:
return {"error": e.error.message}
except Exception as e:
return {"error": str(e)}
# Frontend code (JavaScript) would handle the client\_secret and use Stripe.js
# to complete the payment authentication when required
Conclusion
You've now learned how to use the Stripe API with Python for a variety of payment scenarios. Remember to:
Refer to the official Stripe documentation (https://stripe.com/docs/api) for detailed information on all available endpoints and features.
When it comes to serving you, we sweat the little things. That’s why our work makes a big impact.