Paylume API

A small REST API: create a payment, send the customer to checkout_url, and listen for a signed webhook. Base URL: https://paylume.besends.com/api/v1

Authentication

Use your secret key as a bearer token. sk_test_ keys create test payments (simulator + sandbox gateways, no money moves). sk_live_ keys unlock after verification. Keep keys server-side only.

Authorization: Bearer sk_test_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Create a payment

POST /payments — amounts are integers in minor units (2500 = 25.00). Send an Idempotency-Key header so retries never double-charge.

FieldTypeDescription
amount*integerMinor units, > 0
currency*stringUSD, EUR, GBP, BDT, INR, AUD, CAD, SGD, AED, MYR
descriptionstringShown on the checkout (≤ 500)
referencestringYour order id (≤ 120)
customerobject{ email, name } — prefills provider pages
success_urlurlCustomer returns here with ?payment_id=…&status=succeeded
cancel_urlurlCustomer returns here on cancel
metadataobjectUp to 20 string key/values, echoed back in webhooks
curl https://paylume.besends.com/api/v1/payments \
  -H "Authorization: Bearer $PAYLUME_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order_1001" \
  -d '{"amount":2500,"currency":"USD","reference":"order_1001",
       "success_url":"https://shop.example/thanks","cancel_url":"https://shop.example/cart"}'

Retrieve & list

GET /payments/{id}
GET /payments?limit=20&created_before=2026-09-01T00:00:00Z
GET /balance          # live balances by currency: available / pending / reserve

The payment object

{
  "id": "pay_8fK2xQ…",
  "object": "payment",
  "mode": "live",
  "status": "succeeded",      // requires_payment_method | processing | succeeded | expired | canceled
  "amount": 2500,
  "currency": "USD",
  "reference": "order_1001",
  "method": "card",
  "fee": 103,                 // your package commission (+ gateway surcharge)
  "net": 2397,
  "metadata": {},
  "paid_at": "2026-09-27T14:02:11.000Z",
  "expires_at": "…", "created_at": "…",
  "checkout_url": "https://paylume.besends.com/pay/pay_…?t=…"
}

A failed attempt (declined card, cancelled wallet) keeps the payment open so the customer can retry with another method until it expires.

Webhooks

Set an HTTPS endpoint in Developers. Events: payment.succeeded, payment.processing, payment.expired, payout.paid, payout.rejected. Respond 2xx within 10 s; failures retry at 1m, 5m, 30m, 2h, 6h, 12h, 24h.

Verify Paylume-Signature: t=…,v1=… — HMAC-SHA256 of `${t}.${rawBody}` with your signing secret. Reject if the timestamp is older than 5 minutes. Deduplicate on Paylume-Delivery.

{
  "id": "evt_…",
  "type": "payment.succeeded",
  "created": 1790000000,
  "data": { …payment object… }
}

Errors & limits

HTTP 401 { "error": { "code": "unauthorized", ... } }
HTTP 403 no_package          — live key but no active package
HTTP 400 amount_over_limit   — above your package's per-transaction limit
HTTP 400 monthly_limit       — package monthly volume reached
HTTP 422 validation_error    — "issues": [{ "path": "amount", "message": "..." }]
HTTP 429 rate_limited        — 120 requests / minute / key

Testing

With a test key, the checkout offers the Test simulator (choose Succeed or Decline) plus any sandbox gateways the platform has enabled. Test payments fire real webhooks to your endpoint but never touch your balance.

API documentation · Paylume