Seamless Integration Code Examples

This page describes Seamless Integration Code Examples written by JavaScript(Node.js) and PHP.

These code examples encompass various types of callback requests and response data structures. Please review them thoroughly.

To handle our callback request, you need to:

  • Create a route (callback URL)

  • Parse the incoming request

  • Respond with the appropriate data

Please implement the callback processing code on your server side.

These code examples are for demonstration purposes only. Please do not use them in your production environment.

Please pay close attention to the response JSON structure. Many developers overlook this and end up encountering 'CALLBACK_ERROR'.

/******

VERSION : V200
Callback Handling
v200
Creating Basic Sample Source Written with Node.js (Express + MySQL)
!!! PLEASE DO NOT USE THIS EXAMPLE CODE FOR YOUR PRODUCTION, THIS IS JUST ONLY FOR YOUR REFERRENCE. !!!

/***

Example Tables
/
/*
CREATE TABLE bet_casino (
trans_id VARCHAR(64) NOT NULL,
user_id VARCHAR(20) NOT NULL,
game_id VARCHAR(100) NOT NULL DEFAULT '',
round_id VARCHAR(64) NOT NULL DEFAULT '',
sort ENUM('BET','WIN','CANCEL') NOT NULL,
money INT(11) NOT NULL,
request_datetime INT(11) NOT NULL DEFAULT '0',
PRIMARY KEY (trans_id),
INDEX game_id (game_id, round_id)
);

CREATE TABLE user_casino (
user_id VARCHAR(20) NOT NULL,
user_name VARCHAR(20) NOT NULL,
user_nickname VARCHAR(20) NOT NULL,
money INT(11) NOT NULL DEFAULT '0',
token VARCHAR(50) NOT NULL DEFAULT '',
status ENUM('Active','Drop') NOT NULL DEFAULT 'Active',
PRIMARY KEY (user_id),
INDEX token (token)
);

*/
const express = require('express');
const mysql = require('mysql2/promise'); // Using promise-based mysql2
const bodyParser = require('body-parser');

// Constants
const CALLBACK_TOKEN = 'eadd5a04-4720-4a10-ae60-b11cd01cc3aa';

// Create Express app
const app = express();
app.use(bodyParser.json());

// MySQL Database Connection
const db = mysql.createPool({
    host: '127.0.0.1',
    user: 'root',
    password: '',
    database: 'casino',
});

// Helper function to send JSON response and end connection
const sendResponse = (res, data) => {
    res.json(data);
};

// Middleware to validate Callback Token
app.use((req, res, next) => {
    const tokenData = req.headers['callback-token']?.trim();
    if (CALLBACK_TOKEN !== tokenData) {
        return sendResponse(res, { result: 100, status: 'ERROR' });
    }
    next();
});

// Main route to handle the request
app.post('/callback', async (req, res) => {
    const oData = req.body;
    const command = oData.command;
    const aCheckItem = oData.check.split(',');

    let userInfo = null;
    let betInfo = null;

    // Helper to process checklist items
    const processCheckItems = async () => {
        for (const check of aCheckItem) {
            switch (parseInt(check)) {
                case 21: // user confirmation
                    userInfo = await getUserInfo(oData.data.account);
                    if (!userInfo) return { result: check, status: 'ERROR' };
                    break;

                case 22: // Check if user is active
                    if (userInfo.status !== 'Active') return { result: check, status: 'ERROR' };
                    break;

                case 31: // Check user balance
                    const amount = parseInt(oData.data.amount);
                    if (userInfo.money < amount) {
                        return { result: check, status: 'ERROR', data: { balance: userInfo.money } };
                    }
                    break;

                case 41: // Check if trans_id exists
                    betInfo = await getBetInfo(oData.data.trans_id);
                    if (betInfo) {
                        return { result: check, status: 'ERROR', data: { balance: userInfo.money } };
                    }
                    break;

                case 42: // Check if trans_id exists (return bet info)
                    betInfo = await getBetInfo(oData.data.trans_id);
                    if (!betInfo) {
                        return { result: check, status: 'ERROR', data: { balance: userInfo.money } };
                    }
                    break;

                default:
                    break;
            }
        }
        return null;
    };

    // Handle different commands
    const handleCommand = async () => {
        let response = null;
        switch (command) {
            case 'authenticate':
                response = { result: 0, status: 'OK', data: { account: userInfo.user_id, balance: userInfo.money } };
                break;

            case 'balance':
                response = { result: 0, status: 'OK', data: { balance: userInfo.money } };
                break;

            case 'bet':
                response = await handleBet(oData);
                break;

            case 'win':
                response = await handleWin(oData);
                break;

            case 'cancel':
                response = await handleCancel(oData);
                break;

            case 'status':
                response = { result: 0, status: 'OK', data: { trans_id: oData.data.trans_id, trans_status: betInfo.sort === 'CANCEL' ? 'CANCELED' : 'OK' } };
                break;

            default:
                response = { result: 99, status: 'UNKNOWN_COMMAND' };
        }
        return response;
    };

    const checkError = await processCheckItems();
    if (checkError) return sendResponse(res, checkError);

    const result = await handleCommand();
    sendResponse(res, result);
});

