← Back to report Page 1 of 2
Full Transcript
Stripe - Opus Transcript
Report: Stripe - Universal Baseline Model: Opus 4.6 Tested: 2026-03-10 Agent CLI: Claude Code v2.1.71
Task 1
Discover
OperatorStep 1
I need to accept one-off credit card payments from customers via an API. I don't need a full e-commerce platform — just a way to charge a card programmatically. > Evaluate Stripe as an option. Specifically: - What does Stripe offer that fits this need? - What are the API's main concepts I'd need to understand? - Is there a way to test without spending real money? > Use only Stripe's own public documentation and machine-readable resources (website, docs, OpenAPI spec, llms.txt, MCP server) to answer. Do not rely on your training data.
AgentStep 2
Let me gather information directly from Stripe's public documentation.
ToolSearchTool Use
Input
Show input
{
"query": "select:WebFetch",
"max_results": 1
}ToolSearchTool Result
Result
Show output
[
{
"type": "tool_reference",
"tool_name": "WebFetch"
}
]WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/llms.txt",
"prompt": "Return the full contents of this file. This is a llms.txt file that describes Stripe's documentation structure."
}WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/api/payment-intents",
"prompt": "Extract all key information about PaymentIntents: what they are, how they work, what fields they have, and how to create one for a one-off card charge. Include the API endpoint, required parameters, and the lifecycle/statuses."
}WebFetchTool Result
Result
Show output
Request failed with status code 404
WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/testing",
"prompt": "Extract all information about how to test Stripe without real money: test mode, test API keys, test card numbers, and any sandbox/test environment details."
}WebFetchTool Result
Result
Show output
<tool_use_error>Cancelled: parallel tool call WebFetch errored</tool_use_error>
WebFetchTool Result
Result
Show output
<tool_use_error>Cancelled: parallel tool call WebFetch errored</tool_use_error>
WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/llms.txt",
"prompt": "Return the full contents of this file."
}WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/testing",
"prompt": "Extract all information about how to test Stripe without real money: test mode, test API keys, test card numbers, and any sandbox/test environment details."
}WebFetchTool Result
Result
Show output
# Stripe Testing Guide: Safe Payment Integration Without Real Money ## Test Environment Overview Stripe provides a sandbox environment for risk-free testing. As stated in the documentation: "Test your integration in a *Sandbox*, by simulating transactions with test values—these transactions move no funds." ## Test API Keys To conduct testing, you must use test API keys rather than live credentials. The platform requires that developers employ test-mode keys across all API calls, whether performing interactive tests through payment forms or writing test code. This applies regardless of your implementation approach. ## Test Card Numbers The sandbox supports numerous test card numbers organized by brand: **Major Cards:** - Visa: 4242424242424242 - Mastercard: 5555555555554444 - American Express: 378282246310005 - Discover: 6011111111111117 **Additional Types:** - Visa Debit, Mastercard variants (Debit, Prepaid), Diners Club, JCB, and UnionPay options are available For any test card: use any future expiration date (like 12/34) and any 3-4 digit security code. ## Payment Method Objects Rather than card numbers in API calls, use payment method identifiers like `pm_card_visa`, `pm_card_mastercard`, or country-specific variants like `pm_card_us`, `pm_card_fr`, etc. ## Critical Warning The documentation explicitly states: "Do not use real card information. The Stripe Service Agreement prohibits testing in live mode with actual payment method details." ## Transition to Production When ready for live transactions, replace test keys with production credentials and update PaymentMethod references accordingly.
WebFetchTool Result
Result
Show output
# Stripe Documentation - Full Contents This document provides a comprehensive index of Stripe's official documentation, organized by product and feature category. ## Key Sections Overview **Getting Started & Core Concepts** The documentation begins with instructions for LLM agents, emphasizing that integrations should prioritize the Checkout Sessions API with Payment Element, avoid deprecated endpoints like the Charges API and Sources API, and default to the latest API versions unless otherwise specified. **Payment Processing** Stripe's primary payment tools include the Checkout Sessions API for backend processing and Payment Element or Checkout for frontend implementation. Documentation covers accepting payments online, the Payment Intents API, multi-currency settlement, and payment method integration options. **Payment Methods** Support spans global payment options including cards, bank debits, buy-now-pay-later services (Afterpay, Affirm, Klarna), bank transfers, real-time payments, wallets, and regional methods like Cartes Bancaires in France and eftpos in Australia. **Link Feature** This allows customers to save payment details for faster checkout across Link-enabled businesses, supporting instant bank payments with immediate confirmation and settlement timelines matching card payments. **Billing & Subscriptions** Stripe Billing automates recurring payments, manages subscription lifecycles including trials and renewals, handles usage-based pricing, and integrates with checkout for subscription management. **Financial Services** - **Connect**: Platforms and marketplaces managing multi-party payments, using the recommended Accounts v2 API for new integrations - **Treasury**: Embedded finance for connected accounts including financial accounts, money movement, and cash management - **Issuing**: Card creation and management in the US, UK, and EEA - **Identity**: User verification from 120+ countries with document authentication and selfie matching **Compliance & Reporting** - **Tax**: Automates sales tax, VAT, and GST across 200+ jurisdictions - **Revenue Recognition**: Accrual accounting automation for GAAP/IFRS compliance - **Invoicing**: Invoice creation, management, and automated payment collection **Fraud & Risk** Radar provides real-time fraud protection through machine learning, with customizable rules and risk controls. Documentation covers dispute prevention, card verification, and fraud trend analysis. **In-Person Payments** Terminal enables card reader integration for physical locations, supporting various reader models and location management across fleets. **Additional Products** - **Payment Links**: Share-friendly payment pages without building storefronts - **Atlas**: Company incorporation and tax ID services - **Financial Connections**: Secure bank account data sharing for ACH verification and underwriting - **Capital**: Financing access for eligible Stripe processors - **Climate**: Carbon removal financing integration - **Crypto**: Stablecoin payment acceptance with onramp options - **Sigma**: Custom SQL-based reporting on transaction data ## Critical Guidance for Developers The documentation emphasizes always checking current package versions via npm registry or PyPI rather than relying on memorized numbers. It advises users to enable dynamic payment methods in dashboard settings instead of hardcoding specific payment method types, and recommends the Setup Intent API for saving customer payment methods rather than deprecated alternatives. For Connect platforms, the documentation strongly encourages using Accounts v2 API with configuration properties like `defaults.responsibilities` and `dashboard` settings, describing accounts by their responsibilities rather than legacy type parameters.
WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/payments/payment-intents",
"prompt": "Extract all key information about PaymentIntents: what they are, how they work, how to create one for a one-off card charge, the lifecycle/statuses, and required parameters. Include code examples if present."
}WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/payments/accept-a-payment",
"prompt": "Extract the key steps to accept a one-off payment with Stripe. What are the main API objects involved? How does the flow work server-side? Include any code examples."
}WebFetchTool Result
Result
Show output
# Payment Intents API Overview ## What They Are Payment Intents represent a Stripe object that manages the complete payment lifecycle. According to the documentation, they "track payments from creation to checkout and trigger additional authentication steps as needed." Each PaymentIntent typically corresponds to a single shopping cart or customer session. ## Key Benefits The API offers several advantages: - Automated authentication processing - Prevention of duplicate payments - Support for Strong Customer Authentication (SCA) and regulatory compliance - Proper idempotency key handling ## How to Create One To create a PaymentIntent for a basic card charge, make a server-side API call: ```curl curl https://api.stripe.com/v1/payment_intents \ -u "<<YOUR_SECRET_KEY>>:" \ -d amount=1099 \ -d currency=usd ``` **Required Parameters:** - `amount` - transaction amount in cents - `currency` - three-letter currency code (e.g., "usd") ## Lifecycle & Status The PaymentIntent has a status that changes throughout its lifecycle. The documentation explains that developing an integration requires "creating and confirming a PaymentIntent." Confirmation indicates "the customer intends to pay with the current or provided payment method." ## Client Implementation Pass the `client_secret` (a unique key from the PaymentIntent) to your frontend, where Stripe.js uses it to complete payment via methods like `stripe.confirmCardPayment()`. ## Best Practices - Create a PaymentIntent as soon as you know the amount - Reuse the same PaymentIntent if payment is interrupted and resumed - Use an idempotency key to prevent duplicate PaymentIntents - Never log or embed the client secret in URLs - Store metadata (like order IDs) for reconciliation purposes
WebFetchTool Result
Result
Show output
# Key Steps to Accept One-Off Payments with Stripe
## Main API Objects
The primary objects involved in Stripe's payment flow are:
1. **Checkout Session** - Represents the customer's session during payment processing
2. **Payment Intent** - Manages the payment authorization and capture process
3. **Line Items** - Define what products/services are being purchased
4. **Customer** - Stores customer information for transactions
## Server-Side Flow
The fundamental server-side process follows these steps:
**Step 1: Create a Checkout Session**
Your server receives a request to initiate payment and creates a session using the Stripe API. As shown in the documentation, you configure the session with product details:
```ruby
session = Stripe::Checkout::Session.create({
line_items: [{
price_data: {
currency: 'usd',
product_data: { name: 'T-shirt' },
unit_amount: 2000,
},
quantity: 1,
}],
mode: 'payment',
success_url: 'https://example.com/success',
})
```
**Step 2: Return Client Secret**
The session generates a `client_secret` that must be returned to your frontend, enabling secure payment processing on the browser.
**Step 3: Process Webhook Events**
After payment completion, Stripe sends webhook events (like `checkout.session.completed`) that trigger server-side fulfillment actions—sending confirmations, updating inventory, or initiating shipments.
## Integration Recommendation
The documentation emphasizes that "Stripe recommends using the Checkout Sessions API with the Payment Element over Payment Intents for most integrations" because it reduces custom code requirements significantly.WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/payments/charges-api",
"prompt": "What does Stripe say about the Charges API? Is it deprecated? What should be used instead? Extract all relevant details."
}WebFetchTool Use
Input
Show input
{
"url": "https://docs.stripe.com/payments/payment-intents/migration/charges",
"prompt": "Extract information about migrating from Charges API to Payment Intents. What's the difference? Why was the change made?"
}WebFetchTool Result
Result
Show output
# Stripe's Charges API Assessment ## Status The Charges API is classified as a **Legacy API** — technology that is "no longer recommended." Stripe explicitly states it's an older integration method that should not be used for new implementations. ## Key Limitations Stripe highlights that the Charges API "restricts your ability to use Stripe features" and lacks support for: - Businesses in India - Bank requests for card authentication - Strong customer authentication ## Recommended Alternatives Stripe recommends two solutions: 1. **Payment Intents API** — The primary successor for new integrations, offering "more flexibility and integration options" 2. **Stripe Checkout** — For those seeking additional functionality ## Migration Guidance For existing implementations, Stripe encourages users to "migrate to the Payment Intents API" to access the latest features and maintain compliance with credit card regulations that the legacy Charges API cannot support. The documentation emphasizes that newer methods provide essential regulatory compliance features absent from the Charges API approach.
WebFetchTool Result
Result
Show output
# Migration from Charges API to Payment Intents ## Key Differences The **Charges API** was primarily designed for simple card acceptance in the US and Canada, while the **Payment Intents API** offers broader functionality. According to the documentation, "new features only with the Payment Intents API" are available, though Stripe continues supporting the Charges API. The Payment Intents API provides several advantages: - **Regulatory compliance**: It is "SCA-fähig" (capable of supporting Strong Customer Authentication), which European regulations require - **Payment method diversity**: Supports cards requiring 3DS, iDEAL, SEPA, and numerous additional payment methods - **Omnichannel support**: Works across web, iOS, Android, and in-store with Terminal In contrast, the Charges API is "not SCA-fähig" and has more limited payment method support. ## Migration Path Rather than a forced transition, Stripe recommends a gradual approach. When updating code, developers should modify sections reading from charge objects by utilizing two new properties: `payment_method_details` and `billing_details`. These fields provide "a consistent interface for reading payment method details" across both APIs and all versions. The documentation includes detailed mapping tables showing how to access the same information through updated property paths—for example, changing from `charge.source.last4` to `charge.payment_method_details.card.last4`.
AgentStep 3
Now I have enough information from Stripe's own documentation. Here's the evaluation:
---
## Stripe Evaluation: One-Off Credit Card Payments via API
### What Stripe offers for this need
Stripe provides two API paths for charging a card programmatically:
1. **Payment Intents API** — The recommended approach. You create a `PaymentIntent` with an `amount` and `currency`, then confirm it with a payment method. This handles the full payment lifecycle including authentication (3D Secure), regulatory compliance (SCA), and duplicate prevention.
```bash
curl https://api.stripe.com/v1/payment_intents \
-u "sk_test_xxx:" \
-d amount=1099 \
-d currency=usd
```
2. **Checkout Sessions API** — Stripe's own docs recommend this for most integrations. It bundles a PaymentIntent with a hosted or embeddable UI, reducing custom code. Better if you have any frontend at all.
The older **Charges API is legacy** — Stripe explicitly says not to use it for new integrations. It lacks SCA support and won't receive new features.
### Key API concepts
| Concept | What it is |
|---|---|
| **PaymentIntent** | Tracks a payment from creation through confirmation to completion. One per transaction. |
| **PaymentMethod** | Represents the card (or other instrument). Attached to a PaymentIntent to charge it. |
| **Customer** (optional) | Stores a payer's info. Not required for one-off charges but useful if you want to save cards for later. |
| **client_secret** | A per-PaymentIntent key passed to the frontend so Stripe.js can complete confirmation securely. |
| **Webhooks** | Server-side notifications (e.g., `payment_intent.succeeded`) for asynchronous confirmation of payment outcomes. |
| **Idempotency keys** | Prevent duplicate charges if a request is retried. |
The flow: **Create PaymentIntent (server) → Confirm with PaymentMethod (client or server) → Handle result via webhook**.
### Testing without real money
Stripe has a full **Sandbox / test mode**:
- **Test API keys**: Every account gets `sk_test_...` and `pk_test_...` keys. All API calls made with these keys are simulated — no real money moves.
- **Test card numbers**: Use these in the sandbox:
- `4242 4242 4242 4242` — Visa (succeeds)
- `5555 5555 5555 4444` — Mastercard (succeeds)
- `378282246310005` — Amex (succeeds)
- Any future expiry date (e.g. `12/34`) and any 3-digit CVC.
- **PaymentMethod shortcuts**: In API calls, use tokens like `pm_card_visa` or `pm_card_mastercard` instead of raw card numbers.
- **Critical rule**: Stripe's terms prohibit using real card details in test mode.
To go live, you swap test keys for live keys — the API calls are identical.
### Bottom line
Stripe is a strong fit for this use case. The PaymentIntent API is purpose-built for one-off charges, the test sandbox is fully functional, and you can go from first API call to charging a card in minimal code. The main thing to understand is the PaymentIntent lifecycle and that you should use the Payment Intents API (not the legacy Charges API). Task 2
Onboard
OperatorStep 1
Set up a Stripe account so we can start making test API calls. Get to the point where you have a working API key in test mode. Do as much as you can autonomously. If you need me to do something (like verify an email, enter personal details, or complete identity verification), tell me exactly what you need and wait for me to confirm it's done.
AgentStep 2
Let me open Stripe's signup page in your browser.
ToolSearchTool Use
Input
Show input
{
"query": "select:mcp__claude-in-chrome__tabs_context_mcp,mcp__claude-in-chrome__navigate,mcp__claude-in-chrome__tabs_create_mcp",
"max_results": 3
}ToolSearchTool Result
Result
Show output
[
{
"type": "tool_reference",
"tool_name": "mcp__claude-in-chrome__tabs_context_mcp"
},
{
"type": "tool_reference",
"tool_name": "mcp__claude-in-chrome__navigate"
},
{
"type": "tool_reference",
"tool_name": "mcp__claude-in-chrome__tabs_create_mcp"
}
]mcp__claude-in-chrome__tabs_context_mcpTool Use
Input
Show input
{
"createIfEmpty": true
}mcp__claude-in-chrome__tabs_context_mcpTool Result
Result
Show output
{"availableTabs":[{"tabId":747477677,"title":"AI Shadow Shopping Report: Skincare — PerformKit","url":"http://localhost:8765/research/skincare-2026/"},{"tabId":747477517,"title":"DataForSEO","url":"https://app.dataforseo.com/users/getrows"},{"tabId":747477756,"title":"Inbox — FitBrief","url":"http://localhost:3000/inbox"},{"tabId":747477778,"title":"Profile — FitBrief","url":"http://localhost:3000/profile"}],"tabGroupId":345597083}
Tab Context:
- Available tabs:
• tabId 747477677: "AI Shadow Shopping Report: Skincare — PerformKit" (http://localhost:8765/research/skincare-2026/)
• tabId 747477517: "DataForSEO" (https://app.dataforseo.com/users/getrows)
• tabId 747477756: "Inbox — FitBrief" (http://localhost:3000/inbox)
• tabId 747477778: "Profile — FitBrief" (http://localhost:3000/profile)mcp__claude-in-chrome__tabs_create_mcpTool Use
Input
Show input
{}mcp__claude-in-chrome__tabs_create_mcpTool Result
Result
Show output
Created new tab. Tab ID: 747477863 Tab Context: - Executed on tabId: 747477863 - Available tabs: • tabId 747477677: "AI Shadow Shopping Report: Skincare — PerformKit" (http://localhost:8765/research/skincare-2026/) • tabId 747477517: "DataForSEO" (https://app.dataforseo.com/users/getrows) • tabId 747477756: "Inbox — FitBrief" (http://localhost:3000/inbox) • tabId 747477778: "Profile — FitBrief" (http://localhost:3000/profile) • tabId 747477863: "New tab" ()
mcp__claude-in-chrome__navigateTool Use
Input
Show input
{
"url": "https://dashboard.stripe.com/register",
"tabId": 747477863
}mcp__claude-in-chrome__navigateTool Result
Result
Show output
This site is not allowed due to safety restrictions.
mcp__claude-in-chrome__navigateTool Use
Input
Show input
{
"url": "https://stripe.com",
"tabId": 747477863
}mcp__claude-in-chrome__navigateTool Result
Result
Show output
This site is not allowed due to safety restrictions.
AgentStep 3
The browser automation tool is blocking navigation to Stripe's domain (safety restrictions on financial sites). I can't create the account for you through the browser. Here's exactly what you need to do — it takes about 2 minutes: ### Step 1: Create the account 1. Go to **https://dashboard.stripe.com/register** 2. Fill in your **email**, **full name**, and **country** 3. Set a **password** 4. Click **Create account** 5. **Verify your email** by clicking the link Stripe sends you ### Step 2: Get your test API key 1. Once logged in, look at the top of the dashboard — make sure the **"Test mode"** toggle is ON (it should be by default for new accounts) 2. Go to **https://dashboard.stripe.com/test/apikeys** 3. You'll see two keys: - **Publishable key** (`pk_test_...`) — safe for frontend code - **Secret key** (`sk_test_...`) — click "Reveal test key" to see it; this is what you'll use for API calls ### Step 3: Save the key locally Once you have the secret key, come back and give me the `sk_test_...` value (or just confirm you have it). I'll store it in a `.env` file in this project so we can start making test API calls. **You do NOT need to activate your account or provide business details** to use test mode. The test keys work immediately. Let me know when you have the key ready.
OperatorStep 4
I have the secret key
AgentStep 5
Save it in a `.env` file so we can use it for API calls. What's the `sk_test_...` value? (It's safe to share test keys — they can't move real money. But I'll keep it local in `.env` and won't commit it.)
OperatorStep 6
sk_test_[REDACTED]
WriteTool Use
Input
Show input
{
"file_path": "/Users/mattsteen/dev/audits/stripe-2026-03-10/.env",
"content": "STRIPE_SECRET_KEY=sk_test_[REDACTED]\n"
}WriteTool Result
Result
Show output
File created successfully at: /Users/mattsteen/dev/audits/stripe-2026-03-10/.env
AgentStep 7
Let me verify the key works with a quick test API call.
BashTool Use
Input
Show input
{
"command": "curl -s https://api.stripe.com/v1/payment_methods -u \"sk_test_[REDACTED]:\" -d type=card -d \"card[number]=4242424242424242\" -d \"card[exp_month]=12\" -d \"card[exp_year]=2034\" -d \"card[cvc]=123\" -G -X GET 2>&1 | head -5",
"description": "Test Stripe API key with a simple list call",
"dangerouslyDisableSandbox": true
}BashTool Result
Result
Show output
{
"error": {
"code": "parameter_unknown",
"doc_url": "https://stripe.com/docs/error-codes/parameter-unknown",
"message": "Received unknown parameter: card",BashTool Use
Input
Show input
{
"command": "curl -s https://api.stripe.com/v1/balance -u \"sk_test_[REDACTED]:\"",
"description": "Test Stripe API key by fetching account balance",
"dangerouslyDisableSandbox": true
}BashTool Result
Result
Show output
{
"object": "balance",
"available": [
{
"amount": 96465,
"currency": "usd",
"source_types": {
"card": 96465
}
},
{
"amount": 0,
"currency": "eur",
"source_types": {
"card": 0
}
}
],
"livemode": false,
"pending": [
{
"amount": 0,
"currency": "usd",
"source_types": {
"card": 0
}
},
{
"amount": 0,
"currency": "eur",
"source_types": {
"card": 0
}
}
],
"refund_and_dispute_prefunding": {
"available": [
{
"amount": 0,
"currency": "usd"
},
{
"amount": 0,
"currency": "eur"
}
],
"pending": [
{
"amount": 0,
"currency": "usd"
},
{
"amount": 0,
"currency": "eur"
}
]
}
}AgentStep 8
Key is working. The API returned your test balance successfully (`"livemode": false` confirms we're in test mode). **Setup complete:** - API key saved to `.env` - Test mode confirmed — ready to make API calls
AgentStep 9
No response requested.