Update to latest Stripe best practices

This commit is contained in:
Sawyer
2026-02-18 20:38:50 -08:00
parent 5d65aa1063
commit 2b8e3166a1

View File

@@ -21,19 +21,21 @@ Master Stripe payment processing integration for robust, PCI-compliant payment f
### 1. Payment Flows ### 1. Payment Flows
**Checkout Session (Hosted)** **Checkout Sessions**
- Stripe-hosted payment page - Recommended for most integrations
- Minimal PCI compliance burden - Supports all UI paths:
- Fastest implementation - Stripe-hosted checkout page
- Supports one-time and recurring payments - 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 (Custom UI)** **Payment Intents (Bespoke control)**
- Full control over payment UI - 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 - Requires Stripe.js for PCI compliance
- More complex implementation
- Better customization options
**Setup Intents (Save Payment Methods)** **Setup Intents (Save Payment Methods)**
@@ -109,7 +111,6 @@ def create_checkout_session(amount, currency='usd'):
"""Create a one-time payment checkout session.""" """Create a one-time payment checkout session."""
try: try:
session = stripe.checkout.Session.create( session = stripe.checkout.Session.create(
payment_method_types=['card'],
line_items=[{ line_items=[{
'price_data': { 'price_data': {
'currency': currency, 'currency': currency,
@@ -136,47 +137,64 @@ def create_checkout_session(amount, currency='usd'):
raise raise
``` ```
### Pattern 2: Custom Payment Intent Flow ### Pattern 2: Checkout Sessions with Payment Element
```python ```python
def create_payment_intent(amount, currency='usd', customer_id=None): def create_checkout_session_for_elements(amount, currency='usd'):
"""Create a payment intent for custom checkout UI.""" """Create a checkout session configured for Payment Element."""
intent = stripe.PaymentIntent.create( session = stripe.checkout.Session.create(
amount=amount, mode='payment',
currency=currency, ui_mode='custom',
customer=customer_id, line_items=[{
automatic_payment_methods={ 'price_data': {
'enabled': True, 'currency': currency,
'product_data': {'name': 'Purchase'},
'unit_amount': amount,
}, },
metadata={ 'quantity': 1,
'integration_check': 'accept_a_payment' }],
} return_url='https://yourdomain.com/complete?session_id={CHECKOUT_SESSION_ID}'
) )
return intent.client_secret # Send to frontend return session.client_secret # Send to frontend
# Frontend (JavaScript) # Frontend (JavaScript)
""" """
const stripe = Stripe('pk_test_...'); const stripe = Stripe('pk_test_...');
const elements = stripe.elements(); const appearance = { theme: 'stripe' };
const cardElement = elements.create('card');
cardElement.mount('#card-element');
const {error, paymentIntent} = await stripe.confirmCardPayment( const checkout = stripe.initCheckout({clientSecret});
clientSecret, const loadActionsResult = await checkout.loadActions();
{
payment_method: {
card: cardElement,
billing_details: {
name: 'Customer Name'
}
}
}
);
if (error) { if (loadActionsResult.type === 'success') {
// Handle error const session = loadActionsResult.actions.getSession();
} else if (paymentIntent.status === 'succeeded') { const {actions} = loadActionsResult;
// Payment successful
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 total to user
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;
});
});
} }
""" """
``` ```