[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M70K9K552NPJCQZHGDY6VEQW":3,"skill-same:01M70K9K552NPJCQZHGDY6VEQW":67},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":18,"publishedAt":38,"linkOnly":39,"markdownContent":40,"markdownBody":41,"frontMatter":42,"refName":43,"commitSha":44,"skillDirectory":45,"forksCount":46,"repositoryHtmlUrl":47,"repositoryHomepageUrl":48,"ownerHtmlUrl":49,"ownerBlogUrl":50,"ownerDescription":51,"updatedAt":52,"install":53,"resources":66},"01M70K9K552NPJCQZHGDY6VEQW","stripe-integration",null,"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.","shengdabai\u002FTony-Claude-Code-Skills","shengdabai","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F116417419?v=4","01M70F6D2WY5PQV5A92BKYJQEW","Tony Sheng","01M70F6D3GAAAYZ5H4CC1G8VXM",3,"MIT","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fpayment-processing\u002Fskills\u002Fstripe-integration\u002FSKILL.md",[],[19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37],"stripe integration","integration","stripe","systems","subscriptions","payment","implement","use","for","webhooks","secure","pci","stripe payments","when","payments","implementing","flows","checkout","processing","2026-11-10 10:12:30",false,"---\nname: stripe-integration\ndescription: 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.\n---\n\n# Stripe Integration\n\nMaster Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.\n\n## When to Use This Skill\n\n- Implementing payment processing in web\u002Fmobile applications\n- Setting up subscription billing systems\n- Handling one-time payments and recurring charges\n- Processing refunds and disputes\n- Managing customer payment methods\n- Implementing SCA (Strong Customer Authentication) for European payments\n- Building marketplace payment flows with Stripe Connect\n\n## Core Concepts\n\n### 1. Payment Flows\n**Checkout Session (Hosted)**\n- Stripe-hosted payment page\n- Minimal PCI compliance burden\n- Fastest implementation\n- Supports one-time and recurring payments\n\n**Payment Intents (Custom UI)**\n- Full control over payment UI\n- Requires Stripe.js for PCI compliance\n- More complex implementation\n- Better customization options\n\n**Setup Intents (Save Payment Methods)**\n- Collect payment method without charging\n- Used for subscriptions and future payments\n- Requires customer confirmation\n\n### 2. Webhooks\n**Critical Events:**\n- `payment_intent.succeeded`: Payment completed\n- `payment_intent.payment_failed`: Payment failed\n- `customer.subscription.updated`: Subscription changed\n- `customer.subscription.deleted`: Subscription canceled\n- `charge.refunded`: Refund processed\n- `invoice.payment_succeeded`: Subscription payment successful\n\n### 3. Subscriptions\n**Components:**\n- **Product**: What you're selling\n- **Price**: How much and how often\n- **Subscription**: Customer's recurring payment\n- **Invoice**: Generated for each billing cycle\n\n### 4. Customer Management\n- Create and manage customer records\n- Store multiple payment methods\n- Track customer metadata\n- Manage billing details\n\n## Quick Start\n\n```python\nimport stripe\n\nstripe.api_key = \"sk_test_...\"\n\n# Create a checkout session\nsession = stripe.checkout.Session.create(\n    payment_method_types=['card'],\n    line_items=[{\n        'price_data': {\n            'currency': 'usd',\n            'product_data': {\n                'name': 'Premium Subscription',\n            },\n            'unit_amount': 2000,  # $20.00\n            'recurring': {\n                'interval': 'month',\n            },\n        },\n        'quantity': 1,\n    }],\n    mode='subscription',\n    success_url='https:\u002F\u002Fyourdomain.com\u002Fsuccess?session_id={CHECKOUT_SESSION_ID}',\n    cancel_url='https:\u002F\u002Fyourdomain.com\u002Fcancel',\n)\n\n# Redirect user to session.url\nprint(session.url)\n```\n\n## Payment Implementation Patterns\n\n### Pattern 1: One-Time Payment (Hosted Checkout)\n```python\ndef create_checkout_session(amount, currency='usd'):\n    \"\"\"Create a one-time payment checkout session.\"\"\"\n    try:\n        session = stripe.checkout.Session.create(\n            payment_method_types=['card'],\n            line_items=[{\n                'price_data': {\n                    'currency': currency,\n                    'product_data': {\n                        'name': 'Purchase',\n                        'images': ['https:\u002F\u002Fexample.com\u002Fproduct.jpg'],\n                    },\n                    'unit_amount': amount,  # Amount in cents\n                },\n                'quantity': 1,\n            }],\n            mode='payment',\n            success_url='https:\u002F\u002Fyourdomain.com\u002Fsuccess?session_id={CHECKOUT_SESSION_ID}',\n            cancel_url='https:\u002F\u002Fyourdomain.com\u002Fcancel',\n            metadata={\n                'order_id': 'order_123',\n                'user_id': 'user_456'\n            }\n        )\n        return session\n    except stripe.error.StripeError as e:\n        # Handle error\n        print(f\"Stripe error: {e.user_message}\")\n        raise\n```\n\n### Pattern 2: Custom Payment Intent Flow\n```python\ndef create_payment_intent(amount, currency='usd', customer_id=None):\n    \"\"\"Create a payment intent for custom checkout UI.\"\"\"\n    intent = stripe.PaymentIntent.create(\n        amount=amount,\n        currency=currency,\n        customer=customer_id,\n        automatic_payment_methods={\n            'enabled': True,\n        },\n        metadata={\n            'integration_check': 'accept_a_payment'\n        }\n    )\n    return intent.client_secret  # Send to frontend\n\n# Frontend (JavaScript)\n\"\"\"\nconst stripe = Stripe('pk_test_...');\nconst elements = stripe.elements();\nconst cardElement = elements.create('card');\ncardElement.mount('#card-element');\n\nconst {error, paymentIntent} = await stripe.confirmCardPayment(\n    clientSecret,\n    {\n        payment_method: {\n            card: cardElement,\n            billing_details: {\n                name: 'Customer Name'\n            }\n        }\n    }\n);\n\nif (error) {\n    \u002F\u002F Handle error\n} else if (paymentIntent.status === 'succeeded') {\n    \u002F\u002F Payment successful\n}\n\"\"\"\n```\n\n### Pattern 3: Subscription Creation\n```python\ndef create_subscription(customer_id, price_id):\n    \"\"\"Create a subscription for a customer.\"\"\"\n    try:\n        subscription = stripe.Subscription.create(\n            customer=customer_id,\n            items=[{'price': price_id}],\n            payment_behavior='default_incomplete',\n            payment_settings={'save_default_payment_method': 'on_subscription'},\n            expand=['latest_invoice.payment_intent'],\n        )\n\n        return {\n            'subscription_id': subscription.id,\n            'client_secret': subscription.latest_invoice.payment_intent.client_secret\n        }\n    except stripe.error.StripeError as e:\n        print(f\"Subscription creation failed: {e}\")\n        raise\n```\n\n### Pattern 4: Customer Portal\n```python\ndef create_customer_portal_session(customer_id):\n    \"\"\"Create a portal session for customers to manage subscriptions.\"\"\"\n    session = stripe.billing_portal.Session.create(\n        customer=customer_id,\n        return_url='https:\u002F\u002Fyourdomain.com\u002Faccount',\n    )\n    return session.url  # Redirect customer here\n```\n\n## Webhook Handling\n\n### Secure Webhook Endpoint\n```python\nfrom flask import Flask, request\nimport stripe\n\napp = Flask(__name__)\n\nendpoint_secret = 'whsec_...'\n\n@app.route('\u002Fwebhook', methods=['POST'])\ndef webhook():\n    payload = request.data\n    sig_header = request.headers.get('Stripe-Signature')\n\n    try:\n        event = stripe.Webhook.construct_event(\n            payload, sig_header, endpoint_secret\n        )\n    except ValueError:\n        # Invalid payload\n        return 'Invalid payload', 400\n    except stripe.error.SignatureVerificationError:\n        # Invalid signature\n        return 'Invalid signature', 400\n\n    # Handle the event\n    if event['type'] == 'payment_intent.succeeded':\n        payment_intent = event['data']['object']\n        handle_successful_payment(payment_intent)\n    elif event['type'] == 'payment_intent.payment_failed':\n        payment_intent = event['data']['object']\n        handle_failed_payment(payment_intent)\n    elif event['type'] == 'customer.subscription.deleted':\n        subscription = event['data']['object']\n        handle_subscription_canceled(subscription)\n\n    return 'Success', 200\n\ndef handle_successful_payment(payment_intent):\n    \"\"\"Process successful payment.\"\"\"\n    customer_id = payment_intent.get('customer')\n    amount = payment_intent['amount']\n    metadata = payment_intent.get('metadata', {})\n\n    # Update your database\n    # Send confirmation email\n    # Fulfill order\n    print(f\"Payment succeeded: {payment_intent['id']}\")\n\ndef handle_failed_payment(payment_intent):\n    \"\"\"Handle failed payment.\"\"\"\n    error = payment_intent.get('last_payment_error', {})\n    print(f\"Payment failed: {error.get('message')}\")\n    # Notify customer\n    # Update order status\n\ndef handle_subscription_canceled(subscription):\n    \"\"\"Handle subscription cancellation.\"\"\"\n    customer_id = subscription['customer']\n    # Update user access\n    # Send cancellation email\n    print(f\"Subscription canceled: {subscription['id']}\")\n```\n\n### Webhook Best Practices\n```python\nimport hashlib\nimport hmac\n\ndef verify_webhook_signature(payload, signature, secret):\n    \"\"\"Manually verify webhook signature.\"\"\"\n    expected_sig = hmac.new(\n        secret.encode('utf-8'),\n        payload,\n        hashlib.sha256\n    ).hexdigest()\n\n    return hmac.compare_digest(signature, expected_sig)\n\ndef handle_webhook_idempotently(event_id, handler):\n    \"\"\"Ensure webhook is processed exactly once.\"\"\"\n    # Check if event already processed\n    if is_event_processed(event_id):\n        return\n\n    # Process event\n    try:\n        handler()\n        mark_event_processed(event_id)\n    except Exception as e:\n        log_error(e)\n        # Stripe will retry failed webhooks\n        raise\n```\n\n## Customer Management\n\n```python\ndef create_customer(email, name, payment_method_id=None):\n    \"\"\"Create a Stripe customer.\"\"\"\n    customer = stripe.Customer.create(\n        email=email,\n        name=name,\n        payment_method=payment_method_id,\n        invoice_settings={\n            'default_payment_method': payment_method_id\n        } if payment_method_id else None,\n        metadata={\n            'user_id': '12345'\n        }\n    )\n    return customer\n\ndef attach_payment_method(customer_id, payment_method_id):\n    \"\"\"Attach a payment method to a customer.\"\"\"\n    stripe.PaymentMethod.attach(\n        payment_method_id,\n        customer=customer_id\n    )\n\n    # Set as default\n    stripe.Customer.modify(\n        customer_id,\n        invoice_settings={\n            'default_payment_method': payment_method_id\n        }\n    )\n\ndef list_customer_payment_methods(customer_id):\n    \"\"\"List all payment methods for a customer.\"\"\"\n    payment_methods = stripe.PaymentMethod.list(\n        customer=customer_id,\n        type='card'\n    )\n    return payment_methods.data\n```\n\n## Refund Handling\n\n```python\ndef create_refund(payment_intent_id, amount=None, reason=None):\n    \"\"\"Create a refund.\"\"\"\n    refund_params = {\n        'payment_intent': payment_intent_id\n    }\n\n    if amount:\n        refund_params['amount'] = amount  # Partial refund\n\n    if reason:\n        refund_params['reason'] = reason  # 'duplicate', 'fraudulent', 'requested_by_customer'\n\n    refund = stripe.Refund.create(**refund_params)\n    return refund\n\ndef handle_dispute(charge_id, evidence):\n    \"\"\"Update dispute with evidence.\"\"\"\n    stripe.Dispute.modify(\n        charge_id,\n        evidence={\n            'customer_name': evidence.get('customer_name'),\n            'customer_email_address': evidence.get('customer_email'),\n            'shipping_documentation': evidence.get('shipping_proof'),\n            'customer_communication': evidence.get('communication'),\n        }\n    )\n```\n\n## Testing\n\n```python\n# Use test mode keys\nstripe.api_key = \"sk_test_...\"\n\n# Test card numbers\nTEST_CARDS = {\n    'success': '4242424242424242',\n    'declined': '4000000000000002',\n    '3d_secure': '4000002500003155',\n    'insufficient_funds': '4000000000009995'\n}\n\ndef test_payment_flow():\n    \"\"\"Test complete payment flow.\"\"\"\n    # Create test customer\n    customer = stripe.Customer.create(\n        email=\"test@example.com\"\n    )\n\n    # Create payment intent\n    intent = stripe.PaymentIntent.create(\n        amount=1000,\n        currency='usd',\n        customer=customer.id,\n        payment_method_types=['card']\n    )\n\n    # Confirm with test card\n    confirmed = stripe.PaymentIntent.confirm(\n        intent.id,\n        payment_method='pm_card_visa'  # Test payment method\n    )\n\n    assert confirmed.status == 'succeeded'\n```\n\n## Resources\n\n- **references\u002Fcheckout-flows.md**: Detailed checkout implementation\n- **references\u002Fwebhook-handling.md**: Webhook security and processing\n- **references\u002Fsubscription-management.md**: Subscription lifecycle\n- **references\u002Fcustomer-management.md**: Customer and payment method handling\n- **references\u002Finvoice-generation.md**: Invoicing and billing\n- **assets\u002Fstripe-client.py**: Production-ready Stripe client wrapper\n- **assets\u002Fwebhook-handler.py**: Complete webhook processor\n- **assets\u002Fcheckout-config.json**: Checkout configuration templates\n\n## Best Practices\n\n1. **Always Use Webhooks**: Don't rely solely on client-side confirmation\n2. **Idempotency**: Handle webhook events idempotently\n3. **Error Handling**: Gracefully handle all Stripe errors\n4. **Test Mode**: Thoroughly test with test keys before production\n5. **Metadata**: Use metadata to link Stripe objects to your database\n6. **Monitoring**: Track payment success rates and errors\n7. **PCI Compliance**: Never handle raw card data on your server\n8. **SCA Ready**: Implement 3D Secure for European payments\n\n## Common Pitfalls\n\n- **Not Verifying Webhooks**: Always verify webhook signatures\n- **Missing Webhook Events**: Handle all relevant webhook events\n- **Hardcoded Amounts**: Use cents\u002Fsmallest currency unit\n- **No Retry Logic**: Implement retries for API calls\n- **Ignoring Test Mode**: Test all edge cases with test cards\n","# Stripe Integration\n\nMaster Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.\n\n## When to Use This Skill\n\n- Implementing payment processing in web\u002Fmobile applications\n- Setting up subscription billing systems\n- Handling one-time payments and recurring charges\n- Processing refunds and disputes\n- Managing customer payment methods\n- Implementing SCA (Strong Customer Authentication) for European payments\n- Building marketplace payment flows with Stripe Connect\n\n## Core Concepts\n\n### 1. Payment Flows\n**Checkout Session (Hosted)**\n- Stripe-hosted payment page\n- Minimal PCI compliance burden\n- Fastest implementation\n- Supports one-time and recurring payments\n\n**Payment Intents (Custom UI)**\n- Full control over payment UI\n- Requires Stripe.js for PCI compliance\n- More complex implementation\n- Better customization options\n\n**Setup Intents (Save Payment Methods)**\n- Collect payment method without charging\n- Used for subscriptions and future payments\n- Requires customer confirmation\n\n### 2. Webhooks\n**Critical Events:**\n- `payment_intent.succeeded`: Payment completed\n- `payment_intent.payment_failed`: Payment failed\n- `customer.subscription.updated`: Subscription changed\n- `customer.subscription.deleted`: Subscription canceled\n- `charge.refunded`: Refund processed\n- `invoice.payment_succeeded`: Subscription payment successful\n\n### 3. Subscriptions\n**Components:**\n- **Product**: What you're selling\n- **Price**: How much and how often\n- **Subscription**: Customer's recurring payment\n- **Invoice**: Generated for each billing cycle\n\n### 4. Customer Management\n- Create and manage customer records\n- Store multiple payment methods\n- Track customer metadata\n- Manage billing details\n\n## Quick Start\n\n```python\nimport stripe\n\nstripe.api_key = \"sk_test_...\"\n\n# Create a checkout session\nsession = stripe.checkout.Session.create(\n    payment_method_types=['card'],\n    line_items=[{\n        'price_data': {\n            'currency': 'usd',\n            'product_data': {\n                'name': 'Premium Subscription',\n            },\n            'unit_amount': 2000,  # $20.00\n            'recurring': {\n                'interval': 'month',\n            },\n        },\n        'quantity': 1,\n    }],\n    mode='subscription',\n    success_url='https:\u002F\u002Fyourdomain.com\u002Fsuccess?session_id={CHECKOUT_SESSION_ID}',\n    cancel_url='https:\u002F\u002Fyourdomain.com\u002Fcancel',\n)\n\n# Redirect user to session.url\nprint(session.url)\n```\n\n## Payment Implementation Patterns\n\n### Pattern 1: One-Time Payment (Hosted Checkout)\n```python\ndef create_checkout_session(amount, currency='usd'):\n    \"\"\"Create a one-time payment checkout session.\"\"\"\n    try:\n        session = stripe.checkout.Session.create(\n            payment_method_types=['card'],\n            line_items=[{\n                'price_data': {\n                    'currency': currency,\n                    'product_data': {\n                        'name': 'Purchase',\n                        'images': ['https:\u002F\u002Fexample.com\u002Fproduct.jpg'],\n                    },\n                    'unit_amount': amount,  # Amount in cents\n                },\n                'quantity': 1,\n            }],\n            mode='payment',\n            success_url='https:\u002F\u002Fyourdomain.com\u002Fsuccess?session_id={CHECKOUT_SESSION_ID}',\n            cancel_url='https:\u002F\u002Fyourdomain.com\u002Fcancel',\n            metadata={\n                'order_id': 'order_123',\n                'user_id': 'user_456'\n            }\n        )\n        return session\n    except stripe.error.StripeError as e:\n        # Handle error\n        print(f\"Stripe error: {e.user_message}\")\n        raise\n```\n\n### Pattern 2: Custom Payment Intent Flow\n```python\ndef create_payment_intent(amount, currency='usd', customer_id=None):\n    \"\"\"Create a payment intent for custom checkout UI.\"\"\"\n    intent = stripe.PaymentIntent.create(\n        amount=amount,\n        currency=currency,\n        customer=customer_id,\n        automatic_payment_methods={\n            'enabled': True,\n        },\n        metadata={\n            'integration_check': 'accept_a_payment'\n        }\n    )\n    return intent.client_secret  # Send to frontend\n\n# Frontend (JavaScript)\n\"\"\"\nconst stripe = Stripe('pk_test_...');\nconst elements = stripe.elements();\nconst cardElement = elements.create('card');\ncardElement.mount('#card-element');\n\nconst {error, paymentIntent} = await stripe.confirmCardPayment(\n    clientSecret,\n    {\n        payment_method: {\n            card: cardElement,\n            billing_details: {\n                name: 'Customer Name'\n            }\n        }\n    }\n);\n\nif (error) {\n    \u002F\u002F Handle error\n} else if (paymentIntent.status === 'succeeded') {\n    \u002F\u002F Payment successful\n}\n\"\"\"\n```\n\n### Pattern 3: Subscription Creation\n```python\ndef create_subscription(customer_id, price_id):\n    \"\"\"Create a subscription for a customer.\"\"\"\n    try:\n        subscription = stripe.Subscription.create(\n            customer=customer_id,\n            items=[{'price': price_id}],\n            payment_behavior='default_incomplete',\n            payment_settings={'save_default_payment_method': 'on_subscription'},\n            expand=['latest_invoice.payment_intent'],\n        )\n\n        return {\n            'subscription_id': subscription.id,\n            'client_secret': subscription.latest_invoice.payment_intent.client_secret\n        }\n    except stripe.error.StripeError as e:\n        print(f\"Subscription creation failed: {e}\")\n        raise\n```\n\n### Pattern 4: Customer Portal\n```python\ndef create_customer_portal_session(customer_id):\n    \"\"\"Create a portal session for customers to manage subscriptions.\"\"\"\n    session = stripe.billing_portal.Session.create(\n        customer=customer_id,\n        return_url='https:\u002F\u002Fyourdomain.com\u002Faccount',\n    )\n    return session.url  # Redirect customer here\n```\n\n## Webhook Handling\n\n### Secure Webhook Endpoint\n```python\nfrom flask import Flask, request\nimport stripe\n\napp = Flask(__name__)\n\nendpoint_secret = 'whsec_...'\n\n@app.route('\u002Fwebhook', methods=['POST'])\ndef webhook():\n    payload = request.data\n    sig_header = request.headers.get('Stripe-Signature')\n\n    try:\n        event = stripe.Webhook.construct_event(\n            payload, sig_header, endpoint_secret\n        )\n    except ValueError:\n        # Invalid payload\n        return 'Invalid payload', 400\n    except stripe.error.SignatureVerificationError:\n        # Invalid signature\n        return 'Invalid signature', 400\n\n    # Handle the event\n    if event['type'] == 'payment_intent.succeeded':\n        payment_intent = event['data']['object']\n        handle_successful_payment(payment_intent)\n    elif event['type'] == 'payment_intent.payment_failed':\n        payment_intent = event['data']['object']\n        handle_failed_payment(payment_intent)\n    elif event['type'] == 'customer.subscription.deleted':\n        subscription = event['data']['object']\n        handle_subscription_canceled(subscription)\n\n    return 'Success', 200\n\ndef handle_successful_payment(payment_intent):\n    \"\"\"Process successful payment.\"\"\"\n    customer_id = payment_intent.get('customer')\n    amount = payment_intent['amount']\n    metadata = payment_intent.get('metadata', {})\n\n    # Update your database\n    # Send confirmation email\n    # Fulfill order\n    print(f\"Payment succeeded: {payment_intent['id']}\")\n\ndef handle_failed_payment(payment_intent):\n    \"\"\"Handle failed payment.\"\"\"\n    error = payment_intent.get('last_payment_error', {})\n    print(f\"Payment failed: {error.get('message')}\")\n    # Notify customer\n    # Update order status\n\ndef handle_subscription_canceled(subscription):\n    \"\"\"Handle subscription cancellation.\"\"\"\n    customer_id = subscription['customer']\n    # Update user access\n    # Send cancellation email\n    print(f\"Subscription canceled: {subscription['id']}\")\n```\n\n### Webhook Best Practices\n```python\nimport hashlib\nimport hmac\n\ndef verify_webhook_signature(payload, signature, secret):\n    \"\"\"Manually verify webhook signature.\"\"\"\n    expected_sig = hmac.new(\n        secret.encode('utf-8'),\n        payload,\n        hashlib.sha256\n    ).hexdigest()\n\n    return hmac.compare_digest(signature, expected_sig)\n\ndef handle_webhook_idempotently(event_id, handler):\n    \"\"\"Ensure webhook is processed exactly once.\"\"\"\n    # Check if event already processed\n    if is_event_processed(event_id):\n        return\n\n    # Process event\n    try:\n        handler()\n        mark_event_processed(event_id)\n    except Exception as e:\n        log_error(e)\n        # Stripe will retry failed webhooks\n        raise\n```\n\n## Customer Management\n\n```python\ndef create_customer(email, name, payment_method_id=None):\n    \"\"\"Create a Stripe customer.\"\"\"\n    customer = stripe.Customer.create(\n        email=email,\n        name=name,\n        payment_method=payment_method_id,\n        invoice_settings={\n            'default_payment_method': payment_method_id\n        } if payment_method_id else None,\n        metadata={\n            'user_id': '12345'\n        }\n    )\n    return customer\n\ndef attach_payment_method(customer_id, payment_method_id):\n    \"\"\"Attach a payment method to a customer.\"\"\"\n    stripe.PaymentMethod.attach(\n        payment_method_id,\n        customer=customer_id\n    )\n\n    # Set as default\n    stripe.Customer.modify(\n        customer_id,\n        invoice_settings={\n            'default_payment_method': payment_method_id\n        }\n    )\n\ndef list_customer_payment_methods(customer_id):\n    \"\"\"List all payment methods for a customer.\"\"\"\n    payment_methods = stripe.PaymentMethod.list(\n        customer=customer_id,\n        type='card'\n    )\n    return payment_methods.data\n```\n\n## Refund Handling\n\n```python\ndef create_refund(payment_intent_id, amount=None, reason=None):\n    \"\"\"Create a refund.\"\"\"\n    refund_params = {\n        'payment_intent': payment_intent_id\n    }\n\n    if amount:\n        refund_params['amount'] = amount  # Partial refund\n\n    if reason:\n        refund_params['reason'] = reason  # 'duplicate', 'fraudulent', 'requested_by_customer'\n\n    refund = stripe.Refund.create(**refund_params)\n    return refund\n\ndef handle_dispute(charge_id, evidence):\n    \"\"\"Update dispute with evidence.\"\"\"\n    stripe.Dispute.modify(\n        charge_id,\n        evidence={\n            'customer_name': evidence.get('customer_name'),\n            'customer_email_address': evidence.get('customer_email'),\n            'shipping_documentation': evidence.get('shipping_proof'),\n            'customer_communication': evidence.get('communication'),\n        }\n    )\n```\n\n## Testing\n\n```python\n# Use test mode keys\nstripe.api_key = \"sk_test_...\"\n\n# Test card numbers\nTEST_CARDS = {\n    'success': '4242424242424242',\n    'declined': '4000000000000002',\n    '3d_secure': '4000002500003155',\n    'insufficient_funds': '4000000000009995'\n}\n\ndef test_payment_flow():\n    \"\"\"Test complete payment flow.\"\"\"\n    # Create test customer\n    customer = stripe.Customer.create(\n        email=\"test@example.com\"\n    )\n\n    # Create payment intent\n    intent = stripe.PaymentIntent.create(\n        amount=1000,\n        currency='usd',\n        customer=customer.id,\n        payment_method_types=['card']\n    )\n\n    # Confirm with test card\n    confirmed = stripe.PaymentIntent.confirm(\n        intent.id,\n        payment_method='pm_card_visa'  # Test payment method\n    )\n\n    assert confirmed.status == 'succeeded'\n```\n\n## Resources\n\n- **references\u002Fcheckout-flows.md**: Detailed checkout implementation\n- **references\u002Fwebhook-handling.md**: Webhook security and processing\n- **references\u002Fsubscription-management.md**: Subscription lifecycle\n- **references\u002Fcustomer-management.md**: Customer and payment method handling\n- **references\u002Finvoice-generation.md**: Invoicing and billing\n- **assets\u002Fstripe-client.py**: Production-ready Stripe client wrapper\n- **assets\u002Fwebhook-handler.py**: Complete webhook processor\n- **assets\u002Fcheckout-config.json**: Checkout configuration templates\n\n## Best Practices\n\n1. **Always Use Webhooks**: Don't rely solely on client-side confirmation\n2. **Idempotency**: Handle webhook events idempotently\n3. **Error Handling**: Gracefully handle all Stripe errors\n4. **Test Mode**: Thoroughly test with test keys before production\n5. **Metadata**: Use metadata to link Stripe objects to your database\n6. **Monitoring**: Track payment success rates and errors\n7. **PCI Compliance**: Never handle raw card data on your server\n8. **SCA Ready**: Implement 3D Secure for European payments\n\n## Common Pitfalls\n\n- **Not Verifying Webhooks**: Always verify webhook signatures\n- **Missing Webhook Events**: Handle all relevant webhook events\n- **Hardcoded Amounts**: Use cents\u002Fsmallest currency unit\n- **No Retry Logic**: Implement retries for API calls\n- **Ignoring Test Mode**: Test all edge cases with test cards\n",{"name":5,"description":7},"main","7850740bd837adb32f0a109ab2af82482196c6f2","skills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fpayment-processing\u002Fskills\u002Fstripe-integration",1,"https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills","https:\u002F\u002Fzturnsgo.com","https:\u002F\u002Fgithub.com\u002Fshengdabai","https:\u002F\u002Fzturnsgo.com\u002F","AI × education creator — producer, not consumer. Taught 6,000+ learners; shipping learning tools & daily essays with Claude Code, practicing @xiaolai's way 🥋","2026-11-01 21:28:23",{"source":8,"skillName":5,"commands":54,"prompt":64,"zipAvailable":65},[55,58,61],{"tool":56,"command":57},"npx","npx skills add shengdabai\u002FTony-Claude-Code-Skills --skill stripe-integration",{"tool":59,"command":60},"bunx","bunx skills add shengdabai\u002FTony-Claude-Code-Skills --skill stripe-integration",{"tool":62,"command":63},"pnpm","pnpm dlx skills add shengdabai\u002FTony-Claude-Code-Skills --skill stripe-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002F_collections\u002Fwshobson-agents\u002Fplugins\u002Fpayment-processing\u002Fskills\u002Fstripe-integration\u002FSKILL.md",true,[],[68,87,121,146,168,188],{"skillNo":69,"name":70,"nameZh":6,"description":71,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":72,"categories":73,"keywords":79,"publishedAt":38},"01M70P17DAD4C1C47NPH6A96EM","xiaolai-methodology","以李笑来(Li Xiaolai)的思考方式、方法论与表达风格,为用户做全方位 1-on-1 教练指导,覆盖创业、赚钱、投资、学习、自学、读书写作、用 AI、以及人生心态与自我管理。当用户提到 \"李笑来\"、\"笑来\"、\"笑来老师\"、\"扮演李笑来\"、\"找笑来聊聊\"、\"笑来怎么看\"、\"xiaolai\"、\"把时间当作朋友\"、\"通往财富自由之路\"、\"定投改变命运\"、\"韭菜的自我修养\"、\"自学是门手艺\"、\"让时间陪你慢慢变富\"、\"七年就是一辈子\"、\"元认知\"、\"活在未来\"、\"复利\u002F长期主义\"、\"践行\"、\"痴迷改进\"、\"个人商业模式\u002F出售时间\"、\"睡后收入\"、\"定投\"、\"财富自由\"、\"操作系统升级\"、\"最少必要知识\"、\"北极星提示词\"、\"用 AI 该怎么学\u002F思考\" 等任一触发词,或当用户带着关于创业\u002F赚钱\u002F投资\u002F学习\u002F职业\u002F重大人生决策的困惑、希望被人用笑来式的「逻辑 + 大白话 + 类比 + 重新定义 + 践行导向」来点醒和指导时,自动进入李笑来教练模式。","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fxiaolai-methodology\u002FSKILL.md",[74],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000018","写作与文案","SCENARIO","使用场景",[80,81,82,83,84,85,86],"methodology","xiaolai","xiaolai methodology","朋友","投资","writing","收入",{"skillNo":88,"name":89,"nameZh":6,"description":90,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":91,"categories":92,"keywords":101,"publishedAt":38},"01M70P13NB9YP7ACJR1S861CDS","zread","Produce and consume a wiki-style knowledge base for a code repository via the `zread` CLI and its on-disk output under `.\u002F.zread\u002Fwiki\u002F`. Use this skill whenever the user wants to understand, onboard onto, explore, summarize, map, or get an overview of an unfamiliar codebase; asks for architecture docs, a project wiki, a repo walkthrough, module\u002Fpackage explanations, or \"what does this repo do\"; wants to generate, regenerate, resume, browse, or serve code documentation locally; or mentions zread \u002F zread.ai directly. Also use it proactively before diving into a large unknown repo — if `.\u002F.zread\u002Fwiki\u002Fcurrent` exists, read the generated pages instead of crawling source file-by-file; if it doesn't, consider offering to run `zread generate`. The trigger is the intent (understand a codebase through generated docs), not the literal word \"zread\".","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fzread\u002FSKILL.md",[93,96],{"categoryNo":94,"categoryName":95,"taxonomyType":77,"taxonomyTypeDesc":78},"01JBSEEDCAT000000000000023","Skill与智能体开发",{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000030","开发工程师","PROFESSION","适用职业",[89,102,103,104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120],"knowledge","wiki","explore","walkthrough","project","get","knowledge base","run","generate","intent","cli","map","documentation","project wiki","disk","architecture","code","unknown","generated",{"skillNo":122,"name":123,"nameZh":6,"description":124,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":125,"categories":126,"keywords":131,"publishedAt":38},"01M70P10S4SWMZQ8BJAFBFDRW3","youtube","Launch the YouTube Creator Agent to auto-generate videos.\nUse when: user types \u002Fyoutube, wants to create YouTube videos,\ngenerate video content, or upload to YouTube.\nKeywords: youtube, video, 视频, 创作视频, 发布视频","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube\u002FSKILL.md",[127,128],{"categoryNo":94,"categoryName":95,"taxonomyType":77,"taxonomyTypeDesc":78},{"categoryNo":129,"categoryName":130,"taxonomyType":99,"taxonomyTypeDesc":100},"01JBSEEDCAT000000000000036","内容创作者",[123,132,133,134,135,136,137,138,110,139,140,141,32,26,142,143,144,145],"user","content","视频","creator","generate video","videos","launch","video content","create","upload","auto","types","Video","创作",{"skillNo":147,"name":148,"nameZh":6,"description":149,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":150,"categories":151,"keywords":153,"publishedAt":38},"01M70P0YE95D8BACZCGV8BK90K","youtube-script-sync","Sync, update, or optimize Tony's GetNote knowledge base `Youtube视频逐字稿` by turning each parent recording or first-person idea note into an idempotent child note containing a directly recordable YouTube long-video or Shorts script. Use when the user says “更新\u002F同步\u002F优化 Youtube视频逐字稿知识库”, or says “更新\u002F同步\u002F优化该知识库” while this knowledge base is the active context.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fyoutube-script-sync\u002FSKILL.md",[152],{"categoryNo":94,"categoryName":95,"taxonomyType":77,"taxonomyTypeDesc":78},[154,155,123,156,157,144,158,159,160,161,162,163,164,165,108,166,32,26,102,167],"sync","script","youtube script sync","recording","shorts","first","base","person","update","active","child","optimize","idempotent","long",{"skillNo":169,"name":170,"nameZh":6,"description":171,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":172,"categories":173,"keywords":178,"publishedAt":38},"01M70P0WMV5XT0EEC0N445PW07","writing-skills","How to write SKILL.md files that trigger reliably and teach effectively. Use when creating, improving, or reviewing Claude Code skills.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-skills\u002FSKILL.md",[174,175,176,177],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},{"categoryNo":94,"categoryName":95,"taxonomyType":77,"taxonomyTypeDesc":78},{"categoryNo":97,"categoryName":98,"taxonomyType":99,"taxonomyTypeDesc":100},{"categoryNo":129,"categoryName":130,"taxonomyType":99,"taxonomyTypeDesc":100},[179,85,180,181,182,183,118,32,26,184,185,186,187],"writing skills","how","teach","write skill","write","claude code skills","files","how to","trigger",{"skillNo":189,"name":190,"nameZh":6,"description":191,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":192,"categories":193,"keywords":196,"publishedAt":38},"01M70P0SJFR4YVJQBGMHKGSKXT","writing-rules","How to write .claude\u002Frules\u002F files that Claude actually follows. Use when creating, improving, or reviewing project rules.","https:\u002F\u002Fgithub.com\u002Fshengdabai\u002FTony-Claude-Code-Skills\u002Fblob\u002Fmain\u002Fskills\u002Fxiaolai\u002Fnlpm\u002Fskills\u002Fnlpm\u002Fwriting-rules\u002FSKILL.md",[194,195],{"categoryNo":75,"categoryName":76,"taxonomyType":77,"taxonomyTypeDesc":78},{"categoryNo":129,"categoryName":130,"taxonomyType":99,"taxonomyTypeDesc":100},[197,85,198,106,199,185,32,180,183,26,186],"Rules","writing rules","project rules"]