> ## 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.

# Skills and prompts

> Three guided workflows for building payments, subscriptions, and a marketplace with an AI assistant, with an optional Bachs skill.

Build one complete payment flow at a time with your coding assistant. Each workflow below explains what you need, gives the assistant a specific job, and shows how to check the result.

**You do not need to install a skill.** Choose a workflow and copy its prompt into an assistant that can work with your app's code. If you build with Bachs regularly, the [optional skill](#set-up-the-bachs-skill-optional) keeps the shared guidance available.

Starting a new app? [Choose a starter template](/build/starters/overview) first, then use a workflow below to adapt it.

## Before you start

* Have an app your assistant can inspect, and decide what customers will buy.
* Get a [sandbox API key](/authentication). Keep it in your server's environment; do not paste it into a chat.
* Let your assistant read the linked docs. If it cannot open them, use **Copy page** on each guide and paste the content alongside the prompt.
* Use the [Bachs CLI](/cli/overview) to [forward sandbox webhooks to your machine](/developer-portal/local-testing).

Checkout return URLs must be public. For a fully local app, omit checkout redirects and return to the app manually after paying; the CLI still forwards webhooks locally. Use a public deployment or tunnel if you need an automatic return.

Every prompt includes its own integration rules. You can use it without creating an `AGENTS.md` file or installing a skill.

## Build with the SDK

