Claude Cursor Skill

stripe-integration

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.

LLM Mart · 0 points · 12 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download wshobson-agents-plugins_payment-processing_skills_stripe-integration-554237f.zip · 4 KB
Part of wshobson/agents — 170 skills

Install

skills CLI npx skills add https://github.com/wshobson/agents/tree/main/plugins/payment-processing/skills/stripe-integration
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install wshobson-agents@llmmart
Git git clone https://github.com/wshobson/agents.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole wshobson/agents collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

Stripe Integration

Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.

When to Use This Skill

  • Implementing payment processing in web/mobile applications
  • Setting up subscription billing systems
  • Handling one-time payments and recurring charges
  • Processing refunds and disputes
  • Managing customer payment methods
  • Implementing SCA (Strong Customer Authentication) for European payments
  • Building marketplace payment flows with Stripe Connect

Core Concepts

1. Payment Flows

Checkout Sessions

  • Recommended for most integrations
  • Supports all UI paths:
    • Stripe-hosted checkout page
    • Embedded checkout form
    • Custom UI with Elements (Payment Element, Express Checkout Element) using ui_mode='custom'
  • Provides built-in checkout capabilities (line items, discounts, tax, shipping, address collection, saved payment methods, and checkout lifecycle events)
  • Lower integration and maintenance burden than Payment Intents

Payment Intents (Bespoke control)

  • You calculate the final amount with taxes, discounts, subscriptions, and currency conversion yourself.
  • More complex implementation and long-term maintenance burden
  • Requires Stripe.js for PCI compliance

Setup Intents (Save Payment Methods)

  • Collect payment method without charging
  • Used for subscriptions and future payments
  • Requires customer confirmation

2. Webhooks

Critical Events:

  • payment_intent.succeeded: Payment completed
  • payment_intent.payment_failed: Payment failed
  • customer.subscription.updated: Subscription changed
  • customer.subscription.deleted: Subscription canceled
  • charge.refunded: Refund processed
  • invoice.payment_succeeded: Subscription payment successful

3. Subscriptions

Components:

  • Product: What you're selling
  • Price: How much and how often
  • Subscription: Customer's recurring payment
  • Invoice: Generated for each billing cycle

4. Customer Management

  • Create and manage customer records
  • Store multiple payment methods
  • Track customer metadata
  • Manage billing details

Quick Start

import stripe

stripe.api_key = "sk_test_..."

# Create a checkout session
session = stripe.checkout.Session.create(
    line_items=[{
        'price_data': {
            'currency': 'usd',
            'product_data': {
                'name': 'Premium Subscription',
            },
            'unit_amount': 2000,  # $20.00
            'recurring': {
                'interval': 'month',
            },
        },
        'quantity': 1,
    }],
    mode='subscription',
    success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',
    cancel_url='https://yourdomain.com/cancel'
)

# Redirect user to session.url
print(session.url)

Detailed patterns and worked examples

Detailed pattern documentation lives in references/details.md. Read that file when the navigation tier above is insufficient.

Testing

# Use test mode keys
stripe.api_key = "sk_test_..."

# Test card numbers
TEST_CARDS = {
    'success': '4242424242424242',
    'declined': '4000000000000002',
    '3d_secure': '4000002500003155',
    'insufficient_funds': '4000000000009995'
}

def test_payment_flow():
    """Test complete payment flow."""
    # Create test customer
    customer = stripe.Customer.create(
        email="test@example.com"
    )

    # Create payment intent
    intent = stripe.PaymentIntent.create(
        amount=1000,
        automatic_payment_methods={
            'enabled': True
        },
        currency='usd',
        customer=customer.id
    )

    # Confirm with test card
    confirmed = stripe.PaymentIntent.confirm(
        intent.id,
        payment_method='pm_card_visa'  # Test payment method
    )

    assert confirmed.status == 'succeeded'
