GAGA Game Server API (0.1)

Download OpenAPI specification:

Server-to-server API that the game server implements and the GAGA backend calls. It lets GAGA look up servers and characters by GAGA ID, and deliver purchased items (G Coin first) to a character's in-game mailbox.

中文摘要:本 API 由遊戲伺服器實作,由 GAGA 後端呼叫(伺服器對伺服器)。 用途:查詢伺服器列表、用 GAGA ID 查角色、把購買的道具(先從 G Coin 開始)寄到角色信箱。 與 GAGA SDK、遊戲客戶端、Google Play / App Store 內購無關。

Where this API is used

First consumer: Funtap (VN) web top-up. The player pays on nap.funtap.games; Funtap calls the GAGA backend; the GAGA backend calls this API.

Step Caller → Callee API
1 Funtap → GAGA BE Get servers (Funtap S2S)
1a GAGA BE → Game server GET /servers
2 Funtap → GAGA BE Find role by account_id (Funtap S2S)
2a GAGA BE → Game server GET /roles
3 Player pays on Funtap —
4 Funtap → GAGA BE Payment notification → GAGA verifies with Funtap inquiry
5 GAGA BE → Game server POST /mails — G Coin to mailbox
6 GAGA BE → Game server (only on timeout / 5xx) GET /mails/{invoice_id}

The same contract will be reused later for GAGA Web Shop direct delivery (other item types in items[]), so implement items as a list, not a single G Coin field.

Field names follow the Funtap S2S guide (v2.7) on purpose — server_id, server_name, account_id, role_id, role_name, os, invoice_id, product_id, created_at — so values pass through GAGA unchanged.

Differences from Funtap S2S

Funtap S2S v2.7 This API
Auth client_id + per-endpoint SHA256(secret + params) signature + 5-min timestamp X-Client-Id + X-Api-Key headers over HTTPS + IP allowlist. No signature, no timestamp.
Response shape Mixed (raw array / raw object / {code}) Always {code, message, data}
Find role Spec says array, example shows object Always an array
Request body (POST) form-urlencoded application/json
Retry safety Partner dedupes pay_id Game server dedupes invoice_id (see Idempotency)

Authentication

Every request carries two headers. Credentials are issued by GAGA, one pair per environment (staging and production never share a key).

Header Example Notes
X-Client-Id gaga-xlegend-stg Identifies GAGA environment / game
X-Api-Key sk_stg_9f2c… Static secret, ≥ 32 chars. Compare in constant time.

Transport and network rules:

  • HTTPS only (TLS 1.2+). Reject plain HTTP.
  • IP allowlist: accept calls only from GAGA backend egress IPs (GAGA provides the list per environment). Required on production — POST /mails creates in-game value, and the API key alone is the only other control.
  • Key rotation: GAGA sends a new key; the game server accepts both old and new for an agreed window, then drops the old one.
  • Never log the full X-Api-Key.

Wrong or missing credentials → HTTP 401, code: 401. Source IP not allowed → HTTP 403, code: 403.

Response envelope

All responses are JSON:

{ "code": 200, "message": "OK", "data": { } }
  • code is an integer and equals the HTTP status (200 on success). There is no code: 0.
  • message is human-readable, English, for logs only. GAGA never parses it.
  • data is present on success; it may be omitted on error.
code HTTP Meaning GAGA retries?
200 200 Success (also for a duplicate invoice_id — see Idempotency) —
400 400 Missing / malformed parameter No
401 401 Bad X-Client-Id / X-Api-Key No
403 403 Source IP not allowed No
404 404 Account, server, role or invoice not found No (on GET /mails/{invoice_id}: means not delivered yet)
409 409 Same invoice_id already used with a different payload No — alert
422 422 Unknown item_id, bad quantity, or role cannot receive mail No — alert
500 500 Unexpected error Yes
503 503 Server maintenance / temporarily unavailable Yes

Idempotency

