Skip to content

Northbound API V2

Northbound API V2 is designed to be used by tenants

Authentication

To authenticate your request, include an Authorization header with the following value:

plaintext
Bearer {API_KEY}

Signature

To secure your requests, include an X-Signature header in every call. This signature is generated using HMAC-SHA256 with your API secret key.

Construct the string to be signed by joining the following components with a newline character (\n):

[METHOD]\n[URI]\n[BODY]
TS
import { createHmac } from "crypto";

/**
 * Generates the HMAC SHA256 signature for the request.
 * @param secret - Your API secret key
 * @param method - HTTP method (e.g., "POST")
 * @param uri - The request URI (e.g., "/v1/resource")
 * @param payload - The stringified request body
 */
function generateSignature(
  secret: string,
  method: string,
  uri: string,
  payload: string,
): string {
  const data = `${method}\n${uri}\n${payload}`;
  return createHmac("sha256", secret).update(data).digest("hex");
}
PHP
<?php
/**
 * Generates the HMAC SHA256 signature for the request.
 * 
 * @param string $secret Your API secret key
 * @param string $method HTTP method (e.g., "POST")
 * @param string $uri The request URI (e.g., "/v1/resource")
 * @param string $payload The request body
 * @return string
 */
function generateSignature($secret, $method, $uri, $payload = '') {
    $data = implode(PHP_EOL, array_merge($method, $uri, $payload));
    return hash_hmac('sha256', $data, $secret);
}
?>
JAVA
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;
import java.util.HexFormat;

public class SignatureGenerator {
    /**
     * Generates the HMAC SHA256 signature for the request.
     */
    public static String generateSignature(String secret, String method, String uri, String payload) throws Exception {
        String data = method + "\n" + uri + "\n" + payload;
        
        Mac sha256Hmac = Mac.getInstance("HmacSHA256");
        SecretKeySpec secretKey = new SecretKeySpec(
            secret.getBytes(StandardCharsets.UTF_8), 
            "HmacSHA256"
        );
        sha256Hmac.init(secretKey);
        
        byte[] signedBytes = sha256Hmac.doFinal(data.getBytes(StandardCharsets.UTF_8));
        return HexFormat.of().formatHex(signedBytes);
    }
}

Endpoints

List Orders Requires authentication

GET /api/northbound/v2/transactions

Retrieve a list of all orders.

Headers
HeaderTypeRequiredDescription
AuthorizationstringyesBearer token
X-SignaturestringyesSignature
Response Fields
FieldTypeDescription
dataarrayList of Order Transaction objects
linksarrayPagination links
metaarrayPagination metadata
json
{
  "status": "success",
  "code": 200,
  "data": []
}
json
{
  "status": "error",
  "code": 500,
  "message": "error_message",
  "tracking": "<uuid>"
}

Create Order Requires authentication

POST /api/northbound/v2/transactions

Create a new order.

