Olympus AscendOur official launch event, 12 November 202612 Nov 2026Learn more
Olympus Pay

Build on the Olympus API.

REST endpoints for payments, links, QR codes, payouts, settlements and webhooks. Test with sandbox keys, then switch to live.

# Create a payment link (sandbox key)
curl -X POST https://merchant.olympuspay.co/api/v1/payment-links \
  -H "Authorization: Bearer olp_test_…" \
  -H "Idempotency-Key: 7f3c1a52-order-1042" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Invoice 1042",
    "amount": 126.00,
    "currency": "BWP",
    "returnUrl": "https://example.com/thanks"
  }'
const res = await fetch("https://merchant.olympuspay.co/api/v1/payment-links", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.OLYMPUS_KEY}`,
    "Idempotency-Key": "7f3c1a52-order-1042",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    title: "Invoice 1042",
    amount: 126.00,
    currency: "BWP",
  }),
});
const link = await res.json();
// 200 OK - the payment link object (fields shown are illustrative)
{
  "id": "…",
  "title": "Invoice 1042",
  "amount": 126,
  "currency": "BWP",
  "url": "https://…"
}

Sandbox keys begin olp_test_. Live keys begin olp_live_.

Quick start.

  1. Create a sandbox key

    In the merchant dashboard, open Developers and create a test key. Copy it once; only a hash is stored.

  2. Call the API

    Send it as a bearer token. Add an Idempotency-Key when you create things.

  3. Register a webhook

    Give us an HTTPS URL. The signing secret is shown once.

  4. Go live

    When your business is verified, create a live key and swap it in.

Authentication and scopes.

Every request carries a bearer key. Each endpoint requires a specific scope, so a key that reads settlements cannot create payouts.

  • Bearer authentication with Authorization: Bearer olp_…
  • Sandbox and live keys with separate prefixes
  • Scopes such as payments:read, refunds:create_partial, payouts:create
  • Hashed at rest; the secret is shown once
  • Redirect allowlist per key for return URLs
  • Request activity visible per key
Scopes (examples)
# Read-only reporting key
payments:read
settlements:read

# Checkout-creation key
payment_links:write
qr_codes:write

# Sensitive, keep separate
refunds:create_full
refunds:create_partial
payouts:create

Webhooks.

Register an endpoint to be notified as events happen. Each delivery carries the event name, a timestamp and an HMAC-SHA256 signature of the raw body.

  • payment.succeeded
  • payment.failed
  • payment.refunded
  • payout.completed
  • payout.failed

Deliveries are logged with attempt numbers, and a failed delivery can be retried with a fresh signature timestamp.

Verify a webhook
function verify(rawBody, headers, secret) {
  const ts  = headers["x-olympus-timestamp"];
  const sig = headers["x-olympus-signature"];
  // HMAC-SHA256 over "{timestamp}.{raw body}", hex encoded
  const expected = hmacSha256Hex(secret, `${ts}.${rawBody}`);
  // Also reject old timestamps to stop replays
  return constantTimeEqual(sig, expected);
}

Built for retries.

Idempotency

Send an Idempotency-Key when creating a payment link. Retrying the same key returns the original instead of a duplicate.

Sandbox

Test keys never touch a real processor, and payouts are rejected on them so real funds cannot move.

Second reviewer

Refunds and payouts above a threshold return 202 and wait for approval on live keys.