Agent skill
stripe-api-integration
Integrate Stripe payment processing including customers, payment intents, subscriptions, webhooks. Use when implementing payments, working with Stripe API, or when user mentions Stripe, payments, subscriptions, or billing.
Install this agent skill to your Project
npx add-skill https://github.com/majiayu000/claude-skill-registry/tree/main/skills/other/other/stripe-api-integration
SKILL.md
Stripe API Integration
Integrate Stripe payment processing into applications with customers, payments, subscriptions, and webhooks.
When to Use
- Implementing payment processing
- Creating subscription billing
- Managing customer accounts
- Handling payment webhooks
- Testing payment flows
Prerequisites
- Stripe account: Sign up at https://stripe.com
- API keys: Get from Stripe Dashboard → Developers → API keys
- Use test keys (pk_test_..., sk_test_...) for development
- Python library: Install Stripe SDK
bash
pip install stripe
Quick Start
1. Initialize Stripe
import stripe
# Set your secret key
stripe.api_key = "sk_test_..." # Use environment variable in production
# Test connection
try:
account = stripe.Account.retrieve()
print(f"Connected to Stripe account: {account.id}")
except stripe.error.AuthenticationError:
print("Invalid API key")
2. Create a Customer
customer = stripe.Customer.create(
email="[email protected]",
name="John Doe",
description="Customer for testing"
)
print(f"Created customer: {customer.id}")
3. Create a Payment Intent
payment_intent = stripe.PaymentIntent.create(
amount=2000, # Amount in cents ($20.00)
currency="usd",
customer=customer.id,
payment_method_types=["card"],
description="Example payment"
)
print(f"Payment Intent: {payment_intent.id}")
print(f"Client Secret: {payment_intent.client_secret}")
# Send client_secret to frontend for payment confirmation
Common Operations
Customer Management
Create customer:
customer = stripe.Customer.create(
email="[email protected]",
name="Jane Smith",
metadata={"user_id": "12345"} # Your internal ID
)
Retrieve customer:
customer = stripe.Customer.retrieve("cus_ABC123")
Update customer:
stripe.Customer.modify(
"cus_ABC123",
email="[email protected]",
metadata={"tier": "premium"}
)
List customers:
customers = stripe.Customer.list(limit=10)
for customer in customers.auto_paging_iter():
print(customer.email)
Payment Processing
One-time payment (full flow):
# 1. Create payment intent
payment_intent = stripe.PaymentIntent.create(
amount=5000, # $50.00
currency="usd",
customer="cus_ABC123",
payment_method_types=["card"]
)
# 2. Send client_secret to frontend
client_secret = payment_intent.client_secret
# 3. Frontend confirms with Stripe.js
# (This happens in JavaScript on the frontend)
# 4. Check payment status (after confirmation)
intent = stripe.PaymentIntent.retrieve(payment_intent.id)
if intent.status == "succeeded":
print("Payment successful!")
Charge a saved card:
# If customer has default payment method
payment_intent = stripe.PaymentIntent.create(
amount=1000,
currency="usd",
customer="cus_ABC123",
payment_method="pm_card_visa", # Payment method ID
confirm=True, # Immediately attempt to charge
return_url="https://example.com/return"
)
Subscription Management
Create subscription:
subscription = stripe.Subscription.create(
customer="cus_ABC123",
items=[{"price": "price_ABC123"}], # Price ID from dashboard
payment_behavior="default_incomplete",
expand=["latest_invoice.payment_intent"]
)
# Send client_secret to frontend for payment confirmation
client_secret = subscription.latest_invoice.payment_intent.client_secret
Cancel subscription:
# Cancel at end of period
stripe.Subscription.modify(
"sub_ABC123",
cancel_at_period_end=True
)
# Cancel immediately
stripe.Subscription.delete("sub_ABC123")
Update subscription:
# Change plan
stripe.Subscription.modify(
"sub_ABC123",
items=[{
"id": subscription_item_id,
"price": "price_NEW123" # New price ID
}]
)
Webhook Handling
Setup endpoint:
from flask import Flask, request
import stripe
app = Flask(__name__)
endpoint_secret = "whsec_..." # From Stripe Dashboard
@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, endpoint_secret
)
except ValueError:
return "Invalid payload", 400
except stripe.error.SignatureVerificationError:
return "Invalid signature", 400
# Handle the event
if event.type == "payment_intent.succeeded":
payment_intent = event.data.object
print(f"Payment succeeded: {payment_intent.id}")
# Update your database, send confirmation email, etc.
elif event.type == "customer.subscription.deleted":
subscription = event.data.object
print(f"Subscription canceled: {subscription.id}")
# Revoke access, update user's subscription status
return {"status": "success"}
Important webhook events:
payment_intent.succeeded- Payment completedpayment_intent.payment_failed- Payment failedcustomer.subscription.created- New subscriptioncustomer.subscription.updated- Subscription changedcustomer.subscription.deleted- Subscription canceledinvoice.payment_failed- Subscription payment failed
For complete webhook event reference, see references/WEBHOOK_EVENTS.md.
Error Handling
Stripe errors should be caught and handled appropriately:
import stripe
try:
payment_intent = stripe.PaymentIntent.create(
amount=1000,
currency="usd",
customer="cus_ABC123"
)
except stripe.error.CardError as e:
# Card was declined
print(f"Card error: {e.user_message}")
except stripe.error.RateLimitError:
# Too many requests
print("Rate limit exceeded, retry later")
except stripe.error.InvalidRequestError as e:
# Invalid parameters
print(f"Invalid request: {e}")
except stripe.error.AuthenticationError:
# Invalid API key
print("Authentication failed")
except stripe.error.APIConnectionError:
# Network issue
print("Network error, retry")
except stripe.error.StripeError as e:
# Generic Stripe error
print(f"Stripe error: {e}")
except Exception as e:
# Non-Stripe error
print(f"Unexpected error: {e}")
For complete error types and handling, see references/ERROR_HANDLING.md.
Testing
Use Test Cards
Stripe provides test card numbers:
# Success
# Card: 4242 4242 4242 4242
# Exp: Any future date, CVC: Any 3 digits
# Decline
# Card: 4000 0000 0000 0002
# Requires authentication (3D Secure)
# Card: 4000 0027 6000 3184
Test Mode
Always use test keys for development:
stripe.api_key = "sk_test_..." # Test secret key
Test mode data is completely separate from live mode.
Test Webhooks Locally
Use Stripe CLI to forward webhooks to localhost:
# Install Stripe CLI
brew install stripe/stripe-cli/stripe
# Login
stripe login
# Forward webhooks to local server
stripe listen --forward-to localhost:5000/webhook
Best Practices
-
Use environment variables for API keys:
pythonimport os stripe.api_key = os.environ.get("STRIPE_SECRET_KEY") -
Store customer IDs in your database to link Stripe customers to your users
-
Use idempotency keys for critical operations:
pythonstripe.PaymentIntent.create( amount=1000, currency="usd", idempotency_key="order_12345" # Prevents duplicate charges ) -
Verify webhook signatures to ensure requests are from Stripe
-
Handle errors gracefully and provide user-friendly messages
-
Use test mode extensively before going live
-
Implement proper logging for payment operations
-
Store metadata to link Stripe objects to your system:
pythonmetadata={"order_id": "12345", "user_id": "67890"}
For comprehensive best practices, see references/BEST_PRACTICES.md.
Troubleshooting
Authentication Failed
Problem: stripe.error.AuthenticationError
Solution:
- Verify API key is correct
- Ensure using secret key (sk_...) not publishable key (pk_...)
- Check key matches environment (test vs live)
Payment Intent Requires Action
Problem: Payment intent status is requires_action
Solution:
- Customer needs to complete authentication (3D Secure)
- Send
client_secretto frontend for confirmation - Use Stripe.js to handle authentication flow
Invalid Request
Problem: stripe.error.InvalidRequestError
Solution:
- Check API parameters match documentation
- Verify resource IDs are valid
- Ensure required fields are provided
Rate Limit Exceeded
Problem: stripe.error.RateLimitError
Solution:
- Implement exponential backoff
- Reduce request frequency
- Contact Stripe to increase rate limits if needed
For more troubleshooting, see references/TROUBLESHOOTING.md.
Additional Resources
- Complete API reference:
references/API_REFERENCE.md - Webhook events guide:
references/WEBHOOK_EVENTS.md - Error handling patterns:
references/ERROR_HANDLING.md - Testing strategies:
references/TESTING.md - Best practices:
references/BEST_PRACTICES.md - Troubleshooting guide:
references/TROUBLESHOOTING.md
Official Documentation
- Stripe API Docs: https://stripe.com/docs/api
- Python Library: https://stripe.com/docs/api/python
- Testing: https://stripe.com/docs/testing
- Webhooks: https://stripe.com/docs/webhooks
Recommended Agent Skills
Expand your agent's capabilities with these related and highly-rated skills.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
agent-ops-spec
Manage specification documents in .agent/specs/. Use when user provides requirements, acceptance criteria, or feature descriptions that need to be tracked and validated against implementation.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-testing
Test strategy, execution, and coverage analysis. Use when designing tests, running test suites, or analyzing test results beyond baseline checks.
agent-ops-state
Maintain .agent state files. Use at session start, after meaningful steps, and before concluding: read/update constitution/memory/focus/issues/baseline consistently.
Didn't find tool you were looking for?