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 → 200 proves 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-Key on every POST, PUT and DELETE.
  • 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 parse message.
  • Unknown code → treat by status class.
  • 4xx → fix the request. 5xx → retry later, same key.

Next: Payment lifecycle.