Getting started
The basics every other guide assumes: environments, authentication, money format, idempotency and errors.
flowchart LR
customer["Your customer"]
subgraph yours["Your systems"]
direction TB
server["Your server"]
hook["Your webhook endpoint"]
end
api["Partner API"]
customer -- "checkout" --> server
server -- "HTTPS + API key" --> api
api -- "QR or redirect" --> server
server -- "show it" --> customer
api -- "result event" --> hook
- Only your server calls the API. Browsers are refused (no CORS).
- Results reach you two ways: read the payment, or receive a webhook.
Environments
| Environment | Base URL | Money |
|---|---|---|
| Sandbox | https://sandbox.beever.xyz/v1 |
None moves |
| Production | https://api.beever.xyz/v1 |
Real |
- Use a separate API key per environment.
Authentication
GET /v1/me HTTP/1.1
Authorization: Bearer <your API key>
GET /me→200proves key, base URL and TLS work.- Keep keys server-side. Never ship one to a browser or app.
Money
- Decimal string, major units, plus currency:
{"amount": "150.00", "currency": "MYR"}. - Never a float. Never cents.
- No more decimals than the currency allows (
"150.00"MYR,"150"JPY). Extra precision →400, never rounded.
Idempotency
- Send an
Idempotency-Keyon everyPOST,PUTandDELETE. - A retry with the same key can never create a second payment.
sequenceDiagram participant You as Your server participant API as Partner API You->>API: POST /payments (key k1) API--xYou: response lost You->>API: POST /payments (key k1, same body) API-->>You: 201, the SAME payment You->>API: POST /payments (key k1, different body) API-->>You: 409 idempotency_conflict
| You send | You get |
|---|---|
| Same key, same body | First response, replayed |
| Same key, different body | 409 idempotency_conflict |
| Same key, first still running | 409 in_progress — retry shortly |
- One key per intent (e.g. per order attempt). Reuse it only for retries.
- Refusals replay too. Fixed the cause? Retry with a new key.
- Keys expire after 24h.
Errors
{ "error": { "code": "validation_error", "message": "amount has more decimal places than MYR allows" } }
- Branch on
error.code. Never parsemessage. - Unknown code → treat by status class.
4xx→ fix the request.5xx→ retry later, same key.
Next: Payment lifecycle.