Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
.claude/skills/asymmetric-al-stripe-integration/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-15 | ✗→✓ | ▲ Improved | 192% | 0% |
| case-13 | ✓→✓ | = Same ✓ | 220% | 0% |
| case-01 | ✓→✓ | = Same ✓ | 207% | 0% |
| case-02 | ✓→✓ | = Same ✓ | 196% | 0% |
| case-03 | ✓→✓ | = Same ✓ | 303% | 0% |
Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.
Checkout Session (Hosted)
Payment Intents (Custom UI)
Setup Intents (Save Payment Methods)
Critical Events:
payment_intent.succeeded: Payment completedpayment_intent.payment_failed: Payment failedcustomer.subscription.updated: Subscription changedcustomer.subscription.deleted: Subscription canceledcharge.refunded: Refund processedinvoice.payment_succeeded: Subscription payment successfulComponents:
pythonimport stripe stripe.api_key = "sk_test_..." # Create a checkout session session = stripe.checkout.Session.create( payment_method_types=['card'], 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)
pythondef create_checkout_session(amount, currency='usd'): """Create a one-time payment checkout session.""" try: session = stripe.checkout.Session.create( payment_method_types=['card'], line_items=[{ 'price_data': { 'currency': currency, 'product_data': { 'name': 'Purchase', '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
pythondef create_payment_intent(amount, currency='usd', customer_id=None): """Create a payment intent for custom checkout UI.""" 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 # Frontend (JavaScript) """ const stripe = Stripe('pk_test_...'); const elements = stripe.elements(); const cardElement = elements.create('card'); cardElement.mount('#card-element'); const {error, paymentIntent} = await stripe.confirmCardPayment( clientSecret, { payment_method: { card: cardElement, billing_details: { name: 'Customer Name' } } } ); if (error) { // Handle error } else if (paymentIntent.status === 'succeeded') { // Payment successful } """
pythondef 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
pythondef 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
pythonfrom 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']}")
pythonimport 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
pythondef 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
pythondef 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'), } )
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, currency='usd', customer=customer.id, payment_method_types=['card'] ) # Confirm with test card confirmed = stripe.PaymentIntent.confirm( intent.id, payment_method='pm_card_visa' # Test payment method ) assert confirmed.status == 'succeeded'
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-13 | pass→pass | 7,751 | 7,355 | -5% | 1 | 1 | 0% | 1,503 | 4,812 | +220% | 0 | 0 | — |
case-01 | pass→pass | 7,697 | 8,476 | +10% | 1 | 1 | 0% | 1,607 | 4,928 | +207% | 0 | 0 | — |
case-02 | pass→pass | 7,732 | 6,425 | -17% | 1 | 1 | 0% | 1,510 | 4,477 | +196% | 0 | 0 | — |
case-03 | pass→pass | 6,807 | 7,945 | +17% | 1 | 1 | 0% | 1,186 | 4,776 | +303% | 0 | 0 | — |
case-04 | pass→pass | 9,515 | 6,745 | -29% | 1 | 1 | 0% | 1,605 | 4,501 | +180% | 0 | 0 | — |
case-05 | pass→pass | 5,795 | 6,718 | +16% | 1 | 1 | 0% | 1,128 | 4,496 | +299% | 0 | 0 | — |
case-06 | pass→pass | 12,695 | 8,658 | -32% | 1 | 1 | 0% | 2,169 | 4,823 | +122% | 0 | 0 | — |
case-07 | pass→pass | 8,100 | 6,889 | -15% | 1 | 1 | 0% | 1,511 | 4,492 | +197% | 0 | 0 | — |
case-08 | pass→pass | 12,651 | 12,867 | +2% | 1 | 1 | 0% | 2,485 | 5,720 | +130% | 0 | 0 | — |
case-09 | pass→pass | 4,816 | 3,898 | -19% | 1 | 1 | 0% | 894 | 3,926 | +339% | 0 | 0 | — |
case-10 | pass→pass | 18,849 | 16,138 | -14% | 1 | 1 | 0% | 3,508 | 6,397 | +82% | 0 | 0 | — |
case-11 | pass→pass | 6,405 | 6,538 | +2% | 1 | 1 | 0% | 1,314 | 4,637 | +253% | 0 | 0 | — |
case-12 | pass→pass | 6,223 | 4,738 | -24% | 1 | 1 | 0% | 1,154 | 4,142 | +259% | 0 | 0 | — |
case-14 | pass→pass | 3,996 | 4,008 | +0% | 1 | 1 | 0% | 627 | 3,935 | +528% | 0 | 0 | — |
case-15 | fail→pass | 9,435 | 9,765 | +3% | 1 | 1 | 0% | 1,767 | 5,157 | +192% | 0 | 0 | — |
case-16 | pass→pass | 6,223 | 4,976 | -20% | 1 | 1 | 0% | 1,076 | 4,064 | +278% | 0 | 0 | — |
case-17 | pass→pass | 6,150 | 4,396 | -29% | 1 | 1 | 0% | 1,000 | 3,933 | +293% | 0 | 0 | — |
case-18 | pass→pass | 6,071 | 5,839 | -4% | 1 | 1 | 0% | 1,142 | 4,350 | +281% | 0 | 0 | — |
case-19 | pass→pass | 2,541 | 1,861 | -27% | 1 | 1 | 0% | 410 | 3,517 | +758% | 0 | 0 | — |
case-20 | pass→pass | 9,640 | 4,490 | -53% | 1 | 1 | 0% | 1,741 | 4,039 | +132% | 0 | 0 | — |
case-21 | pass→pass | 7,583 | 4,351 | -43% | 1 | 1 | 0% | 1,501 | 4,033 | +169% | 0 | 0 | — |
case-22 | pass→pass | 4,989 | 4,252 | -15% | 1 | 1 | 0% | 776 | 3,932 | +407% | 0 | 0 | — |
case-23 | fail→fail | 5,847 | 6,547 | +12% | 1 | 1 | 0% | 1,134 | 4,521 | +299% | 0 | 0 | — |
case-24 | pass→pass | 4,082 | 5,491 | +35% | 1 | 1 | 0% | 797 | 4,317 | +442% | 0 | 0 | — |
case-25 | pass→pass | 12,591 | 15,116 | +20% | 1 | 1 | 0% | 2,084 | 6,150 | +195% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 25 cases were attempted. The headline lift of +4 percentage points is the difference between those two pass rates over the 25 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.