// Helper functions
const getUserInfo = async (userId) => {
    const sql = 'SELECT * FROM user_casino WHERE user_id = ?';
    const [rows] = await db.query(sql, [userId]);
    return rows[0];
};

const getBetInfo = async (transId) => {
    const sql = 'SELECT * FROM bet_casino WHERE trans_id = ?';
    const [rows] = await db.query(sql, [transId]);
    return rows[0];
};

const handleBet = async (oData) => {
    const { trans_id, game_code, round_id, amount } = oData.data;
    const user_id = userInfo.user_id;
    const transTimestamp = Math.floor(Date.now() / 1000); // UNIX timestamp

    try {
        const betSql = 'INSERT INTO bet_casino (trans_id, user_id, game_id, round_id, sort, money, request_datetime) VALUES (?, ?, ?, ?, ?, ?, ?)';
        await db.query(betSql, [trans_id, user_id, game_code, round_id, 'BET', amount, transTimestamp]);

        const newBalance = userInfo.money - amount;
        const updateUserSql = 'UPDATE user_casino SET money = ? WHERE user_id = ?';
        await db.query(updateUserSql, [newBalance, user_id]);

        return { result: 0, status: 'OK', data: { balance: newBalance } };
    } catch (err) {
        return { result: 99, status: 'ERROR', data: { balance: userInfo.money } };
    }
};

const handleWin = async (oData) => {
    const { trans_id, game_code, round_id, amount } = oData.data;
    const user_id = userInfo.user_id;
    const transTimestamp = Math.floor(Date.now() / 1000); // UNIX timestamp

    try {
        const winSql = 'INSERT INTO bet_casino (trans_id, user_id, game_id, round_id, sort, money, request_datetime) VALUES (?, ?, ?, ?, ?, ?, ?)';
        await db.query(winSql, [trans_id, user_id, game_code, round_id, 'WIN', amount, transTimestamp]);

        const newBalance = userInfo.money + amount;
        const updateUserSql = 'UPDATE user_casino SET money = ? WHERE user_id = ?';
        await db.query(updateUserSql, [newBalance, user_id]);

        return { result: 0, status: 'OK', data: { balance: newBalance } };
    } catch (err) {
        return { result: 99, status: 'ERROR', data: { balance: userInfo.money } };
    }
};

const handleCancel = async (oData) => {
    const { trans_id } = oData.data;
    const user_id = userInfo.user_id;
    let user_money = userInfo.money;

    if (betInfo.sort !== 'CANCEL') {
        const isBet = betInfo.sort === 'BET';
        const moneyChange = isBet ? betInfo.money : -betInfo.money;

        try {
            const updateBetSql = 'UPDATE bet_casino SET sort = "CANCEL" WHERE trans_id = ?';
            await db.query(updateBetSql, [trans_id]);

            user_money += moneyChange;
            const updateUserSql = 'UPDATE user_casino SET money = ? WHERE user_id = ?';
            await db.query(updateUserSql, [user_money, user_id]);

            return { result: 0, status: 'OK', data: { balance: user_money } };
        } catch (err) {
            return { result: 99, status: 'ERROR', data: { balance: userInfo.money } };
        }
    } else {
        return { result: 0, status: 'OK', data: { balance: user_money } };
    }
};

Last updated