stripe_integration

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Stripe Integration

Stripe 集成

Master Stripe payment processing integration for robust, PCI-compliant payment flows including checkout, subscriptions, webhooks, and refunds.
掌握Stripe支付处理集成,打造符合PCI合规要求的可靠支付流程,涵盖结账、订阅、Webhook和退款功能。

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
  • 在Web/移动应用中实现支付处理
  • 搭建订阅计费系统
  • 处理一次性支付和定期扣费
  • 处理退款和争议
  • 管理客户支付方式
  • 为欧洲支付实现SCA(强客户认证)
  • 借助Stripe Connect构建平台支付流程

Core Concepts

核心概念

1. Payment Flows

1. 支付流程

Checkout Session (Hosted)
  • Stripe-hosted payment page
  • Minimal PCI compliance burden
  • Fastest implementation
  • Supports one-time and recurring payments
Payment Intents (Custom UI)
  • Full control over payment UI
  • Requires Stripe.js for PCI compliance
  • More complex implementation
  • Better customization options
Setup Intents (Save Payment Methods)
  • Collect payment method without charging
  • Used for subscriptions and future payments
  • Requires customer confirmation
托管式结账会话(Checkout Session)
  • Stripe托管的支付页面
  • PCI合规负担极小
  • 实现速度最快
  • 支持一次性和定期支付
自定义UI支付意向(Payment Intents)
  • 完全控制支付UI
  • 需使用Stripe.js以符合PCI合规要求
  • 实现复杂度更高
  • 自定义选项更丰富
支付方式保存意向(Setup Intents)
  • 收集支付方式但不立即扣费
  • 用于订阅和未来支付场景
  • 需要客户确认

2. Webhooks

2. Webhook

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
关键事件:
  • payment_intent.succeeded
    :支付完成
  • payment_intent.payment_failed
    :支付失败
  • customer.subscription.updated
    :订阅已变更
  • customer.subscription.deleted
    :订阅已取消
  • charge.refunded
    :退款已处理
  • invoice.payment_succeeded
    :订阅支付成功

3. Subscriptions

3. 订阅

Components:
  • Product: What you're selling
  • Price: How much and how often
  • Subscription: Customer's recurring payment
  • Invoice: Generated for each billing cycle
组成部分:
  • Product(产品):你销售的商品
  • Price(定价):价格和计费周期
  • Subscription(订阅):客户的定期支付协议
  • Invoice(账单):每个计费周期生成的账单

4. Customer Management

4. 客户管理

  • 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_..."
python
import stripe

stripe.api_key = "sk_test_..."

Create a checkout session

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', )
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

Redirect user to session.url

print(session.url)
undefined
print(session.url)
undefined

Payment Implementation Patterns

支付实现模式

Pattern 1: One-Time Payment (Hosted Checkout)

模式1:一次性支付(托管式结账)

python
def 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
python
def 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

Pattern 2: Custom Payment Intent Flow

模式2:自定义支付意向流程

