> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ancha.io/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These docs describe the Ancha CLI, npm package @ancha-labs/cli version 0.1.4, and the hosted workspace at app.ancha.io. Coding agents should start at https://docs.ancha.io/coding-agents. Run the CLI as `ancha` after `npm install -g @ancha-labs/cli`, or as `npx -y @ancha-labs/cli@0.1.4` without installing. Pass --json for machine-readable output, or set ANCHA_JSON=1. Every command ends with a `next:` line naming the next command. Exit codes: 0 pass, 1 a check failed or a comparison regressed, 2 usage, config or authentication error, 3 infrastructure error, 4 unimplemented endpoint with --strict.

# Stripe

> A stateful replica of the Stripe API in test mode: customers, products and prices, subscriptions, invoices and invoice items, payment intents, charges, refunds and the balance.

The Stripe replica implements 34 endpoints of the Stripe API, version `2026-10-28.endive`, in test mode. Its key is `stripe`. It was tested with the `stripe` Node SDK.

## Connect

| Variable | Value |
| - | - |
| `STRIPE_API_URL` | Base URL. Paths start with `/v1/`. |
| `STRIPE_SECRET_KEY` | Fake test-mode secret key. Send `Authorization: Bearer <key>`. |
| `STRIPE_API_HOST_URL` | The same replica as a host name, `<env>-stripe.localhost`, for clients that can only change the host. It resolves only on the computer that runs the world server. |

```js Node theme={null}
import Stripe from 'stripe';
const stripe = new Stripe(process.env.STRIPE_SECRET_KEY!, { maxNetworkRetries: 0, httpClient: Stripe.createFetchHttpClient((input, init) => {
  const url = new URL(String(input));
  return fetch(process.env.STRIPE_API_URL + url.pathname + url.search, init);
}) });
const customers = await stripe.customers.list({ limit: 10 });
```

This is what `ancha connect stripe --lang ts` prints. Stripe's SDK has no base-path option, so the custom fetch client prefixes every request with `STRIPE_API_URL`. That works inside a container and against a hosted workspace too.

## Endpoints

| Method | Path | Support |
| - | - | - |
| `POST` | `/v1/customers` | partial: `invoice_settings` supports `default_payment_method` only; addresses, shipping, tax IDs and cash balances are gaps |
| `GET` | `/v1/customers` | supported |
| `GET` | `/v1/customers/search` | partial: `query` supports `email`, `name`, `phone`, `metadata["key"]` and `created` with `:`, `~`, `>`, `<`, `-`, `AND` and `OR` |
| `GET`, `POST` | `/v1/customers/:id` | supported |
| `DELETE` | `/v1/customers/:id` | partial: cancels the customer's subscriptions, as Stripe does |
| `GET` | `/v1/products`, `/v1/products/:id`, `/v1/prices`, `/v1/prices/:id` | supported |
| `GET` | `/v1/subscriptions` | partial: without `status`, canceled subscriptions are left out, as Stripe does |
| `GET`, `DELETE` | `/v1/subscriptions/:id` | supported |
| `POST` | `/v1/subscriptions/:id` | partial: `items` (id, price, quantity, deleted, metadata), `cancel_at_period_end`, `metadata` and `description`; prorations become pending invoice items; `always_invoice` is a gap |
| `GET` | `/v1/invoices`, `/v1/invoices/:id` | supported |
| `POST` | `/v1/invoices` | partial: pending invoice items are included only with `pending_invoice_items_behavior=include`, the default for new API versions |
| `POST` | `/v1/invoices/:id` | partial: drafts take description, footer, custom fields, metadata, `auto_advance` and due dates; open invoices the same except due dates; paid and void invoices metadata only |
| `POST` | `/v1/invoices/:id/finalize`, `/v1/invoices/:id/void` | supported |
| `POST` | `/v1/invoices/:id/pay` | partial: charges the given card or the customer's default; a declined test card answers 402 and the failed attempt stays on the invoice |
| `POST` | `/v1/invoiceitems` | partial: `amount` or `pricing[price]` with `quantity`; `price_data`, discounts and tax rates are gaps |
| `GET` | `/v1/invoiceitems` | supported |
| `POST` | `/v1/payment_intents` | partial: card payments with a saved payment method or a test token such as `pm_card_visa`; `pm_card_chargeDeclined*` tokens decline; 3D Secure, manual capture and other methods are gaps |
| `GET` | `/v1/payment_intents`, `/v1/payment_intents/:id` | supported |
| `POST` | `/v1/payment_intents/:id/confirm`, `/v1/payment_intents/:id/cancel` | supported |
| `GET` | `/v1/charges`, `/v1/charges/:id` | supported |
| `POST` | `/v1/refunds` | partial: card refunds settle at once |
| `GET` | `/v1/refunds`, `/v1/refunds/:id` | supported |
| `GET` | `/v1/balance` | partial: available and pending card funds; payouts and fees are not modeled |

Anything else returns HTTP 501 with Stripe's error shape and `x-ancha-gap: 1`. Requests pinned to an API version before `2025-03-31` are coverage gaps: older object shapes are not served.

## Starter data

The `stripe-starter` dataset is the test-mode account **Acme**, statement descriptor `ACME ANALYTICS`, with 12,845.50 USD available and 1,200.00 USD pending.

| Record | Detail |
| - | - |
| Products and prices | "Acme Team" at 1,200 USD a month (`team_monthly`); "Acme Enterprise" per seat at 100 USD a month (`enterprise_seat_monthly`) or 48,000 USD a year (`enterprise_annual`); "Onboarding package" at 2,500 USD once (`onboarding_once`). Prices carry these lookup keys. |
| Customers | Pinecrest Health (Visa ending 4242; 120 seats from December 1), Kestrel Credit Union (Mastercard ending 4444; invoices must reference their PO), Helix Manufacturing (Visa ending 9995, which declines with `insufficient_funds`), Summit Freight (Amex ending 8431) and Ridgeway Robotics (Visa ending 1881, a pilot). |
| Subscriptions | Pinecrest: 120 Enterprise seats, trialing until 2026-12-01. Kestrel: Enterprise annual, active, invoiced with 30 days to pay. Helix: Team monthly, past due. Summit: Team monthly, active. |
| Invoices | Summit's August, September and October invoices, paid. Helix's October invoice, open after two failed attempts. Kestrel's annual renewal, a draft. Ridgeway's onboarding package, paid. |
| Payments and refunds | A 5,000 USD implementation deposit from Pinecrest, and a duplicate 1,200 USD September payment from Summit that was refunded. |

Customer and deal records carry `hubspot_deal` metadata that matches the HubSpot starter data.

## Checks

Stripe has no state checks. Use trace checks, for example `{ called: "POST /v1/refunds" }` or `{ not_called: "DELETE /v1/subscriptions/*" }`.

## Limits

* Test mode only: cards are test tokens or seeded cards; no 3D Secure, payouts, disputes, taxes, coupons or webhooks.
* The SDK takes no base path: use the custom fetch client above, or point the host at `STRIPE_API_HOST_URL` on the computer that runs the world.
* API versions before `2025-03-31` are coverage gaps.


## Related topics

- [Tools](https://docs.ancha.io/tools/overview.md)
- [Test file (scene.yaml)](https://docs.ancha.io/reference/test-file.md)
- [ancha connect](https://docs.ancha.io/cli/connect.md)
- [Environment variables](https://docs.ancha.io/reference/environment-variables.md)
- [Introduction](https://docs.ancha.io/index.md)


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.