Building with AI tools
AI coding assistants write plausible Pesepay integrations that don’t work.
Pesepay is small enough that models have little real training data on it, so
they fall back on what other gateways do: a publishableKey, a webhook
signature header, plain JSON request bodies, a ZWL currency code. Every one
of those is wrong here, and the code fails at runtime rather than at review.
Two things fix most of it: give the model the real docs, and tell it not to fill gaps from memory.
Machine-readable sources
Section titled “Machine-readable sources”This site publishes itself in formats built for models. Paste a URL into your assistant, or attach the file to your project.
| URL | What it is |
|---|---|
/llms.txt | An index of every page, with the rules that are most often got wrong stated up front |
/llms-full.txt | The entire documentation site as one text file |
/llms-small.txt | A compact build for smaller context windows |
/_llms-txt/api-reference.txt | Every endpoint, field, error and data model, without the guides |
/_llms-txt/payment-methods.txt | Per-method codes, currencies, amount limits, required fields and failure modes |
/_llms-txt/getting-started.txt | Onboarding, the quickstart, both payment flows and the encryption scheme |
/openapi.yaml | The OpenAPI 3.1 spec — see OpenAPI spec & Postman |
For an agent that can fetch as it works, /llms.txt plus permission to
follow its links beats pasting one page. For a one-shot prompt, attach
/llms-full.txt.
A prompt to start from
Section titled “A prompt to start from”Paste this above your own request. The constraints matter more than the wording — the point is to make “I don’t know” a permitted answer.
You are helping me integrate Pesepay, a Zimbabwean payment gateway.
Ground rules — follow these exactly:
1. Use ONLY the Pesepay documentation I have given you (https://developers.pesepay.com/llms-full.txt and https://developers.pesepay.com/openapi.yaml). Do not fill gaps from memory of Stripe, Paystack, Flutterwave or any other gateway.2. Do NOT invent endpoints, request or response fields, currency codes, payment method codes, transaction statuses, headers, or security mechanisms. If something you need is not in the documentation, say so and stop — do not produce a plausible substitute.3. Quote the source: for every endpoint and field you use, name the page or spec path it comes from.4. Flag any assumption you make, in a list at the end.
Facts about Pesepay that contradict most other gateways — apply them:
- Request and response bodies are ENCRYPTED, not plain JSON. Every integration endpoint takes {"payload": "<base64>"}, where the payload is the JSON body encrypted with AES-256-CBC. The key is the 32-character application encryption key; the IV is the FIRST 16 CHARACTERS OF THAT SAME KEY. Responses are encrypted the same way. Error responses are NOT encrypted.- There are two different keys and they are not interchangeable: the integration key goes in the `authorization` header; the encryption key is used only for the cipher above. There is no publishable or client-side key — nothing may be called from frontend code.- Result callbacks are UNSIGNED, UNENCRYPTED, and NEVER RETRIED. There is no signature header to verify. Confirm every payment by calling check-payment-status with the reference number.- Zimbabwe dollars are addressed by two distinct currency codes that are NOT aliases: `ZiG` (EcoCash, PayGo) and `ZWG` (Zimswitch, Omari). `ZWL` is a legacy code that appears nowhere in these APIs — never emit it.- Card payments (Visa, Mastercard, Zimswitch) are redirect-only. There is no seamless/direct card integration.- Seamless make-payment is POST /v2/payments/make-payment in both production and sandbox.- Sandbox and production keys are environment-specific and fail confusingly when crossed.
My task: <describe what you want built>Reviewing what it produces
Section titled “Reviewing what it produces”Generated Pesepay code fails in a small number of recognisable ways. Check these before you run it:
| Check | Why |
|---|---|
Is the body sent as {"payload": "..."}? | Plain JSON bodies are the most common generated mistake |
| Is the IV the first 16 characters of the encryption key? | Models default to a random IV prefixed to the ciphertext, which decrypts to nothing |
| Is it verifying a webhook signature? | There isn’t one. Any signature-verification code is invented |
| Does it treat the callback as final? | It isn’t — the status must be re-fetched |
| Are the keys reachable from the client? | Any key in frontend code is a live credential leak |
| Are currency and payment method codes ones the docs list? | ZWL and invented PZW codes are not real — check them against Payment method codes |