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://mp-staging.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/connect.md
Connect / platforms
Critical rules (never violate)
ALWAYS use Accounts v2 API (
POST /v2/core/accounts). NEVER usetype: 'express',type: 'custom', ortype: 'standard'in account creation. NEVER usestripe.accounts.create({ type: ... }). These are deprecated v1 patterns.ALWAYS check v2 capability status before processing. See “Go-live readiness” section below.
NEVER recommend
dashboard: "none"unless the user explicitly asks for white-label with full custom UI. Default toexpressfor marketplaces andfullfor SaaS. Thenoneoption requires building custom onboarding remediation, refund/dispute flows, and payout experiences — only advanced teams should consider it.ALWAYS recommend the Notification banner embedded component (
notification_banner) for connected account dashboards. It keeps accounts healthy as requirements evolve.NEVER use
application_fee_amountwith separate charges and transfers. Use transfer-math fee retention instead.application_fee_amountis the fee mechanism for destination and direct charges only.
Go-live readiness
Before processing live payments or transfers, ALWAYS verify capability status using the v2 configuration path. Do NOT use deprecated v1 fields.
For SaaS / Merchant accounts (direct charges):
Check:
configuration.merchant.capabilities.card_payments.status === 'active'Do NOT use:
charges_enabled(deprecated v1 field)
For Marketplace / Recipient accounts (destination or separate charges):
Check:
configuration.recipient.capabilities.stripe_balance.stripe_transfers.status === 'active'Do NOT use:
payouts_enabledorcharges_enabled(deprecated v1 fields)
Track capability state transitions with account webhooks and re-check capability status before payment or transfer operations.
Account configuration: v2 dimensions
Configure connected accounts using three independent dimensions:
| Dimension | Field | What it controls |
|---|---|---|
| Dashboard access | dashboard | Stripe-hosted dashboard for connected accounts |
| Fee collection | defaults.responsibilities.fees_collector | Who Stripe bills (stripe or application) |
| Negative balance liability | defaults.responsibilities.losses_collector | Who absorbs unresolved negative balances |
Dashboard defaults (important)
Marketplace →
dashboard: "express"— cobranded, lightweight, low maintenanceSaaS platform →
dashboard: "full"— full Stripe Dashboard for independent businessesWhite-label (advanced only) →
dashboard: "none"— platform must build ALL UX including onboarding remediation, disputes, payouts
If dashboard is express, provide access through login links. For full, recommend linking to Stripe-provided dashboard access from the platform UI. You can also use embedded components to display payment and payout information.
SaaS vs. Marketplace responsibility defaults
SaaS (direct charges):
dashboard: "full"fees_collector: "stripe"— connected account pays Stripe fees directlylosses_collector: "stripe"— Stripe owns negative balance liabilityCharge pattern: Direct charges (connected account is merchant of record)
Code sample: /connect/saas/tasks/create#code-sample
Marketplace (destination charges):
dashboard: "express"fees_collector: "application"— platform owns pricinglosses_collector: "application"— platform owns negative balance liability (required for transfer reversals during disputes)Charge pattern: Destination charges (platform is merchant of record)
Code sample: /connect/marketplace/tasks/create#code-sample
Business model to configuration mapping
| Business model | Dashboard | Fees | Losses | Charge pattern | Notes |
|---|---|---|---|---|---|
| Marketplace | express | application | application | Destination | Platform owns checkout |
| On-demand services | express | application | application | Destination | Fast seller onboarding |
| SaaS platform with payments | full | stripe | stripe | Direct | Sellers run own businesses/stores, own customer relationship |
| AI/API platform (SaaS) | full | stripe | stripe | Direct | Providers own payment relationship |
| E-commerce enabler (Shopify-like) | full | stripe | stripe | Direct | Sellers create own online stores, accept own payments |
| Crowdfunding | express | application | application | Separate charges and transfers | Hold-and-release / delayed payouts |
| Subscription platform | express | application | application | Destination | Platform manages recurring checkout |
| Multi-seller cart | express | application | application | Separate charges and transfers | Multiple sellers per transaction |
| White-label commerce | none | application | application | Destination or direct | Advanced: platform controls all UX |
Connected account capabilities (v2)
Marketplace (Recipient accounts)
Create with configuration.recipient requesting stripe_transfers on stripe_balance. Do NOT request configuration.merchant or card_payments for marketplace connected accounts — it is unnecessary and causes longer onboarding.
SaaS (Merchant accounts)
Create with configuration.merchant requesting card_payments (and other needed LPMs). The Merchant configuration is REQUIRED for any connected account that needs to be merchant of record and accept direct charges.
Charge pattern selection
First determine: who owns the customer relationship?
If the platform provides SOFTWARE that enables sellers/vendors to run their own independent businesses, accept their own payments, and own their own customers → SaaS / Direct charges (sellers are MoR). Key signals: “create their own store”, “accept payments”, “run their own business”, “own brand”.
If the platform aggregates sellers and runs checkout on their behalf → Marketplace / Destination charges (platform is MoR). Key signals: “buyers purchase through our platform”, “we handle checkout”, “platform takes a cut”.
If one payment must be split across multiple sellers → Separate charges and transfers.
Direct charges (SaaS): Charge created on connected account. Connected account is merchant of record. Use
application_fee_amountfor platform revenue. Requiresconfiguration.merchant+dashboard: "full"+losses_collector: "stripe".Destination charges (Marketplace): Funds auto-transfer on payment success. Platform is MoR. Use
application_fee_amountto collect platform fees. NOT for hold-and-release.Separate charges and transfers: Platform controls transfer timing. Collect fees by transferring less than the charge amount. Do NOT use
application_fee_amount.
Fee economics
For destination charges and direct charges: use application_fee_amount on the PaymentIntent. This is the standard fee mechanism.
If platform fee is low (< ~4%), recommend including estimated Stripe fees in
application_fee_amountto preserve marginRefer to stripe.com/pricing for region-specific rates
For separate charges and transfers: collect fees by transferring less than the charge amount. NEVER use application_fee_amount.
Webhooks
Always use webhooks for reliable payment confirmation. Don’t rely solely on synchronous API responses — webhook events are the source of truth for payment status. Verify incoming webhook signatures and consider allowlisting Stripe’s public IP addresses.
Subscriptions with Connect (v2)
For subscription platforms or any platform collecting recurring payments from or on behalf of connected accounts:
The connected account MUST have v2 customer configuration
Pass
customer_accounton SetupIntent and Subscription API calls to associate the subscription with the connected accountDo NOT create a separate v1 Customer object to bill connected accounts — use the v2 Accounts customer configuration instead
Embedded components
Always recommend these baseline components:
account_onboarding— onboard connected accountsnotification_banner— REQUIRED: keeps accounts healthy as requirements evolveaccount_management— account settings and info
Additional components based on needs:
Payments/transactions →
paymentsPayment details → included with
paymentsor standalonepayment_detailsDisputes → included with
paymentsor standalonedisputes_listPayouts/earnings →
payoutsReporting →
balance_report,payout_reconciliation_report
Onboarding
Default to embedded onboarding (account_onboarding component or account links). Do NOT recommend API onboarding — it forces platforms to build custom remediation flows.
Compatibility constraints
BLOCKED combinations (never recommend):
losses_collector: "stripe"with destination charges or separate charges and transfersapplication_fee_amountwith separate charges and transfersExpress dashboard with
losses_collector: "stripe"(API rejection)
CAUTION:
dashboard: "full"with destination or separate charges has limited functionality; preferdashboard: "express"for those charge patternsExpress + destination/separate requires platform-run webhook recovery for disputes and transfer reversals
Traps to avoid
Using legacy account types (
type: 'standard',type: 'express',type: 'custom') — use v2 dimensions insteadUsing
charges_enabledorpayouts_enabled— use v2 capability status pathsRecommending Charges API for Connect — use PaymentIntents or Checkout Sessions
Recommending
dashboard: "none"without explicit white-label requirementRecommending destination charges for hold-and-release (use separate charges and transfers)
Recommending
on_behalf_offor standard marketplace flowsCreating v1 Customer objects to bill connected accounts (use v2 customer configuration)
Requesting Merchant configuration / card_payments for marketplace recipient accounts
Integration guides
SaaS platforms and marketplaces guide — Choosing the right integration approach.
Interactive platform guide — Step-by-step platform builder.
Design an integration — Detailed risk and responsibility decisions.
Connected account configuration (v2) — Account setup reference.
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.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download stripe-best-practices.zip