Files for agents
/llms.txt: an index of every page with a one-line description. Start here./llms-full.txt: every page in one file, for agents that read everything up front.
Copy-paste prompt
Put your Sandbox secret key (it starts withzk_test_) in the environment variable ZAHLO_API_KEY, then give your agent this prompt, filling in the brackets:
Rules for generated integrations
- The secret key stays on the server. Read it from
ZAHLO_API_KEY. The browser only ever gets a session’surl(hosted) or itsclientToken(embedded). - Verify every webhook on the raw request body before parsing it, and reject a bad signature or a timestamp more than 300 seconds old with
400. - Dedupe and act in one transaction. Insert the event id into a table with a unique constraint and apply the business change (mark the order paid, grant access) in the same database transaction; return
2xxonly after it commits. A duplicate event id returns200without work. Never record the event id, return200, and fulfil afterwards: a crash in between loses the order. - Tolerate out-of-order events. Re-fetch the object (
GET /checkout-sessions/:id,GET /subscriptions/:id) and act on its current state instead of applying an older event’s data. - Fulfil one-time orders on
checkout.session.completed, never onpayment.confirmedalone and never because the customer reached your success page. The success page shows “processing” until the webhook has run. - Grant SaaS access from the subscription’s status: active while
trialingoractive, orpast_duewithin the grace period. - Handle reversals:
refund.succeeded,dispute.created,subscription.payment_failed,subscription.past_dueandsubscription.cancelled. - Retry safely. Send one
Idempotency-Keyper logical operation and reuse it on every retry. Retry only on a network error,409 request_in_progress,429or a5xx(includingprovider_outcome_unknown), at most twice, honouringRetry-After. Never retry other4xx, and never retry with a new key. - Never hard-code object ids. The Sandbox and live are separate accounts with different ids. Find prices with
GET /prices?lookupKey=…and coupons by their code, and create customers at runtime. Treat every id as an opaque string. - Register your checkout domains (
POST /checkout-domains) before testing; in the Sandbox this includeslocalhost:<port>. - Use
{CHECKOUT_SESSION_ID}insuccessUrlso your success page can retrieve the session with the secret key. - Check Not supported and Limits before promising a feature.