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

# Test billing locally

> Use Stripe sandbox Checkout and a local webhook listener without live charges.

This guide is for contributors running the Bench web app on port 5173 and API on port 8080.
Use a Stripe sandbox or test environment only. Never load a live payment key into the local launcher.

## Update the Stripe CLI

For a Homebrew installation on macOS:

```sh theme={null}
brew update
brew upgrade stripe
stripe version
```

`stripe upgrade` is not a Stripe CLI command. Update it through the package
manager used to install it. See the [official Stripe CLI instructions](https://github.com/stripe/stripe-cli).

## Forward sandbox events

Authenticate the Stripe CLI to the same sandbox that owns your test products and prices:

```sh theme={null}
stripe login
stripe listen \
  --events checkout.session.completed,customer.subscription.updated,customer.subscription.deleted,invoice.payment_succeeded,invoice.payment_failed \
  --forward-to http://127.0.0.1:8080/api/billing/webhook
```

The local endpoint is **`http://127.0.0.1:8080/api/billing/webhook`**. Keep the listener running.
Use its `whsec_...` signing secret, not the secret from an unrelated Dashboard endpoint.
These are snapshot events consumed by Bench's billing handler. You do not need to enable every Stripe event.

Finish `stripe login` in the browser before starting the listener. If login was
canceled with Ctrl+C or credentials expired, run it again and use the new pairing
link. Do not paste pairing links, secret keys or webhook signing secrets into tickets.

Stripe cannot deliver directly to your machine's localhost from a Dashboard webhook destination.
For local development, use the CLI forwarding command. A deployed endpoint instead needs its own
reachable HTTPS URL and signing secret. See [Stripe webhook testing](https://docs.stripe.com/webhooks)
and [the Stripe CLI](https://docs.stripe.com/cli).

## Configure test prices

Create recurring EUR sandbox prices matching the local plan catalog:

| Plan    | Monthly price | Annual price  |
| ------- | ------------- | ------------- |
| Builder | €99 / month   | €950 / year   |
| Growth  | €349 / month  | €3,350 / year |

Use four distinct price IDs from the same sandbox as the API key. Annual cards show a rounded
monthly equivalent; Checkout charges the annual price. Free has no Stripe price.

In this development workspace, enter the values in the ignored `.context/local-billing.env` file:

```dotenv theme={null}
STRIPE_SECRET_KEY=sk_test_REPLACE
STRIPE_WEBHOOK_SECRET=whsec_REPLACE
STRIPE_PRICE_ID_BUILDER_MONTHLY=price_REPLACE
STRIPE_PRICE_ID_BUILDER_YEARLY=price_REPLACE
STRIPE_PRICE_ID_GROWTH_MONTHLY=price_REPLACE
STRIPE_PRICE_ID_GROWTH_YEARLY=price_REPLACE
```

```sh theme={null}
chmod 600 .context/local-billing.env
```

Restart the local API after configuration changes, once active evaluations have finished.
The workspace launcher accepts only test secret keys and passes billing configuration to the API,
not Vite or the browser. It rejects partial configuration and duplicate price IDs. An unconfigured
Checkout button stays disabled; a UI fixture passing does not mean Stripe is configured.

For existing subscribers, configure the sandbox Customer Portal to allow the relevant subscription
updates. Bench passes the selected price into the confirmation flow. Changing a plan is not an
authorization to silently create a second subscription.

## Verify the full flow

1. Open **Bench pricing**, choose Monthly or Yearly, then select Builder or Growth.
2. Confirm the plan, amount and billing interval on hosted Checkout before submitting.
3. Use Stripe's sandbox card `4242 4242 4242 4242`, a future expiry and any three-digit CVC.
4. Confirm the listener receives a successful webhook response and Bench refreshes the plan and allowance.
5. Test a failed payment, duplicate event delivery and a subscription change in the sandbox.
6. Review changes and prorations on the Customer Portal confirmation screen before submitting.

See [Stripe testing](https://docs.stripe.com/testing) for additional test payment methods.
Do not use real card details. Account onboarding or expired CLI credentials must be resolved in
Stripe; Bench cannot bypass account restrictions.

Model-provider billing is independent. A working Stripe Checkout does not resolve an evaluation
provider's credit balance.
