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

> ## Agent Instructions
> Money is always a decimal string at the currency's precision (for example "29.00"), paired with an ISO 4217 currency field. Never use minor units.
> Build against the sandbox first: base URL https://sandbox-api.bachs.io with sk_sandbox_ keys. Production is https://api.bachs.io with sk_live_ keys; going live is a key swap.
> Treat webhooks (for example collection.succeeded) as the source of truth for fulfilment, never client-side events or redirects.
> Subscriptions are created by completing a checkout for a recurring product. There is no direct create-subscription endpoint.
> IDs carry resource prefixes (cust_, prod_, sub_, chk_, inv_, ref_) and timestamps are ISO 8601 UTC.

# Go-live checklist

> The technical checks to run before you swap your sandbox keys for live keys.

Your integration works the same way in the sandbox and in production, so going live is a key swap after your account is verified. Run these checks first. Each one is a single line with a link to the page that explains it.

## Account

* [ ] Your account is verified, so your production keys work. See [Create and verify your account](https://docs.bachs.io/go-live.md).
* [ ] You have no open tasks on your dashboard. Open tasks can limit accepting payments and withdrawing. See [How reviews and tasks work](https://docs.bachs.io/go-live.md#how-reviews-and-tasks-work).

## Keys and environment

* [ ] Your server sends an `sk_live_` key to `https://api.bachs.io`. A key only works against its own environment. See [Two environments, two keys](https://docs.bachs.io/authentication.md#two-environments-two-keys).
* [ ] Your production key has only the scopes your integration uses. A key cannot reach an endpoint outside its scopes, so a leaked key can do less damage. See [Scopes](https://docs.bachs.io/authentication.md#scopes).
* [ ] Your keys and webhook signing secrets live in environment variables or a secrets manager, never in browser code, the repository or logs. See [Keep keys safe](https://docs.bachs.io/authentication.md#keep-keys-safe).
* [ ] No deployment mixes sandbox and live keys, and no sandbox URL, key or secret is left in your production configuration. See [Keep keys safe](https://docs.bachs.io/authentication.md#keep-keys-safe).
* [ ] You rotated any key that may have leaked during development. Rotation invalidates the old secret at once, so update your deployment first. See [Keep keys safe](https://docs.bachs.io/authentication.md#keep-keys-safe).
* [ ] You created your products again in production and updated their IDs in your code. The sandbox and production share nothing. See [Nothing is shared with production](https://docs.bachs.io/integrate/sandbox.md#nothing-is-shared-with-production).
* [ ] Your `success_url` is a public page on your site. See [Accept a payment with Checkout](https://docs.bachs.io/guides/checkout/checkout-sessions.md).

## Payments

* [ ] Your server sets product IDs, prices and amounts, never the browser. See [Sell digital products](https://docs.bachs.io/build/use-cases/digital-products.md).
* [ ] You send amounts as decimal strings with a currency, such as `"29.00"`. See [Send your first request](https://docs.bachs.io/authentication.md#send-your-first-request).
* [ ] You fulfil an order only from a verified webhook, not from the redirect to your success page. A customer can close the tab before the redirect. See [Accept a payment with Checkout](https://docs.bachs.io/guides/checkout/checkout-sessions.md).
* [ ] Before you fulfil, you match the payment to your order, its amount and its currency. See [Sell digital products](https://docs.bachs.io/build/use-cases/digital-products.md).
* [ ] You keep orders and event IDs in a real database, not a local file. See [Sell digital products](https://docs.bachs.io/build/use-cases/digital-products.md).
* [ ] You tested every payment outcome in the sandbox, including declined cards, insufficient funds and a failed refund. See [Test payment outcomes](https://docs.bachs.io/integrate/sandbox.md#test-payment-outcomes).

## Webhooks

* [ ] You registered a production webhook endpoint for every event you handle. Endpoints do not carry over from the sandbox. See [Set up webhooks](https://docs.bachs.io/guides/webhooks/overview.md).
* [ ] Your production endpoint's signing secret is in your environment, and you checked it against a live delivery. Each endpoint has its own secret. See [Verifying your webhooks](https://docs.bachs.io/guides/webhooks/overview.md#verifying-your-webhooks).
* [ ] Your handler checks the signature on the raw body before it parses JSON, rejects old timestamps, and accepts a delivery if any `v1=` signature matches. See [How the signature works](https://docs.bachs.io/guides/webhooks/overview.md#how-the-signature-works).
* [ ] You ignore a delivery whose event `id` you already processed. The same event can arrive more than once. See [Receiving events](https://docs.bachs.io/guides/webhooks/overview.md#receiving-events).
* [ ] You compare `created_at` before you overwrite stored state. Events can arrive out of order. See [Responding to deliveries](https://docs.bachs.io/guides/webhooks/overview.md#responding-to-deliveries).
* [ ] Your handler ignores fields it does not recognise. Bachs can add new fields at any time. See [Receiving events](https://docs.bachs.io/guides/webhooks/overview.md#receiving-events).
* [ ] You return a `2xx` within 10 seconds of storing the event, and a `5xx` when your own processing fails. Bachs does not retry most `4xx` responses. See [Retries](https://docs.bachs.io/guides/webhooks/overview.md#retries).

## Errors and retries

* [ ] Every `POST` and `PATCH` sends an `Idempotency-Key` for one business operation, and you save the key before you send the request. See [Idempotency](https://docs.bachs.io/guides/idempotency.md).
* [ ] After a timeout or a `5xx` on a write, you check the operation's state before you retry, and you retry with the same key and body. A `5xx` does not prove that nothing happened. See [Recover an uncertain write](https://docs.bachs.io/guides/idempotency.md#recover-an-uncertain-write).
* [ ] Your code branches on `error_code`, not on `detail` or the HTTP status alone. See [Handling errors](https://docs.bachs.io/errors.md#handling-errors).
* [ ] You handle the error codes your endpoints can return, and you wait for `Retry-After` on a `429`. See [Error reference](https://docs.bachs.io/api-reference/error-reference.md).

## Subscriptions

If you sell subscriptions:

* [ ] You chose what happens when payment retries run out. See [When recovery is exhausted](https://docs.bachs.io/guides/subscriptions/failed-payments.md#when-recovery-is-exhausted).
* [ ] You configured what customers can change in the customer portal. See [Configuring the portal](https://docs.bachs.io/guides/customer-portal/overview.md#configuring-the-portal).

## Connect platforms

If you run a platform with Connect:

* [ ] Your platform completed registered-business compliance, and `connect` is `active` in production. Sandbox access does not allow production use. See [Take Connect live](https://docs.bachs.io/connect/go-live.md).
* [ ] Your production keys have only the Connect scopes you use, such as `connected_accounts:write`, `transfers:write` and `payouts:write`. See [Take Connect live](https://docs.bachs.io/connect/go-live.md).
* [ ] Your production webhook endpoint has `event_source` set to `connect` or `all`. Without it, you receive no events about your accounts. See [Take Connect live](https://docs.bachs.io/connect/go-live.md).
* [ ] Your integration waits for each capability to become `active` instead of assuming it. In production, a new capability starts `restricted` until a reviewer enables it. See [What does change](https://docs.bachs.io/connect/go-live.md#what-does-change).
* [ ] Every request that acts for a business sends its `X-Account-Id`. See [Acting as an account](https://docs.bachs.io/connect/acting-as-an-account.md).
* [ ] You start transfers when funds settle, not when the charge succeeds. See [Balances](https://docs.bachs.io/connect/balances.md).
* [ ] You decided when you transfer a seller's share. Once it is transferred and withdrawn, a reversal cannot recover it. See [Split payments](https://docs.bachs.io/connect/split-payments.md).
* [ ] You know whose balance pays for refunds and lost disputes: your own on a marketplace, the business's on a SaaS platform. See [Refunds on Connect](https://docs.bachs.io/connect/refunds.md).

## Review your code

* [ ] You ran the review prompt against your integration and fixed what it found. See [Review before go-live](https://docs.bachs.io/build/ai/prompts.md#review-before-go-live).

## Next steps

* [Create and verify your account](https://docs.bachs.io/go-live.md): what verification asks for and how reviews work.
* [Test your integration](https://docs.bachs.io/integrate/sandbox.md): force a failed payment and test your handler against every result.
* [Set up webhooks](https://docs.bachs.io/guides/webhooks/overview.md): signatures, retries and what happens when an endpoint keeps failing.
* [Take Connect live](https://docs.bachs.io/connect/go-live.md): what changes between the sandbox and production for a platform.


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