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

# Stripe

> The Stripe account behind each environment, what Ledger creates in it, and the webhook that keeps balances in step.

Ledger runs payments through Stripe and never handles card details itself. Each environment has its own Stripe account, connected in **Settings › Stripe**.

## The Stripe account in each environment

| | Sandbox | Live |
| - | - | - |
| Account | A Stripe test account Ledger creates for your workspace, or your own test mode | Your own Stripe account, in live mode |
| Key | Managed by Ledger, or your `sk_test_` key | Your `sk_live_` key |
| Set up | Ready when the workspace is created | **Settings › Stripe › Connect Stripe** while viewing Live |

The Sandbox test account lives on Ledger's Stripe Connect platform, so it needs no Stripe sign-up. To use your own Stripe test mode instead, for example to see objects in your own Stripe Dashboard, choose **Use a different key** in **Settings › Stripe** and paste an `sk_test_` secret key.

Ledger accepts standard secret keys (`sk_test_`, `sk_live_`). It encrypts them, never shows them again, and checks a key with Stripe before saving it.

## What Ledger creates in Stripe

| Ledger | Stripe |
| - | - |
| A paid plan | A product with a monthly USD price, updated when the plan changes |
| A customer's first purchase | A customer, carrying Ledger metadata that links it back |
| Attaching a paid plan | A Checkout Session in subscription mode, then a subscription |
| Attaching a credit pack | A one-time Checkout Session and an invoice for the pack |
| Overage (Sandbox) | Lines on the renewal invoice, one per rate |

Free plans and features never reach Stripe.

## The webhook

Stripe tells Ledger about payments through a signed webhook. Ledger treats it as the only proof that money arrived: it grants credits from these events, never from a browser redirect.

When you connect a key, Ledger creates the endpoint in that Stripe account for you, pinned to the Stripe API version Ledger is built against and subscribed to these events:

| Event | What Ledger does |
| - | - |
| `checkout.session.completed` | Links the new subscription; grants a credit pack's credits once paid. |
| `checkout.session.expired` | Closes the pending plan or pack, so a new Checkout can open. |
| `invoice.created` | Grants a renewal's credits and adds overage lines while the invoice is a draft. |
| `invoice.paid` | Activates a paid plan and grants its first credits; applies a paid upgrade. |
| `invoice.voided` | Ends the credits a voided renewal invoice granted. |
| `customer.subscription.deleted` | Ends the plan, and bills any remaining overage. |
| `customer.subscription.pending_update_applied` | Confirms an upgrade Stripe applied. |
| `customer.subscription.pending_update_expired` | Closes an upgrade whose payment never completed. |
| `test_helpers.test_clock.ready`, `customer.deleted` | Sandbox only: follows [simulated time](https://docs.integrateledger.com/customers/simulate-time.md). |

Each delivery is verified against the endpoint's signing secret, and handling it twice changes nothing, so Stripe's retries are safe.

### Webhook health

Before it opens a paid Checkout or starts an upgrade, Ledger checks with Stripe that the endpoint exists, is enabled, points at Ledger, uses the expected API version and subscribes to the events above. If it doesn't, the request returns `502 stripe_webhook_unhealthy` and no Checkout opens, because the payment couldn't reach the customer's balance.

**Settings › Stripe** shows the webhook as **Receiving** when it's healthy, or **Not active** with a **Check again** button. If you deleted or edited the endpoint in Stripe, reconnecting the key creates a fresh one.

> [!WARNING]
>
> Don't edit or delete Ledger's endpoint in your Stripe Dashboard. If payments stop updating balances, check **Settings › Stripe** first.

## You don't handle Stripe webhooks

Ledger consumes Stripe's events for you. Your app reads the results from Ledger's API: the customer's plan, balance, subscriptions and purchases. To react to billing changes in your app, subscribe to Ledger's own [webhooks](https://docs.integrateledger.com/webhooks.md).

## Next steps

> [card] [Billing lifecycle](https://docs.integrateledger.com/concepts/billing-lifecycle.md)
>
> How these events move a customer through billing.

> [card] [Go live](https://docs.integrateledger.com/getting-started/deploy.md)
>
> Connect your live Stripe account.


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