XP Reload

API Documentation

B2B Top-up API · v1

Introduction

The XP Reload B2B API lets your application sell digital game top-ups through our platform. Your backend talks to our API; we handle pricing, wallet billing, supplier fulfillment, and status updates.

Base URL

https://api.xpreload.com/api/v1
  • Server-to-server only — never put API secrets in a browser app
  • JSON request/response
  • Prices are always calculated by XP Reload (never send an amount)
  • Use reference_id for safe retries

Authentication

Every request requires an API Key and API Secret issued by XP Reload admin.

Recommended headers:

headers
X-Api-Key: xk_your_key_here
X-Api-Secret: xs_your_secret_here
Accept: application/json
Content-Type: application/json

Or Bearer form:

Authorization
Authorization: Bearer xk_your_key_here.xs_your_secret_here

Conventions

Success envelope:

json
{
  "success": true,
  "data": { }
}

Error envelope:

json
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Insufficient client balance."
  }
}

Currency is PHP. Timestamps are ISO-8601.

Rate limits

Each client has a per-minute limit (default 60). Exceeding it returns HTTP 429 with code RATE_LIMIT_EXCEEDED. Respect Retry-After when present.

Idempotency

POST /orders requires reference_id. Replaying the same reference for the same client returns the original order and does not charge again. Use your internal order ID as the reference.

Games

GET/api/v1/games

List active games available for ordering.

curl
curl "https://api.xpreload.com/api/v1/games" \
  -H "X-Api-Key: xk_xxx" \
  -H "X-Api-Secret: xs_xxx" \
  -H "Accept: application/json"
response
{
  "success": true,
  "data": {
    "games": [
      {
        "id": 1,
        "name": "Mobile Legends",
        "code": "MLBB",
        "slug": "mobile-legends",
        "category": "MOBA"
      }
    ]
  }
}

Products

GET/api/v1/products
GET/api/v1/products/{productCode}

Query params for list: game_code, search, per_page. Product price is your account price. Use required_parameters when creating orders.

curl
curl "https://api.xpreload.com/api/v1/products?game_code=MLBB" \
  -H "X-Api-Key: xk_xxx" \
  -H "X-Api-Secret: xs_xxx" \
  -H "Accept: application/json"

Orders

Create order

POST/api/v1/orders

Do not send amount or price. Server calculates the charge and deducts your wallet.

curl
curl -X POST "https://api.xpreload.com/api/v1/orders" \
  -H "X-Api-Key: xk_xxx" \
  -H "X-Api-Secret: xs_xxx" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{
    "reference_id": "CLIENT-ORDER-12345",
    "product_id": "MLBB-86",
    "parameters": {
      "user_id": "123456789",
      "zone_id": "1234"
    }
  }'
201 response
{
  "success": true,
  "data": {
    "order_id": "API260809ABCDEF",
    "reference_id": "CLIENT-ORDER-12345",
    "status": "processing",
    "product": { "id": "MLBB-86", "name": "86 Diamonds" },
    "amount": 85.0,
    "currency": "PHP",
    "quantity": 1,
    "supplier_reference": "SUP-XXXX",
    "failure_reason": null,
    "created_at": "2026-08-09T01:23:45+00:00",
    "completed_at": null
  }
}

Get order

GET/api/v1/orders/{order_id}
GET/api/v1/orders?reference_id=CLIENT-ORDER-12345
GET/api/v1/orders?per_page=20

Wallet

GET/api/v1/wallet
GET/api/v1/wallet/transactions

Accounts are prepaid. Orders create purchase ledger entries. Supplier failures may create refund entries. Wallet top-ups are handled by XP Reload admin.

wallet response
{
  "success": true,
  "data": {
    "balance": 9915.0,
    "currency": "PHP"
  }
}

Order statuses

StatusMeaning
processingAccepted / submitted; waiting for final result
successfulTop-up completed
failedFailed (see failure_reason)
cancelledCancelled
refundedRefunded when applicable

Webhooks

Configure your webhook URL with XP Reload admin. We POST signed events when order status changes.

Events: order.processing, order.successful, order.failed, order.refunded

Headers:

http
X-Webhook-Id: 550e8400-e29b-41d4-a716-446655440000
X-Webhook-Timestamp: 1723165425
X-Webhook-Signature: <hmac_sha256_hex>
X-Webhook-Event: order.successful

Verify signature:

formula
signed_payload = "{timestamp}.{raw_body}"
expected = HMAC_SHA256_HEX(webhook_secret, signed_payload)
Node.js verify
const crypto = require("crypto");

function verifyWebhook(rawBody, timestamp, signature, secret, maxAgeSec = 300) {
  const age = Math.abs(Date.now() / 1000 - Number(timestamp));
  if (age > maxAgeSec) return false;

  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");

  try {
    return crypto.timingSafeEqual(
      Buffer.from(expected, "utf8"),
      Buffer.from(signature, "utf8")
    );
  } catch {
    return false;
  }
}

Errors

CodeHTTPMeaning
INVALID_API_KEY401Bad or missing credentials
FORBIDDEN403Suspended client / IP blocked
PRODUCT_NOT_FOUND404Unknown product
ORDER_NOT_FOUND404Unknown order (or not yours)
INVALID_PARAMETERS422Bad game parameters
INSUFFICIENT_BALANCE422Wallet too low
PRODUCT_UNAVAILABLE422Product unavailable
RATE_LIMIT_EXCEEDED429Too many requests
SUPPLIER_ERROR502Upstream fulfillment failed
INTERNAL_ERROR500Unexpected server error

Quick integration flow

  1. GET /products — pick product + required parameters
  2. GET /wallet — confirm balance
  3. POST /orders — create with your reference_id
  4. On timeout, retry same reference_id (safe)
  5. Receive webhook order.successful / order.failed
  6. Optional: GET /orders/{order_id} to confirm
Need credentials or wallet top-up? Contact your XP Reload administrator. Full markdown guide also lives in the backend repo at docs/B2B_API_DEVELOPER_GUIDE.md.