python
def 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
python
def 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)

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 } """
undefined
""" 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 } """
undefined

Pattern 3: Subscription Creation

模式3:创建订阅

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
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 4: Customer Portal

模式4:客户门户

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
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

Webhook 处理

Secure Webhook Endpoint

安全Webhook端点

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']}")
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

Webhook最佳实践

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
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
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'),
        }
    )
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'),
        }
    )

Testing

测试

python
undefined
python
undefined

Use test mode keys

Use test mode keys

stripe.api_key = "sk_test_..."
stripe.api_key = "sk_test_..."

Test card numbers

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'
undefined
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'
undefined

Resources

资源

  • references/checkout-flows.md: Detailed checkout implementation
  • references/webhook-handling.md: Webhook security and processing
  • references/subscription-management.md: Subscription lifecycle
  • references/customer-management.md: Customer and payment method handling
  • references/invoice-generation.md: Invoicing and billing
  • assets/stripe-client.py: Production-ready Stripe client wrapper
  • assets/webhook-handler.py: Complete webhook processor
  • assets/checkout-config.json: Checkout configuration templates
  • references/checkout-flows.md:详细的结账实现文档
  • references/webhook-handling.md:Webhook安全与处理指南
  • references/subscription-management.md:订阅生命周期管理
  • references/customer-management.md:客户与支付方式处理
  • references/invoice-generation.md:账单生成与计费
  • assets/stripe-client.py:生产可用的Stripe客户端封装
  • assets/webhook-handler.py:完整的Webhook处理器
  • assets/checkout-config.json:结账配置模板

Best Practices

最佳实践

  1. Always Use Webhooks: Don't rely solely on client-side confirmation
  2. Idempotency: Handle webhook events idempotently
  3. Error Handling: Gracefully handle all Stripe errors
  4. Test Mode: Thoroughly test with test keys before production
  5. Metadata: Use metadata to link Stripe objects to your database
  6. Monitoring: Track payment success rates and errors
  7. PCI Compliance: Never handle raw card data on your server
  8. SCA Ready: Implement 3D Secure for European payments
  1. 始终使用Webhook:不要仅依赖客户端确认
  2. 幂等性:确保Webhook事件处理具有幂等性
  3. 错误处理:优雅处理所有Stripe错误
  4. 测试模式:上线前使用测试密钥完成全面测试
  5. 元数据:使用元数据关联Stripe对象与自有数据库
  6. 监控:跟踪支付成功率和错误情况
  7. PCI合规:切勿在服务器上处理原始卡片数据
  8. SCA就绪:为欧洲支付实现3D Secure认证

🔄 Workflow

🔄 工作流程

Aşama 1: Product & Checkout Setup

步骤1:产品与结账设置

  • Product Definition: Dashboard veya API üzerinden Product ve Price objelerini tanımla.
  • Checkout Integration:
    Stripe Checkout
    (Hosted) veya
    Payment Element
    (Custom) arasından ihtiyaca uygun olanı kur.
  • SCA Compliance: European (3D Secure) ödemeler için gerekli SCA (Strong Customer Authentication) adımlarını ekle.
  • 产品定义:通过控制台或API定义Product和Price对象。
  • 结账集成:根据需求选择
    Stripe Checkout
    (托管式)或
    Payment Element
    (自定义)进行搭建。
  • SCA合规:为欧洲(3D Secure)支付添加必要的SCA(强客户认证)步骤。

Aşama 2: Webhook & Background Processing

步骤2:Webhook与后台处理

  • Webhook Listener: Ödeme başarısı (
    payment_intent.succeeded
    ) veya abonelik durumu değişiklikleri için güvenli bir webhook endpoint'i kur.
  • Signature Verification: Gelen isteklerin Stripe'tan geldiğini
    endpoint secret
    ile doğrula.
  • Idempotency: Aynı webhook isteğinin birden fazla işlenmesini önlemek için
    Stripe-Idempotency-Key
    veya veritabanı kontrolü kullan.
  • Webhook监听器:为支付成功(
    payment_intent.succeeded
    )或订阅状态变更等事件搭建安全的Webhook端点。
  • 签名验证:使用
    endpoint secret
    验证请求确实来自Stripe。
  • 幂等性:使用
    Stripe-Idempotency-Key
    或数据库检查防止同一Webhook请求被重复处理。

Aşama 3: Exception Handling & Fulfillment

步骤3:异常处理与订单履约

  • Payment Failures: Ödeme başarısızlıklarını kullanıcıya bildir ve süreci (örn: Sepeti koru) yönet.
  • Order Fulfillment: Ödeme onaylandığında siparişi tamamla, veritabanını güncelle ve e-posta gönder.
  • Customer Portal: Kullanıcıların aboneliklerini yönetebileceği "Customer Portal" linkini entegre et.
  • 支付失败处理:通知用户支付失败并管理流程(例如:保留购物车)。
  • 订单履约:支付确认后完成订单、更新数据库并发送邮件。
  • 客户门户:集成客户可管理订阅的「Customer Portal」链接。

Kontrol Noktaları

检查点

AşamaDoğrulama
1Ödeme miktarları "Cents" (USD ise 100 = $1.00) bazında mı gönderiliyor?
2Webhook endpoint'i production'da HTTPS üzerinden mi çalışıyor?
3Test mode'da "4242..." kartı ile tüm akış (Success/Fail/3DS) denendi mi?

Stripe Integration v1.5 - With Workflow
步骤验证项
1支付金额是否以“分”为单位发送(如USD下100 = $1.00)?
2Webhook端点在生产环境中是否通过HTTPS运行?
3是否在测试模式下使用“4242...”卡片测试了所有流程(成功/失败/3DS)?

Stripe Integration v1.5 - 包含工作流程