Tole.
Register
Agent-ready · integration briefUpdated for API v1

Give an agent the context and get a working integration

The brief locks down the contract, security, auto-invoice schedules, unknown outcomes, and webhook verification so the agent never has to guess the API.

Copy the complete brief

Paste it into Codex, Claude Code, Cursor, or another agent inside the target repository. The agent will inspect the stack first and fit Tole into the existing architecture.

The brief uses English so technical names match OpenAPI and generated code is less likely to distort field names.

Agent integration brief
Integrate Tole Payments API into this codebase.

Authoritative contract:
- OpenAPI 3.1: https://api.tolepay.kz/v1/openapi.json
- Human guide: https://tolepay.kz/ru/docs
- Raw agent guide: https://tolepay.kz/for-ai.md
- Base URL: https://api.tolepay.kz/v1

Before editing code:
1. Inspect the repository stack, existing HTTP client, env conventions, persistence, background jobs, and test setup.
2. Read the current OpenAPI document. Do not invent fields, SDKs, routes, statuses, or webhook events.
3. Keep all Tole credentials server-side. Add TOLE_API_KEY and optional TOLE_CONNECTION_ID to the existing secret/env system; never expose them to browser bundles or logs.

Implementation requirements:
1. Create a small typed Tole adapter around the repository's existing HTTP client. Use Authorization: Bearer <tole_sk_...>, Content-Type: application/json, and X-Tole-Connection-Id when configured.
2. Implement the requested invoice, QR, or recurring-invoice flow using the exact OpenAPI schemas. For every idempotent mutation send a stable Idempotency-Key derived from the local business operation ID, not a random key generated on each retry.
3. Persist Tole's local resource id and commandId. For recurring invoices also persist recurringInvoiceId, occurrenceId, and the generated paymentIntentId when present. Never treat a private Kaspi identifier as a public operationId.
4. Handle 200/201 as complete. On 202 in_progress, honor Retry-After and poll Location or GET /commands/{commandId}. On 202 outcome_unknown, never auto-repeat the mutation; reconcile command and payment-intent state.
5. Implement webhook verification over the exact raw request body before JSON parsing: v1=hex(HMAC-SHA256(secret, "<webhook-id>.<webhook-timestamp>.<exact_body>")). Reject invalid signatures, guard timestamp replay, deduplicate webhook-id, persist before processing, and return 2xx only after durable acceptance.
6. Use bounded timeouts. Retry safe reads with exponential backoff. Do not blindly retry payment mutations, 4xx responses, or unknown outcomes.
7. Add structured redacted logs. Never log API keys, webhook secrets, phone numbers, raw provider payloads, QR tokens, or payment URLs.
8. If recurring invoices are requested, model them as automatic invoice issuance, never as an automatic charge. Use a typed monthly, interval, weekly, or once schedule plus an IANA timezone; preview upcoming runs before create/update. Retry delays apply only when Tole could not issue the invoice. Never create a replacement merely because an issued invoice is unpaid, and never retry an outcome_unknown occurrence.
9. Add tests for success, validation error, 401/403, 409 idempotency or revision conflict, 429 Retry-After, 202 in_progress, 202 outcome_unknown, webhook valid/invalid signature, duplicate event, and timeout. Recurring flows also need timezone, short-month, pause/resume, missed-run, retry, and duplicate-occurrence tests.
10. Exercise immediate payment flows against /v1/sandbox/* with a test API key and required X-Tole-Connection-Id before enabling live mode. Recurring invoices are live-only until OpenAPI explicitly documents a sandbox mirror; do not invent one or simulate success inside production code.

Deliverables:
- production adapter and domain mapping;
- environment-variable documentation without real secrets;
- webhook endpoint and signature verification;
- automated tests and a copy-pasteable sandbox smoke command for supported immediate payment routes;
- for recurring invoices: a human-readable schedule summary, previewed next runs, lifecycle controls, and occurrence-to-payment correlation;
- a short handoff listing changed files, test results, and any remaining live-only verification.

If a required credential, connection ID, webhook URL, timezone, or business mapping is missing, finish all safe local work first and then ask for only that missing value. Never ask the user to paste a secret into chat.

Contract map

These rules must stay true in every implementation.

Server-side authorization

The tole_sk_* Bearer key never reaches client-side JavaScript.

Stable idempotency

One business operation always uses one Idempotency-Key, including network retries.

Auto-invoice is not a charge

A schedule issues a regular invoice; the customer still decides whether to pay.

202 is not success or failure

Poll in_progress and never automatically repeat outcome_unknown.

Raw webhook body

Compute HMAC before JSON.parse and process event IDs idempotently.

Sandbox first

Test keys and sandbox connections are isolated from live Kaspi; recurring invoices remain live-only until documented.

No provider IDs

Persist public Tole UUIDs and never infer private Kaspi fields.

What to prepare before running the agent

Do not paste secrets into the prompt. Put them into the project's protected local environment.

  • A test API key in TOLE_API_KEY.
  • The sandbox connection UUID in TOLE_CONNECTION_ID.
  • The public HTTPS URL for the future webhook endpoint.
  • A local order/payment ID used to derive a stable Idempotency-Key.
  • The first flow to integrate: phone invoice, QR, or a live auto-invoice.
  • For an auto-invoice: an IANA timezone, schedule rule, and technical retry policy.

Never send a live key to an agent through chat. The agent must read it only from env/secret manager and use masked placeholders in code, tests, and documentation.

When the integration is actually done

Ask the agent to finish only after these checks pass.

  • A sandbox mutation creates a resource and persists id + commandId.
  • Repeating the same business ID does not create a second payment.
  • 202 in_progress honors Retry-After; outcome_unknown does not repeat the mutation.
  • An auto-invoice displays a date preview, persists recurringInvoiceId/occurrenceId, and never duplicates an issued but unpaid invoice.
  • A valid webhook is accepted, an invalid signature is rejected, and a duplicate event ID is safe.
  • Secrets and sensitive payloads are absent from git diff, browser bundles, and logs.
  • Tests pass and any unperformed live Kaspi acceptance is called out separately.

Sources the agent must read

Message us on WhatsApp