invoice_id (GAGA's transaction id) is the idempotency key for POST /mails.

  1. Store invoice_id with a unique constraint in the same transaction that creates the mail.
  2. Same invoice_id + same payload again → do not send another mail; return 200 with the original mail_id and "duplicate": true.
  3. Same invoice_id + different account_id / server_id / role_id / items → 409.
  4. Keep invoice_id records for at least 90 days.

GAGA retry behaviour (so you know what to expect):

  • Timeout: 10 s per call.
  • On timeout, network error, 500 or 503: GAGA first calls GET /mails/{invoice_id}. If 200 → done. If 404 → GAGA re-sends POST /mails with the same invoice_id.
  • Back-off: 30 s, 2 min, 10 min, 1 h, then every 6 h up to 72 h, then manual handling.

Data formats

Field Format
account_id GAGA ID, canonical form without dashes, 16 chars: THGA284190375216 (display form TH-GA-284190375216). The same value the game server receives as gaga_id from GAGA SDK login.
*_id String. Do not assume numeric.
created_at, sent_at Unix timestamp, seconds, integer.
quantity Integer ≥ 1.
Text UTF-8. role_name may contain CJK / Vietnamese / Thai characters.

Environments

The game server provides two base URLs (staging and production), as Funtap requires separate test and live endpoints. Paths below are fixed; only the base URL changes.

Env Base URL (provided by game team) Credentials (provided by GAGA)
Staging https://<stg-host>/gaga/v1 X-Client-Id / X-Api-Key (stg) + GAGA stg egress IPs
Production https://<prod-host>/gaga/v1 X-Client-Id / X-Api-Key (prod) + GAGA prod egress IPs

What the game team provides

  1. Base URLs (staging, production).
  2. G Coin item_id (and any other item_id GAGA may send), with max quantity per mail.
  3. Mailbox expiry rule (how long an unclaimed mail stays) and attachment limit per mail.
  4. A staging server with test accounts that have characters, for joint testing.

Not in scope

  • GAGA SDK, game client changes, Google Play / App Store purchases.
  • Funtap "check item condition" / "list item available" — answered by the GAGA backend, not the game server.
  • Refund / item removal (to be agreed separately).

Server & Role

Lookups used while the player fills the Funtap top-up form.

List game servers

Returns every server the player can top up to. Mirrors Funtap S2S 1. Get game server/area.

Include servers under maintenance only if they can still receive mail later; GAGA caches this list for 5 minutes.

Authorizations:
(ClientIdApiKey)

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "OK",
  • "data": [
    ]
}

Find characters by GAGA ID

Returns the characters that a GAGA account has on one server. Mirrors Funtap S2S 2. Find game role, but always returns an array (the player picks one in a dropdown).

  • Account has no game data, or no character on that server → 404.
  • Do not reveal whether the GAGA ID exists on other servers.
Authorizations:
(ClientIdApiKey)
query Parameters
account_id
required
string^[A-Z]{4}[0-9]{12}$
Example: account_id=VNGA284190375216

GAGA ID, canonical form (no dashes).

server_id
required
string
Example: server_id=12345

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "OK",
  • "data": [
    ]
}

Mail Delivery

Deliver purchased items to a character's mailbox, and check delivery status.

Send items to a character's mailbox

Delivers items (e.g. G Coin) as a mail attachment. Called after GAGA has verified the payment with Funtap. Equivalent of Funtap S2S 3. Payment notification, one hop further down.

Idempotent on invoice_id — see Idempotency. The game server must never create two mails for the same invoice_id.

Validate before sending: role_id belongs to account_id on server_id, and every item_id is known. Return 200 only after the mail is committed to the database.

Authorizations:
(ClientIdApiKey)
Request Body schema: application/json
required
invoice_id
required
string <= 64 characters

GAGA transaction id. Idempotency key.

account_id
required
string^[A-Z]{4}[0-9]{12}$

GAGA ID, canonical form.

server_id
required
string
role_id
required
string
product_id
required
string

GAGA package id the player bought. For audit only; deliver items, not product_id.

required
Array of objects (Item) [ 1 .. 10 ] items
mail_title
required
string <= 50 characters
mail_content
required
string <= 500 characters
source
required
string
Enum: "funtap" "webshop"

Sales channel, for the game's own reports.

created_at
required
integer

Payment time, Unix seconds.

Responses

Request samples

Content type
application/json
{
  • "invoice_id": "GW20261002A1B2C3D4",
  • "account_id": "VNGA284190375216",
  • "server_id": "12345",
  • "role_id": "2356423",
  • "product_id": "GCOIN_1000",
  • "items": [
    ],
  • "mail_title": "GAGA Top-up",
  • "mail_content": "Thank you for your purchase. 1,000 G Coin + 100 bonus.",
  • "source": "funtap",
  • "created_at": 1790000000
}

Response samples

Content type
application/json
Example
{
  • "code": 200,
  • "message": "OK",
  • "data": {
    }
}

Check delivery by invoice_id

Returns the mail created for an invoice_id. Equivalent of Funtap S2S 4. Payment inquiry.

GAGA calls this when POST /mails timed out or returned 5xx, and during daily reconciliation. 404 here means not delivered — GAGA will then re-send with the same invoice_id.

Authorizations:
(ClientIdApiKey)
path Parameters
invoice_id
required
string <= 64 characters
Example: GW20261002A1B2C3D4

Responses

Response samples

Content type
application/json
{
  • "code": 200,
  • "message": "OK",
  • "data": {
    }
}