Partner S2S API (1.0.0)

Download OpenAPI specification:

Server-to-Server API for automated partner integrations with digital goods distribution platform.

Authentication

All requests require Bearer token:

Authorization: Bearer {your-s2s-token}

Info

Authentication and balance info

Verify token

Get authenticated partner information

Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get balance

Current balance with overdraft information

Authorizations:
BearerAuth

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get balance transaction history

Paginated balance transaction history (cursor-based pagination)

Authorizations:
BearerAuth
query Parameters
cursor
string

Pagination cursor from meta.next_cursor

per_page
integer [ 1 .. 100 ]
Default: 50

Items per page (max 100)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "meta": {
    }
}

Catalog

Product catalog

List products

Get paginated product list with optional filters

Authorizations:
BearerAuth
query Parameters
cursor
string

Pagination cursor from previous response

per_page
integer <= 200
Default: 100

Items per page

category_id
integer

Filter by category

type
string
Enum: "voucher" "recharge_fixed" "recharge" "voucher_open_range" "esim" "other"

Filter by product type

include_skus
boolean
Default: false

Include SKU list (without pricing)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "meta": {
    }
}

Get product details

Get product with SKUs, pricing and stock information

Authorizations:
BearerAuth
path Parameters
uuid
required
string <uuid>

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Get pricelist

SKU prices and stock status (optimized for price sync)

Authorizations:
BearerAuth
query Parameters
cursor
string
per_page
integer <= 200
Default: 100
category_id
integer
type
string
Enum: "voucher" "recharge_fixed" "esim"

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "meta": {
    }
}

Get categories

Available categories with attributes

Authorizations:
BearerAuth
query Parameters
target
string
Enum: "product" "sku"

Filter attributes by target

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ]
}

Orders

Order management

List orders

Get order history with filters

Authorizations:
BearerAuth
query Parameters
cursor
string
per_page
integer <= 100
Default: 50
status
string
Enum: "created" "processing" "completed" "cancelled" "failed" "partially_completed"
external_id
string

Search by your order ID

date_from
string <date-time>
Example: date_from=2025-01-01T00:00:00Z
date_to
string <date-time>
Example: date_to=2025-01-31T23:59:59Z

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": [
    ],
  • "meta": {
    }
}

Create order

Create new order. Requires HMAC-SHA256 signature for S2S authentication.

Authentication Requirements

  • X-Timestamp header is required
  • X-Signature header is required
  • Authorization: Bearer {s2s_token} is required

Signature Calculation

Step 1: Get current Unix timestamp

const timestamp = Math.floor(Date.now() / 1000); // e.g., 1768478058

Step 2: Prepare JSON body

{
  "external_id": "ORD-12345",
  "item": {
    "sku_id": "019bc0dd-8562-7173-afd9-a5cc534fafb7",
    "quantity": 1
  }
}

Step 3: Build payload string

const payload = timestamp + "." + JSON.stringify(body);
// Result: "1768478058.{\"external_id\":\"ORD-12345\",\"item\":{\"sku_id\":\"019bc0dd-8562-7173-afd9-a5cc534fafb7\",\"quantity\":1}}"

Step 4: Calculate HMAC-SHA256 signature

const crypto = require('crypto');
const signature = crypto
  .createHmac('sha256', partnerSecret)  // Use your partner secret
  .update(payload)
  .digest('hex');
// Result: "13fbd7a9a501ea39aeec861a27158dfa00c491aa657798adac8ed9b2066a6fa2"

Step 5: Send request with headers

curl -X POST https://api.example.com/v1/partner/orders \
  -H "Authorization: Bearer {your_s2s_token}" \
  -H "X-Timestamp: 1768478058" \
  -H "X-Signature: 13fbd7a9a501ea39aeec861a27158dfa00c491aa657798adac8ed9b2066a6fa2" \
  -H "Content-Type: application/json" \
  -d '{"external_id":"ORD-12345","item":{"sku_id":"019bc0dd-8562-7173-afd9-a5cc534fafb7","quantity":1}}'

Important Notes

  • Timestamp tolerance: ±5 minutes from server time
  • Secret location: Get partner_secret from your partner settings (not the API token!)
  • Body format: Use exact JSON body sent in request (no whitespace changes)
  • external_id uniqueness: Must be unique across all your orders
  • Balance check: Ensure sufficient balance (including overdraft if enabled)

Code Examples

JavaScript/Node.js

const crypto = require('crypto');

const timestamp = Math.floor(Date.now() / 1000);
const body = {
  external_id: "ORD-12345",
  item: { sku_id: "019bc0dd-8562-7173-afd9-a5cc534fafb7", quantity: 1 }
};
const payload = timestamp + "." + JSON.stringify(body);
const signature = crypto.createHmac('sha256', partnerSecret).update(payload).digest('hex');

