Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.
Add this skill
npx mdskills install sickn33/stripe-integrationComprehensive payment integration guide with clear patterns, security practices, and actionable code examples
1---2name: stripe-integration3description: Implement Stripe payment processing for robust, PCI-compliant payment flows including checkout, subscriptions, and webhooks. Use when integrating Stripe payments, building subscription systems, or implementing secure checkout flows.4---56# Stripe Integration78Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.910## Do not use this skill when1112- The task is unrelated to stripe integration13- You need a different domain or tool outside this scope1415## Instructions1617- Clarify goals, constraints, and required inputs.18- Apply relevant best practices and validate outcomes.19- Provide actionable steps and verification.20- If detailed examples are required, open `resources/implementation-playbook.md`.2122## Use this skill when2324- Implementing payment processing in web/mobile applications25- Setting up subscription billing systems26- Handling one-time payments and recurring charges27- Processing refunds and disputes28- Managing customer payment methods29- Implementing SCA (Strong Customer Authentication) for European payments30- Building marketplace payment flows with Stripe Connect3132## Core Concepts3334### 1. Payment Flows35**Checkout Session (Hosted)**36- Stripe-hosted payment page37- Minimal PCI compliance burden38- Fastest implementation39- Supports one-time and recurring payments4041**Payment Intents (Custom UI)**42- Full control over payment UI43- Requires Stripe.js for PCI compliance44- More complex implementation45- Better customization options4647**Setup Intents (Save Payment Methods)**48- Collect payment method without charging49- Used for subscriptions and future payments50- Requires customer confirmation5152### 2. Webhooks53**Critical Events:**54- `payment_intent.succeeded`: Payment completed55- `payment_intent.payment_failed`: Payment failed56- `customer.subscription.updated`: Subscription changed57- `customer.subscription.deleted`: Subscription canceled58- `charge.refunded`: Refund processed59- `invoice.payment_succeeded`: Subscription payment successful6061### 3. Subscriptions62**Components:**63- **Product**: What you're selling64- **Price**: How much and how often65- **Subscription**: Customer's recurring payment66- **Invoice**: Generated for each billing cycle6768### 4. Customer Management69- Create and manage customer records70- Store multiple payment methods71- Track customer metadata72- Manage billing details7374## Quick Start7576```python77import stripe7879stripe.api_key = "sk_test_..."8081# Create a checkout session82session = stripe.checkout.Session.create(83 payment_method_types=['card'],84 line_items=[{85 'price_data': {86 'currency': 'usd',87 'product_data': {88 'name': 'Premium Subscription',89 },90 'unit_amount': 2000, # $20.0091 'recurring': {92 'interval': 'month',93 },94 },95 'quantity': 1,96 }],97 mode='subscription',98 success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',99 cancel_url='https://yourdomain.com/cancel',100)101102# Redirect user to session.url103print(session.url)104```105106## Payment Implementation Patterns107108### Pattern 1: One-Time Payment (Hosted Checkout)109```python110def create_checkout_session(amount, currency='usd'):111 """Create a one-time payment checkout session."""112 try:113 session = stripe.checkout.Session.create(114 payment_method_types=['card'],115 line_items=[{116 'price_data': {117 'currency': currency,118 'product_data': {119 'name': 'Purchase',120 'images': ['https://example.com/product.jpg'],121 },122 'unit_amount': amount, # Amount in cents123 },124 'quantity': 1,125 }],126 mode='payment',127 success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',128 cancel_url='https://yourdomain.com/cancel',129 metadata={130 'order_id': 'order_123',131 'user_id': 'user_456'132 }133 )134 return session135 except stripe.error.StripeError as e:136 # Handle error137 print(f"Stripe error: {e.user_message}")138 raise139```140141### Pattern 2: Custom Payment Intent Flow142```python143def create_payment_intent(amount, currency='usd', customer_id=None):144 """Create a payment intent for custom checkout UI."""145 intent = stripe.PaymentIntent.create(146 amount=amount,147 currency=currency,148 customer=customer_id,149 automatic_payment_methods={150 'enabled': True,151 },152 metadata={153 'integration_check': 'accept_a_payment'154 }155 )156 return intent.client_secret # Send to frontend157158# Frontend (JavaScript)159"""160const stripe = Stripe('pk_test_...');161const elements = stripe.elements();162const cardElement = elements.create('card');163cardElement.mount('#card-element');164165const {error, paymentIntent} = await stripe.confirmCardPayment(166 clientSecret,167 {168 payment_method: {169 card: cardElement,170 billing_details: {171 name: 'Customer Name'172 }173 }174 }175);176177if (error) {178 // Handle error179} else if (paymentIntent.status === 'succeeded') {180 // Payment successful181}182"""183```184185### Pattern 3: Subscription Creation186```python187def create_subscription(customer_id, price_id):188 """Create a subscription for a customer."""189 try:190 subscription = stripe.Subscription.create(191 customer=customer_id,192 items=[{'price': price_id}],193 payment_behavior='default_incomplete',194 payment_settings={'save_default_payment_method': 'on_subscription'},195 expand=['latest_invoice.payment_intent'],196 )197198 return {199 'subscription_id': subscription.id,200 'client_secret': subscription.latest_invoice.payment_intent.client_secret201 }202 except stripe.error.StripeError as e:203 print(f"Subscription creation failed: {e}")204 raise205```206207### Pattern 4: Customer Portal208```python209def create_customer_portal_session(customer_id):210 """Create a portal session for customers to manage subscriptions."""211 session = stripe.billing_portal.Session.create(212 customer=customer_id,213 return_url='https://yourdomain.com/account',214 )215 return session.url # Redirect customer here216```217218## Webhook Handling219220### Secure Webhook Endpoint221```python222from flask import Flask, request223import stripe224225app = Flask(__name__)226227endpoint_secret = 'whsec_...'228229@app.route('/webhook', methods=['POST'])230def webhook():231 payload = request.data232 sig_header = request.headers.get('Stripe-Signature')233234 try:235 event = stripe.Webhook.construct_event(236 payload, sig_header, endpoint_secret237 )238 except ValueError:239 # Invalid payload240 return 'Invalid payload', 400241 except stripe.error.SignatureVerificationError:242 # Invalid signature243 return 'Invalid signature', 400244245 # Handle the event246 if event['type'] == 'payment_intent.succeeded':247 payment_intent = event['data']['object']248 handle_successful_payment(payment_intent)249 elif event['type'] == 'payment_intent.payment_failed':250 payment_intent = event['data']['object']251 handle_failed_payment(payment_intent)252 elif event['type'] == 'customer.subscription.deleted':253 subscription = event['data']['object']254 handle_subscription_canceled(subscription)255256 return 'Success', 200257258def handle_successful_payment(payment_intent):259 """Process successful payment."""260 customer_id = payment_intent.get('customer')261 amount = payment_intent['amount']262 metadata = payment_intent.get('metadata', {})263264 # Update your database265 # Send confirmation email266 # Fulfill order267 print(f"Payment succeeded: {payment_intent['id']}")268269def handle_failed_payment(payment_intent):270 """Handle failed payment."""271 error = payment_intent.get('last_payment_error', {})272 print(f"Payment failed: {error.get('message')}")273 # Notify customer274 # Update order status275276def handle_subscription_canceled(subscription):277 """Handle subscription cancellation."""278 customer_id = subscription['customer']279 # Update user access280 # Send cancellation email281 print(f"Subscription canceled: {subscription['id']}")282```283284### Webhook Best Practices285```python286import hashlib287import hmac288289def verify_webhook_signature(payload, signature, secret):290 """Manually verify webhook signature."""291 expected_sig = hmac.new(292 secret.encode('utf-8'),293 payload,294 hashlib.sha256295 ).hexdigest()296297 return hmac.compare_digest(signature, expected_sig)298299def handle_webhook_idempotently(event_id, handler):300 """Ensure webhook is processed exactly once."""301 # Check if event already processed302 if is_event_processed(event_id):303 return304305 # Process event306 try:307 handler()308 mark_event_processed(event_id)309 except Exception as e:310 log_error(e)311 # Stripe will retry failed webhooks312 raise313```314315## Customer Management316317```python318def create_customer(email, name, payment_method_id=None):319 """Create a Stripe customer."""320 customer = stripe.Customer.create(321 email=email,322 name=name,323 payment_method=payment_method_id,324 invoice_settings={325 'default_payment_method': payment_method_id326 } if payment_method_id else None,327 metadata={328 'user_id': '12345'329 }330 )331 return customer332333def attach_payment_method(customer_id, payment_method_id):334 """Attach a payment method to a customer."""335 stripe.PaymentMethod.attach(336 payment_method_id,337 customer=customer_id338 )339340 # Set as default341 stripe.Customer.modify(342 customer_id,343 invoice_settings={344 'default_payment_method': payment_method_id345 }346 )347348def list_customer_payment_methods(customer_id):349 """List all payment methods for a customer."""350 payment_methods = stripe.PaymentMethod.list(351 customer=customer_id,352 type='card'353 )354 return payment_methods.data355```356357## Refund Handling358359```python360def create_refund(payment_intent_id, amount=None, reason=None):361 """Create a refund."""362 refund_params = {363 'payment_intent': payment_intent_id364 }365366 if amount:367 refund_params['amount'] = amount # Partial refund368369 if reason:370 refund_params['reason'] = reason # 'duplicate', 'fraudulent', 'requested_by_customer'371372 refund = stripe.Refund.create(**refund_params)373 return refund374375def handle_dispute(charge_id, evidence):376 """Update dispute with evidence."""377 stripe.Dispute.modify(378 charge_id,379 evidence={380 'customer_name': evidence.get('customer_name'),381 'customer_email_address': evidence.get('customer_email'),382 'shipping_documentation': evidence.get('shipping_proof'),383 'customer_communication': evidence.get('communication'),384 }385 )386```387388## Testing389390```python391# Use test mode keys392stripe.api_key = "sk_test_..."393394# Test card numbers395TEST_CARDS = {396 'success': '4242424242424242',397 'declined': '4000000000000002',398 '3d_secure': '4000002500003155',399 'insufficient_funds': '4000000000009995'400}401402def test_payment_flow():403 """Test complete payment flow."""404 # Create test customer405 customer = stripe.Customer.create(406 email="test@example.com"407 )408409 # Create payment intent410 intent = stripe.PaymentIntent.create(411 amount=1000,412 currency='usd',413 customer=customer.id,414 payment_method_types=['card']415 )416417 # Confirm with test card418 confirmed = stripe.PaymentIntent.confirm(419 intent.id,420 payment_method='pm_card_visa' # Test payment method421 )422423 assert confirmed.status == 'succeeded'424```425426## Resources427428- **references/checkout-flows.md**: Detailed checkout implementation429- **references/webhook-handling.md**: Webhook security and processing430- **references/subscription-management.md**: Subscription lifecycle431- **references/customer-management.md**: Customer and payment method handling432- **references/invoice-generation.md**: Invoicing and billing433- **assets/stripe-client.py**: Production-ready Stripe client wrapper434- **assets/webhook-handler.py**: Complete webhook processor435- **assets/checkout-config.json**: Checkout configuration templates436437## Best Practices4384391. **Always Use Webhooks**: Don't rely solely on client-side confirmation4402. **Idempotency**: Handle webhook events idempotently4413. **Error Handling**: Gracefully handle all Stripe errors4424. **Test Mode**: Thoroughly test with test keys before production4435. **Metadata**: Use metadata to link Stripe objects to your database4446. **Monitoring**: Track payment success rates and errors4457. **PCI Compliance**: Never handle raw card data on your server4468. **SCA Ready**: Implement 3D Secure for European payments447448## Common Pitfalls449450- **Not Verifying Webhooks**: Always verify webhook signatures451- **Missing Webhook Events**: Handle all relevant webhook events452- **Hardcoded Amounts**: Use cents/smallest currency unit453- **No Retry Logic**: Implement retries for API calls454- **Ignoring Test Mode**: Test all edge cases with test cards455
Full transparency — inspect the skill content before installing.