This commit is contained in:
Sawyer Hollenshead
2026-02-20 14:35:06 -08:00
parent b9a6404352
commit 9da3e5598e

View File

@@ -114,7 +114,7 @@ def create_checkout_session(amount, currency='usd'):
'price_data': { 'price_data': {
'currency': currency, 'currency': currency,
'product_data': { 'product_data': {
'name': 'Purchase', 'name': 'Blue T-shirt',
'images': ['https://example.com/product.jpg'], 'images': ['https://example.com/product.jpg'],
}, },
'unit_amount': amount, # Amount in cents 'unit_amount': amount, # Amount in cents
@@ -136,7 +136,7 @@ def create_checkout_session(amount, currency='usd'):
raise raise
``` ```
### Pattern 2: Checkout Sessions with Payment Element ### Pattern 2: Elements with Checkout Sessions
```python ```python
def create_checkout_session_for_elements(amount, currency='usd'): def create_checkout_session_for_elements(amount, currency='usd'):
@@ -147,7 +147,7 @@ def create_checkout_session_for_elements(amount, currency='usd'):
line_items=[{ line_items=[{
'price_data': { 'price_data': {
'currency': currency, 'currency': currency,
'product_data': {'name': 'Purchase'}, 'product_data': {'name': 'Blue T-shirt'},
'unit_amount': amount, 'unit_amount': amount,
}, },
'quantity': 1, 'quantity': 1,
@@ -155,53 +155,93 @@ def create_checkout_session_for_elements(amount, currency='usd'):
return_url='https://yourdomain.com/complete?session_id={CHECKOUT_SESSION_ID}' return_url='https://yourdomain.com/complete?session_id={CHECKOUT_SESSION_ID}'
) )
return session.client_secret # Send to frontend return session.client_secret # Send to frontend
```
# Frontend (JavaScript) ```javascript
""" const stripe = Stripe("pk_test_...");
const stripe = Stripe('pk_test_...'); const appearance = { theme: "stripe" };
const appearance = { theme: 'stripe' };
const checkout = stripe.initCheckout({ const checkout = stripe.initCheckout({
clientSecret, clientSecret,
elementsOptions: { appearance } elementsOptions: { appearance },
}); });
const loadActionsResult = await checkout.loadActions(); const loadActionsResult = await checkout.loadActions();
if (loadActionsResult.type === 'success') { if (loadActionsResult.type === "success") {
const {actions} = loadActionsResult; const { actions } = loadActionsResult;
const session = actions.getSession(); const session = actions.getSession();
const button = document.getElementById('pay-button'); const button = document.getElementById("pay-button");
const checkoutContainer = document.getElementById('checkout-container'); const checkoutContainer = document.getElementById("checkout-container");
const emailInput = document.getElementById('email'); const emailInput = document.getElementById("email");
const emailErrors = document.getElementById('email-errors'); const emailErrors = document.getElementById("email-errors");
const errors = document.getElementById('confirm-errors'); const errors = document.getElementById("confirm-errors");
// Display a formatted string representing the total amount // Display a formatted string representing the total amount
checkoutContainer.append(`Total: ${session.total.total.amount}`); checkoutContainer.append(`Total: ${session.total.total.amount}`);
// Mount Payment Element // Mount Payment Element
const paymentElement = checkout.createPaymentElement(); const paymentElement = checkout.createPaymentElement();
paymentElement.mount('#payment-element'); paymentElement.mount("#payment-element");
// Store email for submission // Store email for submission
emailInput.addEventListener('blur', () => { emailInput.addEventListener("blur", () => {
actions.updateEmail(emailInput.value).then((result) => { actions.updateEmail(emailInput.value).then((result) => {
if (result.error) emailErrors.textContent = result.error.message; if (result.error) emailErrors.textContent = result.error.message;
}); });
}); });
// Handle form submission // Handle form submission
button.addEventListener('click', () => { button.addEventListener("click", () => {
actions.confirm().then((result) => { actions.confirm().then((result) => {
if (result.type === 'error') errors.textContent = result.error.message; if (result.type === "error") errors.textContent = result.error.message;
}); });
}); });
} }
"""
``` ```
### Pattern 3: Subscription Creation ### 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,
},
)
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 ```python
def create_subscription(customer_id, price_id): def create_subscription(customer_id, price_id):
@@ -224,7 +264,7 @@ def create_subscription(customer_id, price_id):
raise raise
``` ```
### Pattern 4: Customer Portal ### Pattern 5: Customer Portal
```python ```python
def create_customer_portal_session(customer_id): def create_customer_portal_session(customer_id):
@@ -477,3 +517,7 @@ def test_payment_flow():
- **Hardcoded Amounts**: Use cents/smallest currency unit - **Hardcoded Amounts**: Use cents/smallest currency unit
- **No Retry Logic**: Implement retries for API calls - **No Retry Logic**: Implement retries for API calls
- **Ignoring Test Mode**: Test all edge cases with test cards - **Ignoring Test Mode**: Test all edge cases with test cards
```
```