For a Node.js or TypeScript server, use the [official Bachs SDK](https://github.com/bachsdev/bachs-node). It handles API requests, typed responses, and webhook signature verification. Your app still owns authentication, order state, access, and delivery recovery.

The [Next.js SaaS starter](https://github.com/bachsdev/bachs-nextjs-saas) uses the SDK and includes its tested package while the npm release is being prepared. The current npm 0.0.1 package is a placeholder. Follow the starter's package instructions instead of installing that version.

Connect onboarding, account context, and marketplace splits currently use the documented API because these operations are not yet supported by the SDK.

## Choose your workflow

| You want toâ€¦ | Start here |
| - | - |
| Sell an item, booking, or digital product once | [Accept a one-time payment](#accept-a-one-time-payment) |
| Charge for ongoing access to your product | [Sell subscriptions](#sell-subscriptions) |
| Collect a sale and allocate a seller's share | [Build a marketplace](#build-a-marketplace) |

## Accept a one-time payment

**What you'll build:** a customer chooses an item, pays on Bachs checkout, and your app fulfils the order after confirming payment.

**Have ready:** what you sell, its price and currency, and the action that completes an order. Products can be created in the dashboard or through the [Products API](/guides/products/overview).

```text Prompt theme={"dark"}
Add Bachs one-time payments to this app. Inspect its framework, authentication,
order records, and payment code first. Reuse those conventions. Ask for the
item, currency, or fulfilment decision if missing.

For a Node.js or TypeScript server, use the official SDK for checkout and
webhooks.constructEvent for signature verification. Read its supported methods
and release instructions at https://github.com/bachsdev/bachs-node and
https://github.com/bachsdev/bachs-nextjs-saas/tree/main/vendor.
Check the installed version; npm 0.0.1 is only a placeholder. Do not reimplement
the SDK transport. For another server language, use the documented API.

Read:
https://docs.bachs.io/guides/checkout/checkout-sessions.md
https://docs.bachs.io/guides/webhooks/overview.md
https://docs.bachs.io/guides/webhooks/events/collection-succeeded.md
https://docs.bachs.io/guides/idempotency.md

Use https://sandbox-api.bachs.io with BACHS_API_KEY on the server. Explain
dashboard setup, including products and webhook events.

Create checkout on the server with product_cart and our order reference.
Choose prices and product IDs on the server. Save the checkout ID and expected
amount and currency with the order, then redirect to checkout_url. For local testing, omit checkout return URLs; if configured, they must be public.

Verify X-Bachs-Signature-V2 on the raw body before parsing JSON, including
timestamp tolerance and every v1 signature. Fulfil once on collection.succeeded
after matching the order, amount, and currency. Store event IDs durably; make
fulfilment and event completion atomic or recoverable. Return 5xx on handling
failure. The success page reads our order state and handles a delayed webhook;
visiting it never marks an order paid.

Keep secrets server-side and amounts as decimal strings. Persist an
Idempotency-Key for each write operation. Reconcile an uncertain write before
retrying with the same key and unchanged request.

Test success, unsuccessful checkout, a bad signature, duplicate delivery, and
failed processing followed by redelivery. Report what you actually ran, what
I must configure, and how to complete a real sandbox checkout. Read linked
docs for missing details; do not invent API behavior.
```

### Check the result

* A successful sandbox checkout pays the correct order and fulfils it once.
* Opening the success URL before paying leaves the order unpaid.
* An unsuccessful checkout does not fulfil the order.
* Redelivery cannot repeat fulfilment; failed handling can recover on redelivery.
* An unrelated payment or virtual-account deposit cannot pay the order.

After this works, add an [overlay checkout](/guides/checkout/overlay-checkout), [local pricing](/guides/products/local-pricing), or [refunds](/guides/refunds).

## Sell subscriptions

**What you'll build:** monthly and yearly plans, access that follows subscription state, and a **Manage billing** button for the customer portal.

**Have ready:** signed-in users, your plans, and a decision about access during a failed renewal. The current [subscription guide](/guides/subscriptions/overview) supports USD card billing; [free trials](/guides/subscriptions/trials) are in beta.

```text Prompt theme={"dark"}
Add Bachs subscriptions to this app. Inspect its authentication, database,
access checks, and billing code first. Reuse them. Ask for missing plan details
or the access policy during payment recovery.

For a Node.js or TypeScript server, use the official SDK for products,
checkout, customer portal sessions, and webhooks.constructEvent. Read
https://github.com/bachsdev/bachs-node and the package instructions at
https://github.com/bachsdev/bachs-nextjs-saas/tree/main/vendor.
Check the installed version; npm 0.0.1 is only a placeholder. Keep persistent
keys and business state in our app; handle SDK outcomeUnknown by reconciling.
For another server language, use the documented API.

Read:
https://docs.bachs.io/build/use-cases/saas-subscriptions.md
https://docs.bachs.io/guides/webhooks/overview.md
https://docs.bachs.io/guides/idempotency.md

Use https://sandbox-api.bachs.io and server-side BACHS_API_KEY. Omit checkout return URLs for local testing; configured redirects must be public. Explain how
to create recurring products in the dashboard or API, configure portal settings,
and forward the five webhook events named in the use case.

Map a plan key to a product ID on the server. Create checkout with product_cart,
customer, billing_currency, and metadata.user_id. Recurring checkout starts the
subscription; there is no create-subscription endpoint. If the user already
has access, direct them to manage billing.

Verify X-Bachs-Signature-V2 on the raw body, with timestamp tolerance and all
v1 signatures. From customer.subscription.created, updated, and deleted, save
the customer ID and full subscription state against our user. Deduplicate
durably and prevent older events overwriting newer state, including concurrent
deliveries. Commit state and event completion together; return 5xx on failure.

Decide access from stored state, including trialing, active, past_due, and
cancellation. The success page only reads that state. Create each portal
session on the server for the signed-in user's own customer ID. Check the
documented portal settings and cancellation defaults.

Keep secrets server-side and amounts as decimal strings. Persist one
Idempotency-Key per write operation; reconcile uncertain writes before retrying.

Test activation, duplicate and out-of-order events, failed handling followed by
redelivery, renewal failure, and cancellation at period end. Report tests
actually run, remaining setup, and real sandbox checkout steps. Read linked
docs for missing details; do not invent behavior.
```

### Check the result

* A sandbox payment saves the user's customer ID and subscription, then grants access.
* A redirect alone cannot grant access.
* Duplicate or older events cannot undo a later cancellation.
* **Manage billing** opens the signed-in user's own customer portal.
* Scheduled cancellation keeps access for the remaining paid period; immediate cancellation removes it.
* Renewal failure follows your access policy and can recover after a successful retry.

The [full walkthrough](/build/use-cases/saas-subscriptions) includes requests, webhook examples, and a go-live checklist. Add [trials](/guides/subscriptions/trials) or [plan changes](/guides/subscriptions/manage) after the basic flow works.

## Build a marketplace

**What you'll build:** your platform collects a payment, keeps its fee, and the seller's share reaches the seller's Bachs balance at settlement. The seller can then pay out to its own approved destination.

**Have ready:** the [Connect capability](/connect/become-a-platform), seller records, your fee, and the collection currency. Start with **one seller per order**. If each business should own its sale, use [Platform for businesses](/build/use-cases/saas-platform).

```text Prompt theme={"dark"}
Add a single-seller marketplace payment flow with Bachs Connect. Inspect our
onboarding, orders, authentication, database, and payment code. Confirm that
our platform owns the sale and takes a fee. Ask for missing currency, fee,
or seller-onboarding decisions.

Read the SDK's current scope at https://github.com/bachsdev/bachs-node.
Connect account context, seller onboarding and checkout splits are not supported
by the current SDK. Use documented API calls for these operations; never invent
SDK methods or force unsupported fields through type casts. A Node.js server can
use the SDK's webhooks.constructEvent for signature verification.

Read:
https://docs.bachs.io/build/use-cases/marketplace.md
https://docs.bachs.io/connect/onboarding.md
https://docs.bachs.io/connect/capabilities.md
https://docs.bachs.io/connect/marketplaces/refunds-and-disputes.md
https://docs.bachs.io/connect/payouts.md
https://docs.bachs.io/guides/webhooks/overview.md
https://docs.bachs.io/guides/idempotency.md

Use https://sandbox-api.bachs.io with BACHS_API_KEY on the server. Omit checkout return URLs for local testing; configured redirects must be public. Explain
Connect setup and the capabilities and requirements each seller needs.

Create and save a recipient sub account for each seller, and implement the
documented onboarding path. Choose the seller, product, and platform fee on the
server from our order. Create the platform checkout with
transfer_data.destination and platform_fee, linked to our order.

Verify X-Bachs-Signature-V2 on the raw body, with timestamp tolerance and all
v1 signatures. Confirm payment from verified events matched to the order,
amount, and currency. Deduplicate durably, keep state updates recoverable,
and return 5xx on processing failure.

Track payment, settlement into the seller's balance, and payout delivery
separately. The destination charge creates its transfer at settlement:
do not send a second manual transfer. Use documented account context for
the seller's balance and destination. Gate payouts on active capabilities
and a usable destination owned by that seller. A payout create response
does not confirm delivery.

Keep secrets server-side and amounts as decimal strings. Persist operation
idempotency keys and reconcile uncertain writes before retrying. Explain who
bears refunds and disputes. Do not describe this flow as escrow.

Test a paid sale and split, duplicate events, incomplete onboarding, a
destination awaiting approval, and a failed payout. Report which tests used
mocks and which ran in sandbox, remaining setup, and how to reconcile the
payment with the seller's balance and our fee.
```

### Check the result

* The correct seller account ID is saved against each seller.
* The payment is accounted for across the seller's share, platform fee, and processing fee.
* Settlement creates one seller transfer; the app does not send another manually.
* Blocked capabilities or an unusable destination prevent a payout.
* The app tracks payout status through delivery or failure.
* Your team understands the platform's responsibility for refunds and disputes.

Follow the [marketplace walkthrough](/build/use-cases/marketplace) for the split, [Connect payouts](/connect/payouts) for withdrawals, and [refunds and disputes](/connect/marketplaces/refunds-and-disputes) before going live.

## Set up the Bachs skill (optional)

The [public skill source](https://github.com/bachsdev/bachs-nextjs-saas/blob/main/skills/bachs/SKILL.md) covers all three workflows; it is also copied below for convenience.

A skill saves shared Bachs instructions so you do not have to paste them into every task. You still tell the assistant what you want to build. The prompts above work on their own.

<Accordion title="Install in Claude Code">
  1. In your app's project, create a folder called `.claude/skills/bachs`.
  2. Copy the file below and save it as `SKILL.md` in that folder.
  3. In Claude Code, type `/bachs` followed by your task, or use a prompt above.

  Claude Code can also load the skill when a relevant task matches its description. See [Claude Code's instructions](https://code.claude.com/docs/en/skills) for other installation options.

  ```md SKILL.md theme={"dark"}
  ---
  name: bachs
  description: Build or review Bachs one-time checkout, SaaS subscriptions, and marketplace payments with Connect. Use for payment integrations, webhook handling, billing access, seller onboarding, and testing these flows.
  ---

  # Build with Bachs

  Implement the requested Bachs flow in the user's existing app. Use the current
  docs for API fields, product availability, and account requirements.

  ## Understand the app

  Read project instructions and existing authentication, order or billing records,
  payment code, and tests. Reuse the app's framework and data layer.
  Establish the requested flow, currency, product or plan, and account ownership.
  Ask only for missing decisions that affect implementation. Explain the proposed
  flow briefly, then carry out the authorized work.

  ## Read the relevant workflow

  Read the selected guide and the references needed for the task. If web access
  is unavailable, ask the user to paste the pages using Copy page. Do not invent
  endpoints, fields, events, or eligibility.

  | Task | Start here |
  | --- | --- |
  | One-time payment | https://docs.bachs.io/guides/checkout/checkout-sessions.md |
  | SaaS subscriptions | https://docs.bachs.io/build/use-cases/saas-subscriptions.md |
  | Marketplace | https://docs.bachs.io/build/use-cases/marketplace.md |

  Shared references:
  - Webhooks: https://docs.bachs.io/guides/webhooks/overview.md
  - Local testing: https://docs.bachs.io/developer-portal/local-testing.md
  - Write recovery: https://docs.bachs.io/guides/idempotency.md
  - Page index: https://docs.bachs.io/llms.txt

  Include dashboard setup such as products, capability requests, webhook endpoints,
  or portal settings. Separate dashboard setup from routes in the user's app.

  ## Use the official SDK when supported

  For a Node.js or TypeScript server, use the official @bachs/sdk for products,
  checkout sessions, subscriptions, customer portal sessions and webhook
  verification. Read https://github.com/bachsdev/bachs-node before choosing methods
  or types. Construct Bachs with apiKey and an explicit environment. Use
  webhooks.constructEvent on the raw body and request headers; keep event
  persistence and business decisions in the app.

  Check the package's actual exports and version. The npm 0.0.1 package is a
  placeholder, not the tested implementation. Until the 1.0.0 implementation is
  released on npm, the public starter includes its packaged copy and provenance:
  https://github.com/bachsdev/bachs-nextjs-saas/tree/main/vendor
  Do not install the placeholder or add a dependency on a local sibling repository.
  After the matching release is available, use its exact npm version.

  The SDK sends writes once and reports outcomeUnknown on uncertain writes.
  Persist operation keys in the app and reconcile before sending again. Do not
  build another transport, response decoder or signature verifier for supported
  SDK operations. Do not log full provider error bodies or portal URLs.

  The current SDK does not support Connect account context, seller onboarding or
  checkout split fields. Use documented API requests for those marketplace
  operations; do not invent SDK methods or pass unsupported fields through casts.
  Other server languages can use the documented API.

  ## Integration rules

  - Start in the sandbox: https://sandbox-api.bachs.io with an sk_sandbox_ key.
    Production uses https://api.bachs.io and an sk_live_ key. Keep secrets on the
    server in environment variables. Never log them or put them in client code.
  - Send amounts as decimal strings with an ISO currency at its precision.
    Choose or validate prices and product mappings on the server.
  - Checkout redirects must be publicly accessible, even in sandbox. For a fully
    local app, omit them and return manually after payment. Use a public deployment
    or tunnel for automatic return; CLI webhook forwarding is separate.
  - Link the local order or user to checkout and save Bachs IDs. Match a payment
    to its order, expected amount, and currency before fulfilling it. A virtual
    account deposit without an order reference does not pay an order automatically.
  - Verify X-Bachs-Signature-V2 against the original raw request body before
    parsing JSON. Check timestamp tolerance and all v1 signatures as documented.
  - Fulfil orders and grant access from verified webhook state. A success redirect
    or browser event is only a display signal.
  - Deduplicate event IDs durably and prevent older state replacing newer state,
    including concurrent deliveries. Commit state and event completion atomically
    in the app's database, or use a durable queue with equivalent recovery.
    Failed processing must remain eligible for redelivery.
  - Return 2xx after handling or durably accepting an event; return 5xx on processing
    failure. Follow the documented retry policy: 408 and 429 are exceptions to the
    usual non-retry behavior for 4xx.
  - Persist one Idempotency-Key per business operation for public POST/PATCH calls.
    Reuse it with the same request when recovery establishes a retry is needed.
    A timeout or 5xx is an uncertain outcome. Reconcile before resubmitting;
    only successful JSON responses are cached.

  ## Workflow decisions

  ### One-time payment
  Use hosted checkout first unless an overlay is requested. Create it on the
  server using product_cart and a local order reference. Fulfil once from
  collection.succeeded after matching the order. Show pending, paid, and
  unsuccessful outcomes from stored order state.

  ### SaaS subscriptions
  A recurring product checkout creates the subscription; there is no separate
  create-subscription endpoint. A recurring checkout needs a customer. Confirm
  supported billing methods and currencies in the current guide.
  Save the customer and full subscription state against the signed-in user from
  customer.subscription.created, updated, and deleted events.
  Make trialing, active, past_due, and cancellation access policy explicit.
  Create each portal session on the server for the user's own customer.
  Check dashboard settings for card updates and plan switching, and read current
  cancellation semantics before implementing API cancellation.

  ### Marketplace
  Confirm destination charges fit the business: the platform owns the sale and
  the seller sub account receives a share at settlement. Read
  https://docs.bachs.io/connect/choose-your-integration.md if the business should
  own the sale instead. Read onboarding, capabilities, refunds, and payouts.
  Start with one seller per order unless the user needs and the docs support
  another arrangement. Save its account ID and choose destination and fee on
  the server. Let the destination charge generate its transfer at settlement;
  do not add a second manual transfer.
  Payment, seller balance credit, and payout delivery are separate states. A
  payout uses the seller's balance and its usable destination. This is not an
  escrow integration.

  ## Verify and hand off

  Test observable behavior for the selected flow: success, unsuccessful payment,
  invalid signatures, duplicate delivery, older events arriving late, processing
  failure followed by redelivery, and uncertain writes. For subscriptions include
  renewal failure and cancellation; for marketplaces include blocked onboarding,
  settlement, and payout failure.

  Use existing test tools and the sandbox instructions. A synthetic webhook checks
  handling, not completed checkout or settlement. Do not describe mocks or a code
  review as a real sandbox payment.
  Report changes, tests actually run, dashboard setup still needed, and unverified
  steps. Production transactions and deployment require the user's authorization.
  ```
</Accordion>

For another assistant that supports [Agent Skills](https://agentskills.io), install the same `SKILL.md` using that tool's instructions. If your assistant does not support skills, use a prompt above and paste the linked docs when needed.

## Before you go live

Ask your assistant to report files changed, tests actually run, and remaining setup. A mocked webhook test proves handler behavior; it does not prove checkout, settlement, or payout delivery works in sandbox.

| Check | What to confirm |
| - | - |
| Account and setup | Required capabilities are active, products exist, and webhook and portal settings match the workflow. |
| Secret keys | Bachs keys and webhook secrets stay on the server. |
| Payment state | Redirects cannot grant access or fulfil an order. |
| Delivery recovery | Duplicate and older events are handled; failed processing recovers without repeating fulfilment. |
| Write recovery | Uncertain responses are reconciled before retrying; operation keys persist. |
| Real test | The flow has completed in sandbox, including relevant failure cases. |

Follow [Go live](/go-live), or [Take Connect live](/connect/go-live) for a marketplace. Create production resources, use the production key and API URL, and register a webhook endpoint with its own signing secret.


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