Files (agents)
  • references
    • details.md 10.1 KB
      # stripe-integration — detailed patterns and worked examples
      
      ## Payment Implementation Patterns
      
      ### Pattern 1: One-Time Payment (Hosted Checkout)
      
      ```python
      def create_checkout_session(amount, currency='usd'):
          """Create a one-time payment checkout session."""
          try:
              session = stripe.checkout.Session.create(
                  line_items=[{
                      'price_data': {
                          'currency': currency,
                          'product_data': {
                              'name': 'Blue T-shirt',
                              'images': ['https://example.com/product.jpg'],
                          },
                          'unit_amount': amount,  # Amount in cents
                      },
                      'quantity': 1,
                  }],
                  mode='payment',
                  success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',
                  cancel_url='https://yourdomain.com/cancel',
                  metadata={
                      'order_id': 'order_123',
                      'user_id': 'user_456'
                  }
              )
              return session
          except stripe.error.StripeError as e:
              # Handle error
              print(f"Stripe error: {e.user_message}")
              raise
      ```
      
      ### Pattern 2: Elements with Checkout Sessions
      
      ```python
      def create_checkout_session_for_elements(amount, currency='usd'):
          """Create a checkout session configured for Payment Element."""
          session = stripe.checkout.Session.create(
              mode='payment',
              ui_mode='custom',
              line_items=[{
                  'price_data': {
                      'currency': currency,
                      'product_data': {'name': 'Blue T-shirt'},
                      'unit_amount': amount,
                  },
                  'quantity': 1,
              }],
              return_url='https://yourdomain.com/complete?session_id={CHECKOUT_SESSION_ID}'
          )
          return session.client_secret  # Send to frontend
      ```
      
      ```javascript
      const stripe = Stripe("pk_test_...");
      const appearance = { theme: "stripe" };
      
      const checkout = stripe.initCheckout({
        clientSecret,
        elementsOptions: { appearance },
      });
      const loadActionsResult = await checkout.loadActions();
      
      if (loadActionsResult.type === "success") {
        const { actions } = loadActionsResult;
        const session = actions.getSession();
      
        const button = document.getElementById("pay-button");
        const checkoutContainer = document.getElementById("checkout-container");
        const emailInput = document.getElementById("email");
        const emailErrors = document.getElementById("email-errors");
        const errors = document.getElementById("confirm-errors");
      
        // Display a formatted string representing the total amount
        checkoutContainer.append(`Total: ${session.total.total.amount}`);
      
        // Mount Payment Element
        const paymentElement = checkout.createPaymentElement();
        paymentElement.mount("#payment-element");
      
        // Store email for submission
        emailInput.addEventListener("blur", () => {
          actions.updateEmail(emailInput.value).then((result) => {
            if (result.error) emailErrors.textContent = result.error.message;
          });
        });
      
        // Handle form submission
        button.addEventListener("click", () => {
          actions.confirm().then((result) => {
            if (result.type === "error") errors.textContent = result.error.message;
          });
        });
      }
      ```
      
      ### Pattern 3: Elements with Payment Intents
      
      Pattern 2 (Elements with Checkout Sessions) is Stripe's recommended approach, but you can also use Payment Intents as an alternative.
      
      ```python
      def create_payment_intent(amount, currency='usd', customer_id=None):
          """Create a payment intent for bespoke checkout UI with Payment Element."""
          intent = stripe.PaymentIntent.create(
              amount=amount,
              currency=currency,
              customer=customer_id,
              automatic_payment_methods={
                  'enabled': True,
              },
              metadata={
                  'integration_check': 'accept_a_payment'
              }
          )
          return intent.client_secret  # Send to frontend
      ```
      
      ```javascript
      // Mount Payment Element and confirm via Payment Intents
      const stripe = Stripe("pk_test_...");
      const appearance = { theme: "stripe" };
      const elements = stripe.elements({ appearance, clientSecret });
      
      const paymentElement = elements.create("payment");
      paymentElement.mount("#payment-element");
      
      document.getElementById("pay-button").addEventListener("click", async () => {
        const { error } = await stripe.confirmPayment({
          elements,
          confirmParams: {
            return_url: "https://yourdomain.com/complete",
          },
        });
      
        if (error) {
          document.getElementById("errors").textContent = error.message;
        }
      });
      ```
      
      ### Pattern 4: Subscription Creation
      
      ```python
      def create_subscription(customer_id, price_id):
          """Create a subscription for a customer."""
          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'],
              )
      
              return {
                  'subscription_id': subscription.id,
                  'client_secret': subscription.latest_invoice.payment_intent.client_secret
              }
          except stripe.error.StripeError as e:
              print(f"Subscription creation failed: {e}")
              raise
      ```
      
      ### Pattern 5: Customer Portal
      
      ```python
      def create_customer_portal_session(customer_id):
          """Create a portal session for customers to manage subscriptions."""
          session = stripe.billing_portal.Session.create(
              customer=customer_id,
              return_url='https://yourdomain.com/account',
          )
          return session.url  # Redirect customer here
      ```
      
      ## Webhook Handling
      
      ### Secure Webhook Endpoint
      
      ```python
      from flask import Flask, request
      import stripe
      
      app = Flask(__name__)
      
      endpoint_secret = 'whsec_...'
      
      @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:
              # Invalid payload
              return 'Invalid payload', 400
          except stripe.error.SignatureVerificationError:
              # Invalid signature
              return 'Invalid signature', 400
      
          # Handle the event
          if event['type'] == 'payment_intent.succeeded':
              payment_intent = event['data']['object']
              handle_successful_payment(payment_intent)
          elif event['type'] == 'payment_intent.payment_failed':
              payment_intent = event['data']['object']
              handle_failed_payment(payment_intent)
          elif event['type'] == 'customer.subscription.deleted':
              subscription = event['data']['object']
              handle_subscription_canceled(subscription)
      
          return 'Success', 200
      
      def handle_successful_payment(payment_intent):
          """Process successful payment."""
          customer_id = payment_intent.get('customer')
          amount = payment_intent['amount']
          metadata = payment_intent.get('metadata', {})
      
          # Update your database
          # Send confirmation email
          # Fulfill order
          print(f"Payment succeeded: {payment_intent['id']}")
      
      def handle_failed_payment(payment_intent):
          """Handle failed payment."""
          error = payment_intent.get('last_payment_error', {})
          print(f"Payment failed: {error.get('message')}")
          # Notify customer
          # Update order status
      
      def handle_subscription_canceled(subscription):
          """Handle subscription cancellation."""
          customer_id = subscription['customer']
          # Update user access
          # Send cancellation email
          print(f"Subscription canceled: {subscription['id']}")
      ```
      
      ### Webhook Best Practices
      
      ```python
      import hashlib
      import hmac
      
      def verify_webhook_signature(payload, signature, secret):
          """Manually verify webhook signature."""
          expected_sig = hmac.new(
              secret.encode('utf-8'),
              payload,
              hashlib.sha256
          ).hexdigest()
      
          return hmac.compare_digest(signature, expected_sig)
      
      def handle_webhook_idempotently(event_id, handler):
          """Ensure webhook is processed exactly once."""
          # Check if event already processed
          if is_event_processed(event_id):
              return
      
          # Process event
          try:
              handler()
              mark_event_processed(event_id)
          except Exception as e:
              log_error(e)
              # Stripe will retry failed webhooks
              raise
      ```
      
      ## Customer Management
      
      ```python
      def create_customer(email, name, payment_method_id=None):
          """Create a Stripe customer."""
          customer = stripe.Customer.create(
              email=email,
              name=name,
              payment_method=payment_method_id,
              invoice_settings={
                  'default_payment_method': payment_method_id
              } if payment_method_id else None,
              metadata={
                  'user_id': '12345'
              }
          )
          return customer
      
      def attach_payment_method(customer_id, payment_method_id):
          """Attach a payment method to a customer."""
          stripe.PaymentMethod.attach(
              payment_method_id,
              customer=customer_id
          )
      
          # Set as default
          stripe.Customer.modify(
              customer_id,
              invoice_settings={
                  'default_payment_method': payment_method_id
              }
          )
      
      def list_customer_payment_methods(customer_id):
          """List all payment methods for a customer."""
          payment_methods = stripe.PaymentMethod.list(
              customer=customer_id,
              type='card'
          )
          return payment_methods.data
      ```
      
      ## Refund Handling
      
      ```python
      def create_refund(payment_intent_id, amount=None, reason=None):
          """Create a refund."""
          refund_params = {
              'payment_intent': payment_intent_id
          }
      
          if amount:
              refund_params['amount'] = amount  # Partial refund
      
          if reason:
              refund_params['reason'] = reason  # 'duplicate', 'fraudulent', 'requested_by_customer'
      
          refund = stripe.Refund.create(**refund_params)
          return refund
      
      def handle_dispute(charge_id, evidence):
          """Update dispute with evidence."""
          stripe.Dispute.modify(
              charge_id,
              evidence={
                  'customer_name': evidence.get('customer_name'),
                  'customer_email_address': evidence.get('customer_email'),
                  'shipping_documentation': evidence.get('shipping_proof'),
                  'customer_communication': evidence.get('communication'),
              }
          )
      ```
      
  • SKILL.md 4.1 KB
    ---
    name: stripe-integration
    description: 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.
    ---
    
    # Stripe Integration
    
    Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.
    
    ## When to Use This Skill
    
    - Implementing payment processing in web/mobile applications
    - Setting up subscription billing systems
    - Handling one-time payments and recurring charges
    - Processing refunds and disputes
    - Managing customer payment methods
    - Implementing SCA (Strong Customer Authentication) for European payments
    - Building marketplace payment flows with Stripe Connect
    
    ## Core Concepts
    
    ### 1. Payment Flows
    
    **Checkout Sessions**
    
    - Recommended for most integrations
    - Supports all UI paths:
      - Stripe-hosted checkout page
      - Embedded checkout form
      - Custom UI with Elements (Payment Element, Express Checkout Element) using `ui_mode='custom'`
    - Provides built-in checkout capabilities (line items, discounts, tax, shipping, address collection, saved payment methods, and checkout lifecycle events)
    - Lower integration and maintenance burden than Payment Intents
    
    **Payment Intents (Bespoke control)**
    
    - You calculate the final amount with taxes, discounts, subscriptions, and currency conversion yourself.
    - More complex implementation and long-term maintenance burden
    - Requires Stripe.js for PCI compliance
    
    **Setup Intents (Save Payment Methods)**
    
    - Collect payment method without charging
    - Used for subscriptions and future payments
    - Requires customer confirmation
    
    ### 2. Webhooks
    
    **Critical Events:**
    
    - `payment_intent.succeeded`: Payment completed
    - `payment_intent.payment_failed`: Payment failed
    - `customer.subscription.updated`: Subscription changed
    - `customer.subscription.deleted`: Subscription canceled
    - `charge.refunded`: Refund processed
    - `invoice.payment_succeeded`: Subscription payment successful
    
    ### 3. Subscriptions
    
    **Components:**
    
    - **Product**: What you're selling
    - **Price**: How much and how often
    - **Subscription**: Customer's recurring payment
    - **Invoice**: Generated for each billing cycle
    
    ### 4. Customer Management
    
    - Create and manage customer records
    - Store multiple payment methods
    - Track customer metadata
    - Manage billing details
    
    ## Quick Start
    
    ```python
    import stripe
    
    stripe.api_key = "sk_test_..."
    
    # Create a checkout session
    session = stripe.checkout.Session.create(
        line_items=[{
            'price_data': {
                'currency': 'usd',
                'product_data': {
                    'name': 'Premium Subscription',
                },
                'unit_amount': 2000,  # $20.00
                'recurring': {
                    'interval': 'month',
                },
            },
            'quantity': 1,
        }],
        mode='subscription',
        success_url='https://yourdomain.com/success?session_id={CHECKOUT_SESSION_ID}',
        cancel_url='https://yourdomain.com/cancel'
    )
    
    # Redirect user to session.url
    print(session.url)
    ```
    
    ## Detailed patterns and worked examples
    
    Detailed pattern documentation lives in `references/details.md`. Read that file when the navigation tier above is insufficient.
    
    ## Testing
    
    ```python
    # Use test mode keys
    stripe.api_key = "sk_test_..."
    
    # Test card numbers
    TEST_CARDS = {
        'success': '4242424242424242',
        'declined': '4000000000000002',
        '3d_secure': '4000002500003155',
        'insufficient_funds': '4000000000009995'
    }
    
    def test_payment_flow():
        """Test complete payment flow."""
        # Create test customer
        customer = stripe.Customer.create(
            email="test@example.com"
        )
    
        # Create payment intent
        intent = stripe.PaymentIntent.create(
            amount=1000,
            automatic_payment_methods={
                'enabled': True
            },
            currency='usd',
            customer=customer.id
        )
    
        # Confirm with test card
        confirmed = stripe.PaymentIntent.confirm(
            intent.id,
            payment_method='pm_card_visa'  # Test payment method
        )
    
        assert confirmed.status == 'succeeded'
    ```
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related