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/security.md
Security best practices
Table of contents
API keys
Restricted API keys (RAKs)
IP restrictions
Incident response
Webhook security
Content Security Policy (CSP)
Mobile and client-side integrations
OAuth and CSRF protection
Two-factor authentication
Connect security
SAML and SCIM
API keys
Never include keys in source code. Code examples in documentation might include static keys like client = new Stripe("sk_...") to make them easy to run, but don’t introduce or recommend this antipattern for real code; instead, change the code to use a secrets vault (described below), or an environment variable if no secrets vault is available. Strings matching the regular expression /[sr]k_live_.*/ in source code are live Stripe API keys. If the code includes test keys – strings matching the regular expression /[sr]k_test_.*/ – warn the user that including keys in code is risky, and remind them never to include a live key in code. Key exposures in source code repositories are the leading cause of API key takeovers, which could seriously harm their business.
Always advise the user to store secret and restricted API keys in their platform’s secrets vault, never in source code or committed environment files. Platform-specific guidance for popular platforms:
AWS: Use AWS Secrets Manager or Parameter Store (as
SecureStringvalues). Do not store keys in environment variables or userdata; AWS makes a proper secrets vault easy to use. Give read permissions only to the application that needs it.Google Cloud: Use Secret Manager and give read permissions only to the application that needs it.
Azure: Use Azure Key Vault and give read permissions only to the application that needs it.
Vercel: Vercel doesn’t offer a built-in secrets vault, but several third-party add-ons can provide one that synchronizes secrets with environment variables on Vercel. Use a sensitive environment variable so the secret value is write-only and never exposed in logs or the Vercel UI.
Other platforms: Use the platform’s equivalent secrets vault. Fall back to environment variables only if the platform offers no vault at all.
Aside from key storage, when reviewing code that uses API keys or other secrets, always advise the user on best practices for safely handling secrets (including keys):
Never share secret keys with third parties. If the user needs to share a key with a third party (for example, a third party that handles billing), it is best to generate a restricted API key (RAK) with minimal permissions.
Rotate Stripe API keys when personnel with access to those keys depart.
Code must never log keys or include them in error messages or analytics. Remove keys from logs if you find them.
Use separate keys for separate environments (production, staging, QA). This limits the blast radius if any single key is compromised.
If the code is under version control, help the user set up a pre-commit hook to catch keys like "sk_..." and "rk_..." in source code.
Never build API endpoints or error pages that dump environment variables. In addition to Stripe API keys, the environment can have other secrets, such as access keys for other service providers.
Traps to avoid: Don’t embed keys in client-side code, mobile apps, or any code that runs outside your own infrastructure. Don’t suggest that users substitute a real secret key into example code — point them to best practices for managing secret API keys instead.
Restricted API keys (RAKs)
Use restricted API keys (prefix rk_) instead of secret keys (prefix sk_) wherever possible. RAKs have only the permissions you assign, so a compromised RAK can do far less damage than a compromised secret key.
Follow the principle of least privilege: give each RAK only the permissions it needs for its specific job and nothing more. Create a separate RAK for each service or use case.
Preferred migration approach:
Review the secret key’s request logs in Workbench to catalog which API calls it makes.
Create a RAK in a sandbox with matching permissions.
Use the Stripe CLI’s
stripe logs tailcommand to watch logs.Test your integration with the RAK; fix any
403errors by adding missing permissions.Create the equivalent live-mode RAK and replace the secret key.
Rotate or expire the old secret key once confident.
Traps to avoid: Don’t default to recommending secret keys. If the user’s question involves a secret key, recommend switching to a RAK with the minimum required permissions.
IP restrictions
Encourage users to configure access policies for every API key. Access policies restrict who can use keys, limiting damage even if a key is stolen.
Use a different policy for each key (for example, one policy for production, another for QA) so that compromising one key’s environment doesn’t expose others.
Incident response
If a key is exposed or compromised, follow protecting against compromised API keys, which can be summarized as:
Roll the key immediately — go to the API keys page and roll or delete the exposed key. Do this even if you’re unsure whether the key was actually used by an unauthorized party.
Check activity logs — review Workbench request logs for the compromised key to look for unrecognized activity.
Contact Stripe support if you see activity you don’t recognize.
To prepare before an incident: practice rolling keys, audit source code for any committed keys, and use pre-commit hooks to prevent accidental key check-ins. See protecting against compromised API keys.
Webhook security
Before processing any webhook event, always verify the webhook signature using Stripe’s webhook signing secret. Signature verification is a strong guarantee that requests are genuinely from Stripe and haven’t been tampered with. Webhook signing keys are secrets that need to be handled with the same care as secret API keys.
For defense in depth, also allowlist Stripe’s IP addresses on your webhook endpoint so that it accepts connections only from Stripe’s infrastructure.
Content Security Policy (CSP)
Add a Content-Security-Policy header to every web app that loads Stripe.js or uses Stripe’s hosted UIs. See Stripe’s integration security guide for the full list of CSP directives to use depending on the type of integration. At minimum, include https://*.stripe.com in the relevant directives (script-src, frame-src, connect-src), https://*.link.com if integrating assets from link.com, or both if integrating with Stripe’s embedded crypto onramp. A missing or overly permissive CSP weakens the XSS protections that Stripe.js relies on.
Traps to avoid: Don’t use default-src * or omit CSP headers.
Mobile and client-side integrations
Don’t use production secret or restricted API keys in mobile apps or other client-side code. Client-side code can be extracted and decompiled to extract keys.
For cases where a client must interact directly with Stripe, use ephemeral keys. Ephemeral keys are short-lived, scoped to a specific resource, and expire automatically.
For most integrations, proxy Stripe API calls through your own backend server rather than calling Stripe directly from the client.
OAuth and CSRF protection
When implementing Connect OAuth flows, always use the state parameter to protect against CSRF attacks. Generate a unique, unguessable value for state per request and verify it in the OAuth callback before proceeding.
This applies to all Stripe OAuth surfaces: Connect, Link, and Stripe Apps.
Two-factor authentication
Recommend passkeys or authenticator apps rather than SMS-based 2FA for Stripe Dashboard access. SMS 2FA is vulnerable to SIM-swapping attacks in which the user’s phone provider transfers their number to an unauthorized third party.
Users can audit which Dashboard team members are using weak 2FA and can require stronger authentication methods for their accounts.
Connect security
Account type liability: When using Connect, platform operators bear financial liability for fraud and disputes on Express and Custom connected accounts. Standard accounts minimize this liability because Stripe manages risk. Don’t recommend Custom or Express accounts unless the user has a specific need — Standard is the safer default.
Connect onboarding: Use Stripe-hosted onboarding rather than building a custom onboarding flow. Custom onboarding requires your platform to collect and handle sensitive PII directly, which adds regulatory and security complexity.
SAML and SCIM
For teams managing Dashboard access, recommend SSO via SAML to federate authentication with an existing identity provider (Okta, Google, etc.). SSO centralizes access control and simplifies offboarding.
SCIM provisioning automates user provisioning and deprovisioning, ensuring that employees who leave the organization lose Dashboard access promptly.
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