Game8 Store – Developer Center
Home › Technology & API

Test Implementation Guide

📝 This is a reference translation. In case of any discrepancy, the Japanese version prevails.

This guide explains how to try outReview the API specification and prepare the required APIs (purchase eligibility check(purchase eligibility check) and POST /register(purchase registration) with a simple test implementation for integrating with Game8 Store.

Estimated time required:15 minutes

1. Implementing the Endpoints (Approx. 10 minutes)

1.1 Required Environment

  • Use Node.js (Express) or Python (FastAPI)
  • A server that can be deployed locally or to the cloud (AWS, GCP, Vercel, Render, etc.)

1.2 Implementation in Node.js (Express)

const express = require("express");
const cors = require("cors");
const crypto = require("crypto");

const app = express();
app.use(express.json());
app.use(cors());

const VALID_ACCESS_TOKEN = "your_access_token";
const SECRET_KEY = "your_secret_key";

// Authentication middleware
app.use((req, res, next) => {
  const authHeader = req.headers.authorization;
  if (!authHeader) {
    return res.status(401).json({ result_code: "PUB1001", message: "Missing authentication credentials" });
  }
  const [scheme, token] = authHeader.split(" ");
  if (scheme !== "Bearer" || token !== VALID_ACCESS_TOKEN) {
    return res.status(401).json({ result_code: "PUB1002", message: "Invalid access token" });
  }
  next();
});

// X-Signature Verification middleware
const verifySignature = (req, res, next) => {
  const signature = req.headers["x-signature"];
  if (!signature) {
    return res.status(400).json({ result_code: "PUB1004", message: "Missing signature" });
  }
  const requestData = req.method === "GET" ? req.query : req.body
  const payload = JSON.stringify(requestData);
  const computedSignature = crypto.createHmac("sha256", SECRET_KEY).update(payload).digest("base64");
  if (signature !== computedSignature) {
    return res.status(400).json({ result_code: "PUB1004", message: "Invalid signature" });
  }
  next();
};

// Purchase eligibility check (with item reservation support)
app.get("/check", verifySignature, (req, res) => {
    const { game, user, item, price, transaction_id } = req.query;
    if (!game || !user || !item || !price || !transaction_id || isNaN(price)) {
        return res.status(400).json({ result_code: "PUB2001", message: "Missing required parameters or invalid values" });
    }
    res.json({
        request_id: "abc123",
        timestamp: new Date().toISOString(),
        result_code: "PUB0000",
        message: "Purchase allowed",
        purchasable: "available",
        age_category: "under_18",
        account_limit: { total: 10000, remaining: 5000 },
        requested_price: Number(price),
        transaction_id: transaction_id
    });
});

// Purchase registration
app.post("/register", verifySignature, (req, res) => {
    try {
        const { game, user, item, transaction_id, item_name, price, quantity } = req.body;
        if (!game || !user || !item || !transaction_id || !item_name || !price || !quantity || isNaN(price) || isNaN(quantity)) {
            return res.status(400).json({ result_code: "PUB2001", message: "Missing required parameters or invalid values" });
        }
        res.json({
            request_id: "def456",
            timestamp: new Date().toISOString(),
            result_code: "PUB0000",
            message: "The purchase record has been registered.",
            item_granted: true,
            transaction_id: transaction_id
        });
    } catch (error) {
        res.status(500).json({ result_code: "PUB5000", message: "Internal server error" });
    }
});

app.listen(3000, () => console.log("Server running on port 3000"));

1.3 Implementation in Python (FastAPI)

from fastapi import FastAPI, Request, HTTPException, Header, Depends
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import hmac
import hashlib
import base64
import json
from datetime import datetime
from typing import Optional
from urllib.parse import urlencode

app = FastAPI()

# CORSMiddleware configuration
app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

SECRET_KEY = "your_secret_key"
VALID_ACCESS_TOKEN = "your_access_token"

# Request models
class RegisterRequest(BaseModel):
    game: str
    user: str
    item: str
    transaction_id: str
    item_name: str
    price: int
    quantity: int

# Authentication dependency function
async def verify_auth(authorization: Optional[str] = Header(None)):
    if not authorization:
        raise HTTPException(
            status_code=401, 
            detail={"result_code": "PUB1001", "message": "Missing authentication credentials"}
        )
    
    if authorization != f"Bearer {VALID_ACCESS_TOKEN}":
        raise HTTPException(
            status_code=401, 
            detail={"result_code": "PUB1002", "message": "Invalid access token"}
        )
    return True

# Signature verification dependency function (for GET requests)
async def verify_signature_get(request: Request, x_signature: Optional[str] = Header(None)):
    if not x_signature:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB1004", "message": "Missing signature"}
        )
    
    # Get the query parameters
    query_params = dict(request.query_params)
    payload = urlencode(query_params)
    
    # Calculate the signature
    computed_signature = base64.b64encode(
        hmac.new(SECRET_KEY.encode(), payload.encode(), hashlib.sha256).digest()
    ).decode()
    
    if x_signature != computed_signature:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB1004", "message": "Invalid signature"}
        )
    return True