Headers
HeaderTypeRequiredDescription
AuthorizationstringyesBearer token
X-SignaturestringyesSignature
Body Parameters
ParameterTypeRequiredDescription
transaction_idstringyesUnique reference
tenant_idstringyesTenant ID
game_namestringyesGame name
countrystringyesCountry code in iso_3166_2 format
payment_channelstringyesPayment channel
amount_centsintyesAmount in cents
currencystringyesCurrency
item_titlestringyesTitle
item_descriptionstringnoDescription
item_codestringyesItem code
return_urlstringyesReturn URL
webhook_urlstringnoWebhook URL for callback
accountarraynoGame account info
account.server_namestringnoGame character server name
account.login_idstringnoGame character login ID
account.namestringnoGame character name
json
{
  "transaction_id": "some-unique-string",
  "tenant_id": "01KGKW7222XT1WACCWA6MK7888",
  "game_name": "ragnarok-origin-global",
  "payment_channel": "qr_promptpay_thb",
  "country": "MY",
  "amount_cents": 1000,
  "currency": "MYR",
  "title": "Nyan Berry Pack (24,000)",
  "description": "Ragnarok Origin",
  "item_code": "roo-item-246",
  "merchant_return_url": "https://example.com",
  "webhook_url": "https://example.com/webhook",
  "account": {
    "server_name": "Prontera",
    "login_id": "FGHJK1234",
    "name": "Kuro"
  }
}
json
{
  "status": "success",
  "code": 201,
  "data": {
    "type": "payment_transaction",
    "order_id": "01KJMYWXST80RQMVHAQ0EJN8N4",
    "transaction_id": "f1275362-0597-4264-8af7-864cb5f3f039",
    "reference": "",
    "tenant_id": "01KGKW7222XT1WACCWA6MK7888",
    "game_name": "ragnarok-origin-global",
    "payment_channel": "qr_promptpay_thb",
    "amount_cents": "1000",
    "currency": "MYR",
    "item_title": "Nyan Berry Pack (24,000)",
    "item_description": "Ragnarok Origin",
    "item_code": "roo-item-246",
    "status": "created",
    "paylink": "https://games.oneone.com/api/northbound/orders/01KJMYWXST80RQMVHAQ0EJN8N4",
    "verify_url": "https://games.oneone.com/api/northbound/transactions/01KJMYWXST80RQMVHAQ0EJN8N4"
  }
}
json
{
  "status": "error",
  "code": 422,
  "message": "The selected payment channel is invalid."
}
json
{
  "status": "error",
  "code": 500,
  "message": "Error message",
  "tracking": "216d3de6-122c-47b1-8d39-089df90302bd"
}

Get Order Requires authentication

GET /api/northbound/transactions/{order_id}

Retrieve details of a specific order.

Headers
HeaderTypeRequiredDescription
AuthorizationstringyesBearer token
X-SignaturestringyesSignature
URL Parameters
ParameterTypeRequiredDescription
order_idstringyesOrder ID
json
{
  "status": "success",
  "code": 200,
  "data": {
    "type": "payment_transaction",
    "order_id": "01HXBENQCRV4W42NE4WC98QTGY",
    "transaction_id": "265879d0-4099-4efc-a70c-a06fdaa70c2f",
    "reference": "",
    "tenant_id": "01KGKW7222XT1WACCWA6MK7888",
    "game_name": "ragnarok-origin-global",
    "payment_channel": "qr_promptpay_thb",
    "amount_cents": 1000,
    "currency": "MYR",
    "item_title": "Nyan Berry Pack (24,000)",
    "item_description": "Ragnarok Origin",
    "item_code": "roo-item-246",
    "status": "created",
    "paylink": "https://games.oneone.com/api/northbound/orders/01HXBENQCRV4W42NE4WC98QTGY",
    "verify_url": "https://games.oneone.com/api/northbound/transactions/01HXBENQCRV4W42NE4WC98QTGY"
  }
}
json
{
  "status": "error",
  "code": 404,
  "message": "Transaction not found"
}
json
{
  "status": "error",
  "code": 500,
  "message": "Error message",
  "tracking": "216d3de6-122c-47b1-8d39-089df90302bd"
}

Callbacks

Payment Success

After a successful payment, we will send a POST request to your callback URL with this payload:

json
{
    "type": "payment_transaction",
    "order_id": "01HXBENQCRV4W42NE4WC98QTGY",
    "transaction_id": "265879d0-4099-4efc-a70c-a06fdaa70c2f",
    "reference": "",
    "tenant_id": "01KGKW7222XT1WACCWA6MK7888",
    "game_name": "ragnarok-origin-global",
    "payment_channel": "qr_promptpay_thb",
    "amount_cents": 1000,
    "currency": "MYR",
    "item_title": "Nyan Berry Pack (24,000)",
    "item_description": "Ragnarok Origin",
    "item_code": "roo-item-246",
    "status": "paid",
    "paylink": "https://games.oneone.com/api/northbound/orders/01HXBENQCRV4W42NE4WC98QTGY",
    "verify_url": "https://games.oneone.com/api/northbound/transactions/01HXBENQCRV4W42NE4WC98QTGY"
  }

Ensure that your callback URL returns a 200 status code upon successful processing. We will retry the callback up to 3 times if it fails.