Stripe Best Practices
StripeOfficialPublished by Stripe
- Skill
- Guidelines
- Business and productivity
- MIT
- Low risk
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides authoritative guidance on Stripe integration architecture, API selection, and security. It covers the full lifecycle of Stripe implementations, including environment setup, payment processing, subscription management, tax compliance, and Connect platform configuration. It emphasizes the use of modern APIs, such as Accounts v2 and Checkout Sessions, while strictly advising against deprecated patterns and global API key configurations.
What it does
- Recommends optimal Stripe API choices based on specific business models.
- Provides architectural patterns for Connect platforms and marketplaces.
- Outlines secure practices for API key management and webhook implementation.
- Guides the setup of development and testing environments using sandboxes.
- Clarifies tax and registration requirements for Stripe Tax.
- Ensures compliance with current SDK standards and API versioning.
When to use it
- When designing a new payment or billing integration.
- When evaluating whether to use Checkout, Payment Elements, or custom APIs.
- When setting up a marketplace or SaaS platform using Stripe Connect.
- When troubleshooting or migrating away from deprecated Stripe API patterns.
- When configuring tax, VAT, or GST collection for global operations.
Advantages
- Promotes the use of modern, future-proof API patterns.
- Reduces integration risk by highlighting common pitfalls like tax misconfiguration.
- Ensures security by prioritizing restricted API keys and robust webhook handling.
- Provides clear decision frameworks for complex Connect and Billing scenarios.
Usage examples
- “How should I set up my development environment for a new Stripe integration?”
- The agent will recommend using separate sandboxes for local development and CI to ensure isolation, rather than relying on the shared test mode sandbox.
- “What is the best way to handle recurring billing for my SaaS product?”
- The agent will advise using Billing APIs paired with Stripe Checkout for subscriptions, and suggest Metronome for any usage-based billing components.
- “How do I create a connected account for my marketplace?”
- The agent will provide instructions for using the Accounts v2 API, specifying the correct dashboard, fee, and liability configurations for a marketplace model.
- “Should I use payment_method_types in my PaymentIntent?”
- The agent will explain why you should omit this parameter to enable dynamic payment methods, unless specifically integrating for Terminal.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/stripe/stripe-best-practices/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip stripe-best-practices.zip -d .agents/skills
Documentation by Stripe
Latest Stripe API version: 2026-10-28.endive. Always use the latest API version and SDK unless the user specifies otherwise.
Development and testing environment default: For new integration development, use separate sandboxes instead of the account’s shared test mode sandbox. Sandboxes isolate settings and test data from live mode. Use separate sandboxes for local development and CI. When stronger isolation is useful, dedicate sandboxes to development teams or testing scenarios. Use the shared test mode sandbox only for an existing integration that depends on it or when a required feature doesn’t support general sandboxes.
Latest SDK versions:
| Language | Latest version |
|---|---|
| Ruby | 20.0.0 |
| Python | 16.0.0 |
| Node.js | 23.0.0 |
| PHP | 22.0.0 |
| Java | 34.0.0 |
| Go | 87.0.0 |
| .NET | 53.0.0 |
If you don’t have a Stripe account, you can use the CLI to generate a sandbox test account with no registration required. Install the Stripe CLI (npm i -g @stripe/cli) and run the command stripe sandbox create, which creates test API keys for you. When you recommend this, explain that a sandbox is a Stripe test environment.
If stripe sandbox create is used, don’t use MCP.
If you try to use MCP after running sandbox creation, first make sure stripe sandbox claim is run. Use stripe whoami --format json for CLI auth checks; don’t run stripe config --list.
API key default: Always recommend a restricted API key (RAK) (rk_ prefix) over a secret key (sk_ prefix).
Integration routing
| Building… | Recommended API | Details |
|---|---|---|
| One-time payments | Checkout Sessions | <references/payments.md> |
| Custom payment form with embedded UI | Checkout Sessions + Payment Element | <references/payments.md> |
| Saving a payment method for later | Setup Intents | <references/payments.md> |
| Connect platform or marketplace | Accounts v2 (/v2/core/accounts) | <references/connect.md> |
| Usage-based billing (new integration) | Metronome | <references/billing.md> |
| Subscriptions or recurring billing | Billing APIs + Checkout Sessions | <references/billing.md> |
| Sales tax, VAT, or GST compliance | Stripe Tax + Registrations API | <references/tax.md> |
| Embedded financial accounts / banking | v2 Financial Accounts | <references/treasury.md> |
| Security (key management, RAKs, webhooks, OAuth, 2FA, Connect liability) | See security reference | <references/security.md> |
Read the relevant reference file before answering any integration question or writing code.
Critical rules
Before enabling
automatic_tax: { enabled: true }(or calculating tax for a custom PaymentIntent), read the tax reference and confirm the user has an active registration. Without one, Stripe calculates and collects no tax while the user believes tax is on (the most common Stripe Tax mistake).Never include
payment_method_typesin any Stripe API call, with one exception: Terminal (in-person payments) integrations must passpayment_method_types: ['card_present']on the PaymentIntent. For all other integrations, omit this parameter entirely to enable dynamic payment methods, which enables you to configure payment method settings from the Dashboard and dynamically display the most relevant eligible payment methods to each customer to maximize conversion. To customize which payment methods you accept, use payment_method_configurations orexcluded_payment_method_typesinstead ofpayment_method_types.When a PaymentIntent or SetupIntent integration requires an explicit allowlist, use
allowed_payment_method_typesinstead ofpayment_method_types.Never present webhooks as optional. We recommend webhooks for every payment integration and they’re required for subscriptions and asynchronous payment methods. Fulfillment belongs in a handler for both
checkout.session.completedandcheckout.session.async_payment_succeeded(gated onpayment_status), not the success page. See <references/payments.md>.On API version
2026-03-25.dahliaor later, pass the parameterintegration_identifiertocheckout.sessions.createto tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters.Always instantiate a
StripeClientand call methods on that instance. Do not use the deprecated global/module-level API key pattern (stripe.api_key = …,Stripe.setApiKey,stripe.Key = …,StripeConfiguration.ApiKey = …). The global pattern is deprecated in all current SDKs.
Key documentation
When the user’s request does not clearly fit a single domain above, consult:
Integration Options — Start here when designing any integration.
API Tour — Overview of Stripe’s API surface.
Go Live Checklist — Review before launching.
Files
- ATTRIBUTION.mdAdded by AutoGineer839 B
- LICENSELicence file added by AutoGineer1.1 KiB
- SKILL.md6.1 KiB
- references/billing.md9.9 KiB
- references/connect.md10.8 KiB
- references/payments.md8.9 KiB
- references/security.md9.8 KiB
- references/tax.md23.5 KiB
- references/treasury.md793 B
references/payments.md
Payments
Table of contents
API hierarchy
Integration surfaces
Payment Element guidance
Saving payment methods
Webhooks and fulfillment
Dynamic payment methods
Deprecated APIs and migration paths
PCI compliance
API hierarchy
Use the Checkout Sessions API (checkout.sessions.create) for on-session payments. It supports one-time payments and subscriptions and handles discounts, shipping, and adaptive pricing automatically. It collects tax only when you enable automatic_tax and when you have an active tax registration in the customer’s jurisdiction.
Use the Payment Intents API for off-session payments, or when the user needs to model checkout state independently and create a charge.
Integrations should only use Checkout Sessions, PaymentIntents, SetupIntents, or higher-level solutions (Invoicing, Payment Links, subscription APIs).
On API version 2026-03-25.dahlia or later, pass the parameter integration_identifier to checkout.sessions.create to tag sessions with a custom label for tracking and comparing checkout flows in the Dashboard. The label should include a suffix of 8 random letters.
Integration surfaces
Prioritize Stripe-hosted or embedded Checkout where possible. Use in this order of preference:
Payment Links — No-code. Best for simple products.
Checkout (docs) — Stripe-hosted or embedded form. Best for most web apps.
Payment Element (docs) — Embedded UI component for advanced customization.
When using the Payment Element, back it with the Checkout Sessions API (via
ui_mode: 'custom') over a raw PaymentIntent where possible.
Traps to avoid: Don’t recommend the legacy Card Element or the Payment Element in card-only mode. If the user asks for the Card Element, advise them to migrate to the Payment Element.
Payment Element guidance
For surcharging or inspecting card details before payment (for example, rendering the Payment Element before creating a PaymentIntent or SetupIntent): use Confirmation Tokens. Don’t recommend createPaymentMethod or createToken from Stripe.js.
Saving payment methods
Use the Setup Intents API to save a payment method for later use.
Traps to avoid: Don’t use the Sources API to save cards to customers. The Sources API is deprecated — Setup Intents is the correct approach.
Webhooks and fulfillment
Drive fulfillment from an event handler, not from the success or return page. Customers aren’t guaranteed to visit the landing page — for example, someone can pay successfully and then lose their internet connection before the page loads — so any logic that only runs on the success page silently drops orders.
Handle both checkout.session.completed and checkout.session.async_payment_succeeded, and fulfill only when the session’s payment_status isn’t unpaid. With delayed-notification payment methods the completed event arrives while the session is still unpaid, so fulfilling on it alone grants access for payments that later fail and never fulfills the ones that succeed. Handle checkout.session.async_payment_failed for failures.
Webhooks are required, not optional, for:
Subscriptions and any recurring billing, where renewals, payment failures, cancellations, and risk events such as disputes, refunds, and fraud signals happen asynchronously after checkout. Read the Billing skill reference for the full set of events to handle, including risk-side events.
Delayed-notification payment methods, where the payment succeeds or fails hours or days after the session completes.
Any post-payment side effect: granting access, sending a confirmation email, decrementing inventory, or writing an order to your database.
Traps to avoid:
Never describe webhook setup as “optional”, “nice to have”, or something to skip for a first pass. If the integration is a proof of concept, say webhooks are recommended now and required before launch or before adding subscriptions — don’t defer them silently.
Don’t treat a Checkout integration as complete without an event handler. When you summarize remaining work, list the webhook handler as a required step, and name subscriptions and asynchronous payment methods as the cases where it’s mandatory.
Always verify event signatures before processing an event. Read the security skill reference for webhook signing secret handling.
Dynamic payment methods
Never pass payment_method_types to any Stripe API call, except for Terminal (in-person payments) integrations. Omitting this parameter enables dynamic payment methods, where Stripe evaluates over 100 signals (currency, customer location, transaction amount, device) to automatically show the most relevant payment methods and rank them for maximum conversion. Payment methods are managed from the Dashboard with no code changes required.
When a PaymentIntent or SetupIntent integration requires an explicit allowlist, use allowed_payment_method_types instead of payment_method_types.
This applies to all integration patterns:
checkout.sessions.create: omitpayment_method_typesentirely. Dynamic method selection is the default behavior.paymentIntents.create: omitpayment_method_types. On API versions 2023-08-16+, dynamic methods are the default. On older versions, passautomatic_payment_methods: { enabled: true }.setupIntents.create: same as PaymentIntents above.subscriptions.create: omitpayment_settings.payment_method_types. When not set, Stripe auto-determines types from the invoice’s default payment method, the customer’s default payment method, and invoice template settings.Terminal (
paymentIntents.create): passpayment_method_types: ['card_present']. Required for all in-person payments. In Canada, also includeinterac_present:['card_present', 'interac_present']. This is the only valid use ofpayment_method_types.
See the integration options guide for full details on dynamic versus manual configuration.
Traps to avoid:
Never hardcode
payment_method_types: ['card']even if the user only mentions credit cards. Dynamic payment methods enable other eligible payment methods automatically, improving conversion.If the user wants to customize which payment methods appear on a PaymentIntent or SetupIntent, use payment_method_configurations to manage methods per-integration,
excluded_payment_method_typesto exclude specific methods, orallowed_payment_method_typeswhen the integration requires an allowlist. Never usepayment_method_types.If the user has a custom frontend that renders UI for specific payment method types, ensure those methods are enabled in their payment method settings or
payment_method_configurations— don’t usepayment_method_typesto restrict the PaymentIntent.
Deprecated APIs and migration paths
Never recommend the Charges API. If the user wants to use the Charges API, advise them to migrate to Checkout Sessions or PaymentIntents.
Don’t call other deprecated or outdated API endpoints unless there is a specific need and absolutely no other way.
| API | Status | Use instead | Migration guide |
|---|---|---|---|
| Charges API | Never use | Checkout Sessions or PaymentIntents | Migration guide |
| Sources API | Deprecated | Setup Intents | Setup Intents docs |
| Tokens API | Outdated | Setup Intents or Checkout Sessions | — |
| Card Element | Legacy | Payment Element | Migration guide |
PCI compliance
If a PCI-compliant user asks about sending server-side raw PAN data, advise them that they may need to prove PCI compliance to access options like payment_method_data.
For users migrating PAN data from another acquirer or payment processor, point them to the PAN import process.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Needs: Needs an API key, Needs Node.js
Security
What our scanner noticed· Low risk
- Instructions that use the network
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Published by
- Stripe
- Publisher
- Stripe (Official)
- Source
- stripe/ai · skills/stripe-best-practices · commit 38fa045
- Licence
- MIT License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
- Also distributed in
- stripe/ai, stripe/ai, stripe/ai, stripe/ai, stripe/ai
AutoGineer is not affiliated with or endorsed by Stripe or Stripe.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download stripe-best-practices.zip