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_idfor safe retries
Authentication
Every request requires an API Key and API Secret issued by XP Reload admin.
Recommended headers:
X-Api-Key: xk_your_key_here
X-Api-Secret: xs_your_secret_here
Accept: application/json
Content-Type: application/jsonOr Bearer form:
Authorization: Bearer xk_your_key_here.xs_your_secret_hereConventions
Success envelope:
{
"success": true,
"data": { }
}Error envelope:
{
"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
List active games available for ordering.
curl "https://api.xpreload.com/api/v1/games" \
-H "X-Api-Key: xk_xxx" \
-H "X-Api-Secret: xs_xxx" \
-H "Accept: application/json"{
"success": true,
"data": {
"games": [
{
"id": 1,
"name": "Mobile Legends",
"code": "MLBB",
"slug": "mobile-legends",
"category": "MOBA"
}
]
}
}Products
Query params for list: game_code, search, per_page. Product price is your account price. Use required_parameters when creating orders.
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
Do not send amount or price. Server calculates the charge and deducts your wallet.
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"
}
}'{
"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
Wallet
Accounts are prepaid. Orders create purchase ledger entries. Supplier failures may create refund entries. Wallet top-ups are handled by XP Reload admin.
{
"success": true,
"data": {
"balance": 9915.0,
"currency": "PHP"
}
}Order statuses
| Status | Meaning |
|---|---|
| processing | Accepted / submitted; waiting for final result |
| successful | Top-up completed |
| failed | Failed (see failure_reason) |
| cancelled | Cancelled |
| refunded | Refunded 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:
X-Webhook-Id: 550e8400-e29b-41d4-a716-446655440000
X-Webhook-Timestamp: 1723165425
X-Webhook-Signature: <hmac_sha256_hex>
X-Webhook-Event: order.successfulVerify signature:
signed_payload = "{timestamp}.{raw_body}"
expected = HMAC_SHA256_HEX(webhook_secret, signed_payload)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
| Code | HTTP | Meaning |
|---|---|---|
| INVALID_API_KEY | 401 | Bad or missing credentials |
| FORBIDDEN | 403 | Suspended client / IP blocked |
| PRODUCT_NOT_FOUND | 404 | Unknown product |
| ORDER_NOT_FOUND | 404 | Unknown order (or not yours) |
| INVALID_PARAMETERS | 422 | Bad game parameters |
| INSUFFICIENT_BALANCE | 422 | Wallet too low |
| PRODUCT_UNAVAILABLE | 422 | Product unavailable |
| RATE_LIMIT_EXCEEDED | 429 | Too many requests |
| SUPPLIER_ERROR | 502 | Upstream fulfillment failed |
| INTERNAL_ERROR | 500 | Unexpected server error |
Quick integration flow
GET /products— pick product + required parametersGET /wallet— confirm balancePOST /orders— create with yourreference_id- On timeout, retry same
reference_id(safe) - Receive webhook
order.successful/order.failed - Optional:
GET /orders/{order_id}to confirm
docs/B2B_API_DEVELOPER_GUIDE.md.