# Signature verification dependency function (for POST requests)
async def verify_signature_post(request: Request, x_signature: Optional[str] = Header(None)):
    if not x_signature:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB1004", "message": "Missing signature"}
        )
    
    # Get the request body
    body_bytes = await request.body()
    if not body_bytes:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB2001", "message": "Missing required parameters or invalid values"}
        )
    
    # JSON parsing
    try:
        body_json = json.loads(body_bytes)
        payload = json.dumps(body_json)
    except json.JSONDecodeError:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB2001", "message": "Invalid JSON format"}
        )
    
    # Calculate the signature
    computed_signature = base64.b64encode(
        hmac.new(SECRET_KEY.encode(), payload.encode(), hashlib.sha256).digest()
    ).decode()
    
    if x_signature != computed_signature:
        raise HTTPException(
            status_code=400, 
            detail={"result_code": "PUB1004", "message": "Invalid signature"}
        )
    return True

@app.get("/check")
async def check(
    game: str, 
    user: str, 
    item: str, 
    price: int, 
    transaction_id: str,
    _auth: bool = Depends(verify_auth),
    _sig: bool = Depends(verify_signature_get)
):
    return {
        "request_id": "abc123",
        "timestamp": datetime.utcnow().isoformat(),
        "result_code": "PUB0000",
        "message": "Purchase allowed",
        "purchasable": "available",
        "age_category": "under_18",
        "account_limit": {"total": 10000, "remaining": 5000},
        "requested_price": price,
        "transaction_id": transaction_id
    }

@app.post("/register")
async def register(
    request: RegisterRequest,
    _auth: bool = Depends(verify_auth),
    _sig: bool = Depends(verify_signature_post)
):
    try:
        return {
            "request_id": "def456",
            "timestamp": datetime.utcnow().isoformat(),
            "result_code": "PUB0000",
            "message": "The purchase record has been registered.",
            "item_granted": True,
            "transaction_id": request.transaction_id
        }
    except Exception as e:
        raise HTTPException(
            status_code=500,
            detail={"result_code": "PUB5000", "message": "Internal server error"}
        )

if __name__ == "__main__":
    import uvicorn
    uvicorn.run(app, host="0.0.0.0", port=3000)

2. Testing with Postman (Approx. 5 minutes)

In the Authorization header, set Bearer your_access_token , set the calculated signature in X-Signature, and then try the following requests

* The samples on this page are minimal configurations for connectivity testing. For the complete list of request and response fields, please refer to theAPI Specification.

2.1 GET /check request example

GET http://localhost:3000/check
X-Signature: <SIGNED_DATA>

{
  "game": "game123",
  "user": "user456",
  "item": "item789",
  "transaction_id": "txn_123456",
  "price": 500
}

Example response:

{
  "request_id": "abc123",
  "timestamp": "2025-02-27T12:00:00Z",
  "result_code": "PUB0000",
  "message": "Purchase allowed",
  "purchasable": true,
  "transaction_id": "txn_123456"
}

2.2 POST /register request example

POST http://localhost:3000/register
Content-Type: application/json
X-Signature: <SIGNED_DATA>

{
  "game": "game123",
  "user": "user456",
  "item": "item789",
  "transaction_id": "txn_123456",
  "item_name": "100Gems",
  "price": 500,
  "quantity": 1
}

Example response:

{
  "request_id": "def456",
  "timestamp": "2025-02-27T12:00:00Z",
  "result_code": "PUB0000",
  "message": "The purchase record has been registered.",
  "item_granted": true,
  "transaction_id": "txn_123456"
}