fetch('https://api.example.com/v1/partner/orders', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${s2sToken}`,
    'X-Timestamp': timestamp.toString(),
    'X-Signature': signature,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(body)
});

PHP

$timestamp = time();
$body = json_encode([
    'external_id' => 'ORD-12345',
    'item' => [
        'sku_id' => '019bc0dd-8562-7173-afd9-a5cc534fafb7',
        'quantity' => 1
    ]
]);
$payload = $timestamp . '.' . $body;
$signature = hash_hmac('sha256', $payload, $partnerSecret);

$ch = curl_init('https://api.example.com/v1/partner/orders');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Authorization: Bearer ' . $s2sToken,
    'X-Timestamp: ' . $timestamp,
    'X-Signature: ' . $signature,
    'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
$response = curl_exec($ch);

Python

import time
import json
import hmac
import hashlib
import requests

timestamp = int(time.time())
body = {
    "external_id": "ORD-12345",
    "item": {
        "sku_id": "019bc0dd-8562-7173-afd9-a5cc534fafb7",
        "quantity": 1
    }
}
body_json = json.dumps(body, separators=(',', ':'))
payload = f"{timestamp}.{body_json}"
signature = hmac.new(
    partner_secret.encode('utf-8'),
    payload.encode('utf-8'),
    hashlib.sha256
).hexdigest()

response = requests.post(
    'https://api.example.com/v1/partner/orders',
    headers={
        'Authorization': f'Bearer {s2s_token}',
        'X-Timestamp': str(timestamp),
        'X-Signature': signature,
        'Content-Type': 'application/json'
    },
    json=body
)
Authorizations:
BearerAuth
header Parameters
X-Timestamp
required
integer
Example: 1768478058

Unix timestamp (tolerance ±5 minutes)

X-Signature
required
string
Example: 13fbd7a9a501ea39aeec861a27158dfa00c491aa657798adac8ed9b2066a6fa2

HMAC-SHA256 signature (hex)

Request Body schema: application/json
required
external_id
required
string

Your unique order identifier

required
object
metadata
object or null

Custom metadata for your records

Responses

Request samples

Content type
application/json
{
  • "external_id": "ORD-12345",
  • "item": {
    }
}

Response samples

Content type
application/json
{
  • "success": true,
  • "message": "Order created successfully",
  • "data": {
    }
}

Get order details

Get order by UUID

Authorizations:
BearerAuth
path Parameters
uuid
required
string <uuid>
Example: 7898e683-4e56-44a3-9782-eca3f758a844

Order UUID

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Services

Post-purchase service management (eSIM, subscriptions, etc.)

Get eSIM status

Get current status, data balance, and details for an eSIM by ICCID.

Authorizations:
BearerAuth
path Parameters
iccid
required
string
Example: 8944422711108338982

eSIM ICCID (unique identifier)

Responses

Response samples

Content type
application/json
{
  • "success": true,
  • "data": {
    }
}

Webhooks

Outgoing webhooks sent to your server when order statuses change.

Setup

Configure your webhook URL in partner settings. The system will send HTTP POST requests to that URL on order events.

Signature Verification

Every webhook request includes two headers for authenticity verification:

  • X-Timestamp — Unix timestamp (seconds)
  • X-Signature — HMAC-SHA256 signature

Signature calculation:

payload = timestamp + "." + request_body
signature = HMAC-SHA256(payload, partner_secret)

Verification example (PHP):

$timestamp = $_SERVER['HTTP_X_TIMESTAMP'];
$signature = $_SERVER['HTTP_X_SIGNATURE'];
$body = file_get_contents('php://input');

// Protect against replay attacks (±5 min tolerance)
if (abs(time() - (int)$timestamp) > 300) {
    http_response_code(400);
    exit('Timestamp expired');
}

$expected = hash_hmac('sha256', $timestamp . '.' . $body, $partnerSecret);
if (!hash_equals($expected, $signature)) {
    http_response_code(401);
    exit('Invalid signature');
}

Verification example (Python):

import hmac, hashlib, time

timestamp = request.headers['X-Timestamp']
signature = request.headers['X-Signature']
body = request.get_data(as_text=True)

if abs(time.time() - int(timestamp)) > 300:
    return 'Timestamp expired', 400

expected = hmac.new(
    partner_secret.encode(),
    f"{timestamp}.{body}".encode(),
    hashlib.sha256
).hexdigest()

if not hmac.compare_digest(expected, signature):
    return 'Invalid signature', 401

Idempotency

Each webhook includes a unique idempotency_key (UUID). Use it to safely handle duplicate deliveries — the same event may be retried up to 5 times with exponential backoff if your server doesn't return HTTP 2xx.

Response Requirements

Your endpoint must return HTTP 2xx within 10 seconds. Non-2xx responses or timeouts are treated as failures and trigger retries.

Order status changed Webhook

Sent when an order reaches status: completed, failed or partially_completed.

Request Body schema: application/json
required
event
string
Value: "order.status_changed"
timestamp
string <date-time>

ISO 8601 timestamp of when the event occurred

idempotency_key
string <uuid>

Unique key for this delivery — use to safely deduplicate retries

object

Responses

Request samples

Content type
application/json
Example
{
  • "event": "order.status_changed",
  • "timestamp": "2026-01-15T12:58:23+00:00",
  • "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
  • "data": {
    }
}