Introduction
Document Rules
In this document, we used some rules to emphasize specific words and vocabularies.
And pointed to some particular information.
Annotations and Warnings
We emphasized the information might be ignored by 3 visual ways.
Notice
- Please contact Dragoon Soft to ask API address, API token, and Agent Account.
- Please provide IP that connect to us before you get started.(Fill them in MIF)
- The integration transmit formation is Json. And is encoded by UTF-8.
Authentication
API Encryption
How to encrypt API data
Encryption/Decryption Example:
using System;
using System.Net;
using System.Text;
using System.IO;
using AesEverywhere;
namespace Transfer
{
class Members
{
public static string apiUrl = "<url>"; // This is a example url, please fill in the right url from the MIF
public static string aesKey = "HJwMgszptPW8YybZGFluBTm569crSxhd"; // This is a example aes_key, please fill in the right aes_key from the MIF
public static string signKey = "AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ"; // This is a example sign_key, please fill in the right sign_key from the MIF
public static string channel = "01234567"; // This is a example Channel, please fill in the right Channel from the MIF
public static string agent = "exampleAg001"; // This is a example Agent, please fill in the right Agent from the MIF
public static string account = "exampleAct001"; // This is a example Account, please fill in the right Account from the MIF
public static void CreateMember()
{
String d = "{\"agent\":\"" + agent + "\",\"account\":\"" + account + "\"}";
String req = Encryption(d);
String url = "https://" + apiUrl + "/v1/member/create";
Post(req, url);
}
public static string Encryption(string d)
{
String data = AESKeyEncryption(d);
String sign = SignKeyEncryption(data);
return "{\"channel\":\"" + channel + "\",\"data\":\"" + data + "\",\"sign\":\"" + sign + "\"}";
}
public static string AESKeyEncryption(string d)
{
AES256 aes256 = new AES256();
return aes256.Encrypt(d, aesKey);
}
public static string SignKeyEncryption(string d)
{
using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create())
{
byte[] inputBytes = System.Text.Encoding.ASCII.GetBytes(d + signKey);
byte[] hashBytes = md5.ComputeHash(inputBytes);
// Convert the byte array to hexadecimal string
StringBuilder sb = new StringBuilder();
for (int i = 0; i < hashBytes.Length; i++)
{
sb.Append(hashBytes[i].ToString("x2"));
}
return sb.ToString();
}
}
public static void Post(string d, string url)
{
byte[] b = Encoding.UTF8.GetBytes(d);
var r = (HttpWebRequest)WebRequest.Create(url); // This is a example url, please fill in the right url from the MIF
r.Method = "POST";
r.ContentType = "application/json";
r.ContentLength = b.Length;
using (var stream = r.GetRequestStream())
{
stream.Write(b, 0, b.Length);
}
var resp = (HttpWebResponse)r.GetResponse();
var res = new StreamReader(resp.GetResponseStream()).ReadToEnd();
Console.WriteLine(res);
}
public static void Main(string[] args)
{
CreateMember();
}
}
}
// aes256.cs
// This file is part of AES-everywhere project (https://github.com/mervick/aes-everywhere)
//
// This is an implementation of the AES algorithm, specifically CBC mode,
// with 256 bits key length and PKCS7 padding.
//
// Copyright Andrey Izman (c) 2018-2019 <izmanw@gmail.com>
// Licensed under the MIT license
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
//
// <summary>AES256 class implements the OpenSSL compatible cipher AES/256/CBC/PKCS7</summary>
// <copyright file="aes256.cs" company="Andrey Izman">
// Copyright (c) 2018 All Rights Reserved
// </copyright>
// <author>Andrey Izman</author>
// <email>izmanw@gmail.com</email>
// <link>https://github.com/mervick/aes-everywhere</link>
// <license>MIT</license>
using System;
using System.Security.Cryptography;
using System.IO;
using System.Text;
namespace AesEverywhere
{
/// <summary>
/// AES256 class implements the OpenSSL compatible cipher AES/256/CBC/PKCS7
/// </summary>
public class AES256
{
public const int BlockSize = 16;
public const int KeyLen = 32;
public const int IvLen = 16;
private byte[] key;
private byte[] iv;
/// <summary>
/// Encrypt input text with the password using random salt.
/// Returns base64 decoded encrypted string.
/// </summary>
/// <param name="text">Input text to encrypt</param>
/// <param name="passphrase">Passphrase</param>
public string Encrypt(string text, string passphrase)
{
return Encrypt(Encoding.UTF8.GetBytes(text), passphrase);
}
/// <summary>
/// Encrypt input bytes with the password using random salt.
/// Returns base64 decoded encrypted string.
/// </summary>
/// <param name="data">Input data (in bytes) to encrypt</param>
/// <param name="passphrase">Passphrase</param>
public string Encrypt(byte[] data, string passphrase)
{
using (var random = new RNGCryptoServiceProvider())
{
byte[] salt = new byte[8];
random.GetBytes(salt);
DeriveKeyAndIv(passphrase, salt);
byte[] encrypted;
using (var aes = new RijndaelManaged())
{
aes.BlockSize = BlockSize * 8;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = key;
aes.IV = iv;
ICryptoTransform encryptor = aes.CreateEncryptor(aes.Key, aes.IV);
using (var msEncrypt = new MemoryStream())
{
using (var csEncrypt = new CryptoStream(msEncrypt, encryptor, CryptoStreamMode.Write))
{
csEncrypt.Write(data, 0, data.Length);
csEncrypt.FlushFinalBlock();
encrypted = msEncrypt.ToArray();
}
}
}
return System.Convert.ToBase64String(Concat(Concat("Salted__", salt), encrypted));
}
}
/// <summary>
/// Derypt encrypted text with the password using random salt.
/// Returns the decrypted string.
/// </summary>
/// <param name="encrypted">Encrypted text to decrypt</param>
/// <param name="passphrase">Passphrase</param>
public string Decrypt(string encrypted, string passphrase)
{
return Encoding.UTF8.GetString(DecryptToBytes(encrypted, passphrase));
}
/// <summary>
/// Derypt encrypted data with the password using random salt.
/// Returns the decrypted bytes.
/// </summary>
/// <param name="encrypted">Encrypted data to decrypt</param>
/// <param name="passphrase">Passphrase</param>
public byte[] DecryptToBytes(string encrypted, string passphrase)
{
byte[] ct = System.Convert.FromBase64String(encrypted);
if (ct == null || ct.Length <= 0) {
return new byte[0];
}
byte[] salted = new byte[8];
Array.Copy(ct, 0, salted, 0, 8);
if (Encoding.UTF8.GetString(salted) != "Salted__") {
return new byte[0];
}
byte[] salt = new byte[8];
Array.Copy(ct, 8, salt, 0, 8);
byte[] cipherText = new byte[ct.Length - 16];
Array.Copy(ct, 16, cipherText, 0, ct.Length - 16);
DeriveKeyAndIv(passphrase, salt);
byte[] decrypted;
using (var aes = new RijndaelManaged())
{
aes.BlockSize = BlockSize * 8;
aes.Mode = CipherMode.CBC;
aes.Padding = PaddingMode.PKCS7;
aes.Key = key;
aes.IV = iv;
ICryptoTransform decryptor = aes.CreateDecryptor(aes.Key, aes.IV);
using (var msDecrypt = new MemoryStream())
{
using (var csDecrypt = new CryptoStream(msDecrypt, decryptor, CryptoStreamMode.Write))
{
csDecrypt.Write(cipherText, 0, cipherText.Length);
csDecrypt.FlushFinalBlock();
decrypted = msDecrypt.ToArray();
}
}
}
return decrypted;
}
/// <summary>
/// Derive key and iv.
/// </summary>
/// <param name="passphrase">Passphrase</param>
/// <param name="salt">Salt</param>
protected void DeriveKeyAndIv(string passphrase, byte[] salt)
{
MD5 md5 = MD5.Create();
key = new byte[KeyLen];
iv = new byte[IvLen];
byte[] dx = new byte[] {};
byte[] salted = new byte[] {};
byte[] pass = Encoding.UTF8.GetBytes(passphrase);
for (int i = 0; i < (KeyLen + IvLen / 16); i++) {
dx = Concat(Concat(dx, pass), salt);
dx = md5.ComputeHash(dx);
salted = Concat(salted, dx);
}
Array.Copy(salted, 0, key, 0, KeyLen);
Array.Copy(salted, KeyLen, iv, 0, IvLen);
}
private static byte[] Concat(byte[] a, byte[] b)
{
byte[] output = new byte[a.Length + b.Length];
for (int i = 0; i < a.Length; i++)
output[i] = a[i];
for (int j = 0; j < b.Length; j++)
output[a.Length+j] = b[j];
return output;
}
private static byte[] Concat(string a, byte[] b)
{
return Concat(Encoding.UTF8.GetBytes(a), b);
}
}
}
package main
import (
"bytes"
"crypto/md5"
"encoding/hex"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"github.com/mervick/aes-everywhere/go/aes256"
)
var (
apiUrl = "<url>" // This is a example url, please fill in the right url from the MIF
aesKey = "HJwMgszptPW8YybZGFluBTm569crSxhd" // This is a example aes_key, please fill in the right aes_key from the MIF
signKey = "AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ" // This is a example sign_key, please fill in the right sign_key from the MIF
channel = "01234567" // This is a example Channel, please fill in the right Channel from the MIF
agent = "exampleAg001" // This is a example Agent, please fill in the right Agent from the MIF
account = "exampleAct001" // This is a example Account, please fill in the right Account from the MIF
accountData = map[string]interface{}{
"agent": agent,
"account": account,
}
)
func AESKeyEncryption(d string) string {
return aes256.Encrypt(string(d), aesKey)
}
func SignKeyEncryption(d string) string {
h := md5.New()
h.Write([]byte(d))
cipherStr := h.Sum(nil)
return hex.EncodeToString(cipherStr)
}
func CreateMember(a string, s string) {
data := map[string]interface{}{
"channel": channel,
"data": a,
"sign": s,
}
req, err := json.Marshal(&data)
if err != nil {
log.Fatalf("json.Marshal err: %s. data: %+v", err.Error(), data)
return
}
Post(fmt.Sprintf("https://%s/v1/member/create", apiUrl), req)
}
func Post(url string, req []byte) {
r, err := http.NewRequest("POST", url, bytes.NewBuffer(req))
if err != nil {
log.Fatalf("http.NewRequest err: %s. url: %s, req: %+v", err.Error(), url, string(req))
return
}
r.Header.Set("Content-Type", "application/json")
c := &http.Client{}
resp, err := c.Do(r)
if err != nil {
log.Fatalf("client.Do err: %s. url: %s, req: %+v", err.Error(), url, string(req))
return
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response StatusCode:", resp.StatusCode)
res, _ := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(res))
}
func main() {
d, err := json.Marshal(accountData)
if err != nil {
log.Fatalf("json.Marshal err: %s. accountData: %+v", err.Error(), accountData)
return
}
a := AESKeyEncryption(string(d))
s := SignKeyEncryption(fmt.Sprintf("%s%s", a, signKey))
CreateMember(a, s)
}
package com.transfer;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import net.sf.json.JSONObject;
import com.github.mervick.aes_everywhere.Aes256;
public class Transfer {
public static final String apiUrl = "<url>"; // This is a example url, please fill in the right url from the
// MIF
public static final String aesKey = "HJwMgszptPW8YybZGFluBTm569crSxhd"; // This is a example aes_key, please fill in
// the right aes_key from the MIF
public static final String signKey = "AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ"; // This is a example sign_key, please fill
// in the right sign_key from the
// MIF
public static final String channel = "01234567"; // This is a example Channel, please fill in the right Channel from
// the MIF
public static final String agent = "exampleAg001"; // This is a example Agent, please fill in the right Agent from
// the MIF
public static final String account = "exampleAct001"; // This is a example Account, please fill in the right Account
// from
// the MIF
public static final JSONObject actData = new JSONObject();
public static String AESKeyEncryption(String d) {
try {
String a = Aes256.encrypt(d, aesKey);
return a;
} catch (Exception e) {
System.out.println(e);
}
return "";
}
public static String SignKeyEncryption(String d) {
try {
java.security.MessageDigest h = java.security.MessageDigest.getInstance("MD5");
byte[] cipherStr = h.digest(d.getBytes());
StringBuffer sb = new StringBuffer();
for (int i = 0; i < cipherStr.length; ++i) {
sb.append(Integer.toHexString((cipherStr[i] & 0xFF) | 0x100).substring(1, 3));
}
return sb.toString();
} catch (Exception e) {
System.out.println(e);
}
return "";
}
public static void CreateMember(String data, String sign) {
try {
JSONObject req = new JSONObject();
req.put("channel", channel);
req.put("data", data);
req.put("sign", sign);
URL url = new URL("https://" + apiUrl + "/v1/member/create");
Post(url, req.toString().getBytes("UTF-8"));
} catch (Exception e) {
System.out.println(e);
}
}
public static void Post(URL url, byte[] req) {
try {
HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setDoOutput(true);
c.setDoInput(true);
c.setRequestMethod("POST");
c.setUseCaches(false);
c.setInstanceFollowRedirects(true);
c.setRequestProperty("Content-Type", "application/json; charset=UTF-8");
c.connect();
DataOutputStream o = new DataOutputStream(c.getOutputStream());
o.write(req);
o.flush();
o.close();
BufferedReader r = new BufferedReader(new InputStreamReader(c.getInputStream()));
String lines;
StringBuffer sb = new StringBuffer("");
while ((lines = r.readLine()) != null) {
lines = new String(lines.getBytes(), "utf-8");
sb.append(lines);
}
System.out.println(sb);
// 斷開連線
r.close();
c.disconnect();
} catch (Exception e) {
System.out.println(e);
}
}
public static void main(String[] args) {
try {
actData.put("agent", agent);
actData.put("account", account);
String a = AESKeyEncryption(actData.toString());
String s = SignKeyEncryption(a + signKey);
CreateMember(a, s);
} catch (Exception e) {
System.out.println(e);
}
}
}
<?php
// php example
class Authentication {
protected $apiUrl = '<url>'; // This is a example url, please fill in the right url from the MIF
protected $aesKey = 'HJwMgszptPW8YybZGFluBTm569crSxhd'; // This is a example aes_key, please fill in the right aes_key from the MIF
protected $signKey = 'AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ'; // This is a example sign_key, please fill in the right sign_key from the MIF
protected $channel = '01234567'; // This is a example Channel, please fill in the right Channel from the MIF
protected $accountData = [
"agent" => 'exampleAg001', // This is a example Agent, please fill in the right Agent from the MIF
"account" => 'exampleAct001', // This is a example Account, please fill in the right Account from the MIF
];
public function AESKeyEncryption($d, $a)
{
$salt = openssl_random_pseudo_bytes(8);
$salted = $dx = '';
while (strlen($salted) < 48) {
$dx = md5($dx . $a . $salt, true);
$salted .= $dx;
}
$key = substr($salted, 0, 32);
$iv = substr($salted, 32, 16);
return base64_encode('Salted__' . $salt . openssl_encrypt($d . '', 'aes-256-cbc', $key, OPENSSL_RAW_DATA, $iv));
}
public function SignKeyEncryption($a)
{
return md5($a.$this->signKey, false);
}
public function CreateMember($a, $s)
{
$data = ["channel" => $this->channel, "data" => $a, "sign" => $s];
$req = json_encode($data);
$this->Curl($req);
}
public function Curl($req)
{
$curl = curl_init('https://'.$this->apiUrl.'/v1/member/create');
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, ['Content-type: application/json']);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $req);
$ret = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 200 ) {
die("Error: call to URL $curl failed with status $status, response $ret, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
$res = json_decode($ret, true);
print_r($res);
}
public function Start()
{
$d = json_encode($this->accountData);
$a = $this->AESKeyEncryption($d, $this->aesKey);
$s = $this->SignKeyEncryption($a);
$this->CreateMember($a, $s);
}
}
$auth = new Authentication();
$auth->Start();
?>
import json
import hashlib
import requests
from AesEverywhere import aes256 # pip install aes-everywhere
apiUrl = '<url>' # This is a example url, please fill in the right url from the MIF
aesKey = 'HJwMgszptPW8YybZGFluBTm569crSxhd' # This is a example aes_key, please fill in the right aes_key from the MIF
signKey = 'AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ' # This is a example sign_key, please fill in the right sign_key from the MIF
channel = '01234567' # This is a example Channel, please fill in the right Channel from the MIF
accountData = {
'agent': 'exampleAg001', # This is a example Agent, please fill in the right Agent from the MIF
'account': 'exampleAct001' # This is a example Account, please fill in the right Account from the MIF
}
def AESKeyEncryption(d):
return aes256.encrypt(d, aesKey)
def SignKeyEncryption(d):
m = hashlib.md5()
m.update(d.encode())
return m.hexdigest()
def CreateMember(a, s):
data = {
'channel': channel,
'data': a,
'sign': s
}
resp = requests.request("POST", 'https://' + apiUrl + '/v1/member/create', headers={'content-type': "application/json"}, json=data)
print(resp.text)
def Start():
a = AESKeyEncryption(json.dumps(accountData))
s = SignKeyEncryption(a.decode() + signKey)
CreateMember(a.decode('utf-8'), s)
Start()
// nodejs example
var AES256 = require("aes-everywhere");
var crypto = require("crypto");
const request = require("request").defaults({});
var apiUrl = "<url>";
var aesKey = "HJwMgszptPW8YybZGFluBTm569crSxhd"; // This is a example aes_key, please fill in the right aes_key from the MIF
var signKey = "AbKmLhGTkHpoPzj6fWFS4e5BtI3xuvEJ"; // This is a example sign_key, please fill in the right sign_key from the MIF
var channel = "01234567"; // This is a example Channel, please fill in the right Channel from the MIF
var accountData = {
agent: "exampleAg001", // This is a example Agent, please fill in the right Agent from the MIF
account: "exampleAct001", // This is a example Account, please fill your member account
};
function AESKeyEncryption(d) {
return AES256.encrypt(d, aesKey);
}
function SignKeyEncryption(d) {
return crypto.createHash("md5").update(d).digest("hex");
}
function CreateMember(a, s) {
return new Promise((done) => {
var options = {
url: "https://" + apiUrl + "/v1/member/create",
method: "Post",
json: {
channel: channel,
data: a,
sign: s,
},
};
request(options, (err, res, body) => {
console.log("err: ", err);
console.log("body: ", body);
});
});
}
function Start() {
a = AESKeyEncryption(JSON.stringify(accountData));
s = SignKeyEncryption(a + signKey);
CreateMember(a, s);
}
Start();
Encrypt Token Info
DS will provide merchant the channel code, AES key, and MD5 sign key.
| Key | Description |
|---|---|
| channel | channel code |
| AES_key | AES encryption |
| sign_key | MD5 sign |
Example:
POST /v1/member/create HTTP/1.1
Content-Type: application/json
{
"channel": "7878778",
"data": "U2FsdGVkX18agQleI7fP+eJ1l2WmCNZMRajMNRrlkydQRjbHm0LlIBLC1oxdLPWtJgXqcRyg/gEgKDJgpM7sEg==",
"sign": "75ad8c8d3fc993885f7f8f9470e70227"
}
Token Encryption Agreement
Cipher: AES/256/CBC/PKCS5Padding
How to Encrypt and the Process
- Use
AES_keyas a key to doAESencryption and Base 64 encoding. Please send the result as thedatavalue of requesting parameter. - Splice
datatosign_key, and sign with MD5 as thesignvalue of requesting parameter. - To send the channel code which provided by DS as the
channelvalue of requesting parameter. - Submit POST.
Request Defined Construction
| Parameter | Type | Description |
|---|---|---|
| channel | String | channel code |
| sign | String | parameter sign |
| data | String | encrypted requesting parameter |
- golang-api-encryption-example
- csharp-api-encryption-example
- java-api-encryption-example
- php-api-encryption-example
- python-api-encryption-example
- nodejs-api-encryption-example
Members
Register
To register a new member by API
HTTP Request
POST https://<url>/v1/member/create
Example:
{
"agent": "DEMO00001",
"account": "Username002",
"password": "2788b26f9845bf9276b0aa45de7"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| password | String | No | member password |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
}
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
Login in Game
To get the launch URL for members
HTTP Request
POST https://<url>/v1/member/login_game
Example:
{
"game_id": "1001",
"lang": "zh_cn",
"is_demo": true
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| game_id | String | Yes | game id |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| lang | String | Yes | please check language supported |
| oper | String | No | optional parameters |
| backurl | String | No | URL for back button to direct |
| is_demo | Boolean | No | enable demo or not |
| btn | String | No | hide buttons or not. please check the sheet below |
| extra | String | No | extra parameter, ex:1,2,3 please check following sheet |
| max_bet | Number | No | maximum bet level |
| min_bet | Number | No | minumum bet level |
| level | String | No | level of hall (please check info below) |
btn parameters sheet
| Exit Button | Record Button | Parameter |
|---|---|---|
| hide | show | 0,1 |
| show | show | 1,1 |
| show | hide | 1,0 |
| hide | hide | 0,0 |
default to show both buttons
extra parameters sheet
| function | group | Parameter | Description |
|---|---|---|---|
| web | A | 1 | web |
| web app | A | 2 | boot with app webview |
| native app | A | 3 | native app |
| locking straight | B | 11 | to lock screen in straight mode |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
},
"url": "https://game_server_url/h5/1001/?token=d01e14944dcd4a0e9e207f4438bb37da&lang=zh_cn&oper=ds&backurl=https://backurl.com"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| url | String | url for member to use |
UNDER MAINTENANCE:
{
"result": {
"code": 1,
"msg": "UNDER MAINTENANCE"
},
"static": "",
"dynamic": "",
"token": "",
"url": "https://www.dragoonsoft.com/maintenace.html"
}
Logout
To logout member by API.
HTTP Request
POST https://<url>/v1/member/logout
Example:
{
"agent": "AG000001",
"account": "Username002"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
}
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
Inquire Online Status
Member online information
HTTP Request
POST https://<url>/v1/member/login_info
Example:
{
"agent": "AG000001",
"account": "Username002"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"login_info": {
"online": 2
}
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| online | Number | 1: online 2: offline |
Online List
The list of online members.
HTTP Request
POST https://<url>/v1/member/online_list
Example:
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"list": [
{
"agent": "AG000001",
"account": "Username002",
"game_id": "1001",
"login_time": "2019-05-08T12:40:52.036394384Z"
},
{
"agent": "AG000001",
"account": "Username001",
"game_id": "2001",
"login_time": "2019-05-08T12:28:25.086438394Z"
},
{
"agent": "AG000002",
"account": "Username055",
"game_id": "3011",
"login_time": "2019-05-08T12:41:42.026213394Z"
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| list | OnlineMember[] | online list |
OnlineMember Structure Definition
| Parameter | Type | Description |
|---|---|---|
| agent | String | agent account |
| account | String | member account |
| game_id | String | game id |
| login_time | String | login time ex: 2019-05-08T12:40:52.036394384Z |
Online List with Balance
The list of online members with balance information.
HTTP Request
POST https://<url>/v1/member/online_balance_list
Example:
{
"agent": "AG000001"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | yes | agent account |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"list": [
{
"agent": "AG000001",
"account": "Username002",
"game_id": "1001",
"login_time": "2019-05-08T12:40:52.036394384Z",
"balance": 99999.99
},
{
"agent": "AG000001",
"account": "Username001",
"game_id": "2001",
"login_time": "2019-05-08T12:28:25.086438394Z",
"balance": 2.22
},
{
"agent": "AG000002",
"account": "Username055",
"game_id": "3011",
"login_time": "2019-05-08T12:41:42.026213394Z",
"balance": 1
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| list | OnlineMemberBalance[] | online member balance list |
OnlineMemberBalance Structure Definition
| Parameter | Type | Description |
|---|---|---|
| agent | String | agent account |
| account | String | member account |
| game_id | String | game id |
| login_time | String | login time ex: 2019-05-08T12:40:52.036394384Z |
| balance | Number | balance |
Transfer
Transfer
The operation side should proivde a non-repetitive "outer transfer number" for tansferring into game wallet.
HTTP Request
POST https://<url>/v1/trans/transfer
Example:
{
"serial": "1536140284868",
"agent": "AG000001",
"account": "Username002",
"amount": "10000",
"oper_type": 1
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| serial | String | Yes | outer transfer number |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| amount | String | Yes | transaction amount PS: support to 2nd decimal place |
| oper_type | Number | Yes | transaction type( deposit : 1 , withdrawl : 0) |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success",
"timestamp": "2018-11-12T03:03:53.174604283Z"
},
"trans_id": "109668",
"serial": "1536133443167",
"balance": "582427.70"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| timestamp | String | time |
| trans_id | String | inner transaction number |
| serial | String | outer transaction number |
| balance | String | balance |
Inquire Status
For the 3rd user to inquire the transfer status by providing a serial number.
HTTP Request
POST https://<url>/v1/trans/verify
Example:
{
"agent": "develop01c02",
"account": "user0002",
"serial": "1531839120967"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| serial | String | Yes | outer transaction number |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success",
"timestamp": "2018-11-12T03:03:53.174604283Z"
},
"serial": "1531839120967",
"amount": "10.00",
"trans_id": "abcd1234"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| timestamp | String | time |
| serial | String | outer transaction number |
| trans_id | String | inner transaction number |
| amount | String | transaction amount |
Inquire Member Balance
To inquire the balance of members.
HTTP Request
POST https://<url>/v1/trans/check_balance
Example:
{
"agent": "develop01c02",
"account": "Username002"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success",
"timestamp": "2018-11-12T03:03:53.174604283Z"
},
"balance": "449862.90"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| timestamp | String | time |
| balance | String | member balance |
Bet Record
Record Structure Definition
| Parameter | Type | Description |
|---|---|---|
| id | String | bet id |
| bet_at | String | bet time |
| finish_at | String | result time |
| agent | String | agent account |
| member | String | member account |
| game_id | String | game id |
| game_serial | String | game serial |
| game_type | Number | game_type |
| round_id | String | round ID |
| bet_amount | Number | bet amount |
| payout_amount | Number | win score(excluded fee) |
| valid_amount | Number | valid amount |
| status | Number | bet status |
| fee_amount | Number | fee amount |
| jp_amount | Number | jackpot amount |
| event_id | String | event id |
| event_amount | Number | event amount |
| feature_buy | String | Feature Buy Type:Bet Level ex: FG1:2 |
Feature Buy Type
| Parameter | Type | Descryption |
|---|---|---|
| FG1 | String | Free Game |
| BG1 | String | Bonus Game |
Record Status
| Code | Descryption |
|---|---|
| 1 | Normal |
| 2 | Refund |
| 3 | Bet Refused |
| 4 | Bet Record Voided |
| 5 | Cancelled |
Time Structure Definition
| Parameter | Type | Description |
|---|---|---|
| start_time | String | start date ex: 2018-10-19T08:54:14+01:00 |
| end_time | String | end date ex: 2018-10-20T11:47:08+01:00 |
Inquire
To inquire bet records of members below agent in a time range.
HTTP Request
POST https://<url>/v1/record/get_bet_records
Example:
{
"finish_time": {
"start_time": "2018-10-19T08:54:14+01:00",
"end_time": "2018-10-19T08:57:08+01:00"
},
"index": 0,
"limit": 10
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| finish_time | Time | No | inquire transaction by result time |
| index | Number | No | start page default: 0 |
| limit | Number | No | inquire limit default: 1000 maximum: 5000 |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success",
"timestamp": "2018-11-12T04:03:53.174604283Z"
},
"total": "8870",
"rows": [
{
"id": "1",
"bet_at": "2018-10-18T05:47:51Z",
"finish_at": "2018-10-18T05:47:51Z",
"agent": "AG0000001",
"member": "MB03",
"game_id": "1001",
"game_serial": "324823745",
"game_type": 1,
"round_id": "1",
"bet_amount": "1200",
"payout_amount": "0",
"valid_amount": "1200",
"status": 1,
"fee_amount": "10",
"jp_amount": "10",
"event_id": "",
"event_amount": 0,
"feature_buy": ""
},
{
"id": "2",
"bet_at": "2018-10-18T05:47:51Z",
"finish_at": "2018-10-18T05:47:51Z",
"agent": "AG0000001",
"member": "MB03",
"game_id": "1001",
"game_serial": "38427123",
"game_type": 1,
"round_id": "1",
"bet_amount": "3600",
"payout_amount": "0",
"valid_amount": "3600",
"status": 1,
"fee_amount": "10",
"jp_amount": "10",
"event_id": "",
"event_amount": 0,
"feature_buy": "FG1:2"
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| timestamp | String | time |
| total | String | total number |
| rows | Record[] | bet record rows |
game_type
| Code | Descryption |
|---|---|
| 1 | FISHING |
| 3 | SLOT |
| 4 | ARCADE |
| 99 | SYSTEM |
Get Details URL
To inquire the URL for bet details
HTTP Request
POST https://<url>/v1/record/get_bet_detail_page
Example:
{
"game_id": "2001",
"game_serial": "23134242",
"lang": "zh_cn"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| game_id | String | Yes | game id |
| game_serial | String | Yes | serial for games |
| lang | String | Yes | zh_cn and en_us supported |
| id | String | No | bet id |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
},
"url": "https://<record.page>/bet_detail/?token=3fd0e97e-198b-4d34-9ab0-cd3f82f79ba3&lang=zh_cn"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| url | String | bet record detail url |
Get History URL
To inquire the URL for bet history.
HTTP Request
POST https://<url>/v1/member/bet_history
Example:
{
"agent": "AG0000001",
"account": "MB03",
"game_id": "2001",
"lang": "zh_cn"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| game_id | String | Yes | game id |
| lang | String | Yes | zh_cn and en_us supported |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
},
"url": "https://<record.page>/auth/eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ0IjoiODc3MjZjOTg3M2NlNGRmNWI4YTM4MTdiZTc2YjU5NTQifQ.qzLt51idNxxsZV4nXfO0wui-moVDeRdolhlNNdZp7go?g=1&gid=1001&lang=en_us"
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| url | String | bet record detail url |
Win/Lose Statistics
To inquiry the statistics of win/lose for members.
HTTP Request
POST https://<url>/v1/record/get_member_bet_records_by_hour
Example:
{
"start_time": "2018-10-19T13:00:00+01:00",
"end_time": "2018-10-19T13:59:59+01:00",
"index": 0,
"limit": 10
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| start_time | String | Yes | start time |
| end_time | String | Yes | end time |
| index | Number | No | start page |
| limit | Number | No | inquire limit |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "success"
},
"rows": [
{
"statistics_date": "2018-10-19T13:00:00+01:00",
"bet_count": 0,
"bet_amount": 0,
"real_bet_amount": 0,
"payout_amount": 0,
"valid_amount": 0,
"fee_amount": 0,
"jp_amount": 0,
"win_loss_amount": 0
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| rows | WinLoss[] | win lose rows |
WinLoss Structure Definition
| Parameter | Type | Description |
|---|---|---|
| statistics_date | String | statistics date |
| bet_count | Number | bet count |
| bet_amount | Number | bet amount |
| real_bet_amount | Number | real bet amount |
| payout_amount | Number | payout amount |
| valid_amount | Number | valid amount |
| fee_amount | Number | fee amount |
| jp_amount | Number | jackpot amount |
| win_loss_amount | Number | win loss amount |
Summary by Agent
To summarize bet records in a period by agent.
HTTP Request
POST https://<url>/v1/record/get_agent_summary_bet_records
Example:
{
"finish_time": {
"start_time": "2018-10-19T08:54:14+01:00",
"end_time": "2018-10-19T08:57:08+01:00"
}
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| finish_time | Time | Yes | inquire transaction by result time |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"rows": [
{
"agent": "cstest00",
"bet_count": "246",
"bet_amount": 9541.8,
"payout_amount": 9472.12,
"valid_amount": 9541.8,
"fee_amount": 0,
"jp_amount": 0
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| rows | SummaryByAgent[] | summary by agent info |
SummaryByAgent Structure Definition
| Parameter | Type | Description |
|---|---|---|
| agent | String | agent account |
| bet_count | String | bet count |
| bet_amount | Number | bet amount |
| payout_amount | Number | win score(excluded fee) |
| valid_amount | Number | valid amount |
| fee_amount | Number | fee amount |
| jp_amount | Number | jackpot amount |
Game Settings
Status
To inquiry the status of game
HTTP Request
POST https://<url>/v1/config/get_game_info_state_list
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"game_info_state_list": [
{
"id": "1001",
"type": "1",
"active": true,
"names": {
"en_us": "Ocean Lord",
"th_th": "จ้าวมหาสมุทร",
"vi_vn": "Chúa tể đại dương",
"zh_cn": "海霸王"
},
"latest": false,
"hot": true,
"weight": "3002"
},
{
"id": "1002",
"type": "1",
"active": true,
"names": {
"en_us": "Let's Shoot",
"th_th": "มายิงกัน",
"vi_vn": "Hãy Bắn",
"zh_cn": "吃我一炮"
},
"latest": false,
"hot": true,
"weight": "3003"
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| game_info_state_list | GameInfoStateList[] | game info |
GameInfoStateList Structure Definition
| Parameter | Type | Description |
|---|---|---|
| id | String | game id |
| type | String | game type |
| active | Boolean | actived or not |
| names | Map |
languages |
| latest | Boolean | latest |
| hot | Boolean | hot |
| weight | String | weight |
Return Code
| Code | Description |
|---|---|
| 0 | unknown error |
| 1 | succeeded |
| 2 | duplicated |
| 3 | required field |
| 4 | login failed |
| 5 | API access failed |
| 6 | information not found |
| 7 | request time out |
| 8 | verification code invalid |
| 9 | user blocked |
| 10 | player cannot be found |
| 11 | agent cannot be found |
| 12 | content type error |
| 13 | game not found |
| 16 | request limit reached |
| 1000 | signature failed |
| 1001 | amount error |
| 1002 | transaction number duplicated |
| 1003 | verification failed |
| 1004 | data base access failed |
| 1005 | wallet not found |
| 1006 | transaction not found |
| 1007 | processing failed |
| 1008 | transaction amount cannot be negative number |
| 1009 | agent amount not found |
| 1010 | agent amount insufficient |
| 1011 | agent withdrawal refused |
| 1012 | time is out of range |
| 1013 | exceed the second decimal place |
| 1028 | game hasn't been settled |
Format
API Format
| Parameter Key | Type | Format |
|---|---|---|
| account | String | 0~9 , a~z ,A~Z ,- ,_ , length:4 to 36 |
| token | String | 0~9 , a~z ,A~Z ,- ,_ , length:4 to 36 |
| serial | String | 0~9 , a~z ,A~Z ,- ,_ , length:8 to 36 |
Time Format
- Format:
RFC3339 - Example:
2018-10-18T05:47:51+05:00
Supported
Languages
| Parameter | Description |
|---|---|
| zh_cn | Simplified Chinese |
| zh_hk | Traditional Chinese |
| en_us | English |
| vi_vn | Vietnamese |
| th_th | Thai |
| id_id | Indonesian language |
| ja_jp | Japanese |
| ko_kr | Korean |
| pt_pt | Portuguese |
| es_es | Spanish |
| bn_bd | Bengali |
| hi_in | Hindi |
| fr_fr | French |
Currencies
| Parameter | System Ratio |
|---|---|
| 1IDR | 1 : 1 |
| 1LAK | 1 : 1 |
| 1MMK | 1 : 1 |
| 1VND | 1 : 1 |
| AED | 1 : 1 |
| AMD | 1 : 1 |
| ARS | 1 : 1 |
| AUD | 1 : 1 |
| AZN | 1 : 1 |
| BDT | 1 : 1 |
| BRL | 1 : 1 |
| BYN | 1 : 1 |
| CAD | 1 : 1 |
| CDF | 1 : 1 |
| CHF | 1 : 1 |
| CLP | 1 : 1 |
| CNY | 1 : 1 |
| COP | 1 : 1,000 |
| CZK | 1 : 1 |
| EUR | 1 : 1 |
| ETB | 1 : 1 |
| GBP | 1 : 1 |
| GEL | 1 : 1 |
| GHS | 1 : 1 |
| HKD | 1 : 1 |
| HTG | 1 : 1 |
| HUF | 1 : 1 |
| IN5 | 1 : 1 |
| INR | 1 : 1 |
| IRR | 1 : 1,000 |
| JPY | 1 : 1 |
| KES | 1 : 1 |
| KGS | 1 : 1 |
| KHR | 1 : 1 |
| kIDR | 1 : 1,000 |
| kLAK | 1 : 1,000 |
| kMMK | 1 : 1,000 |
| KRW | 1 : 1 |
| kVND | 1 : 1,000 |
| KZT | 1 : 1 |
| LKR | 1 : 1 |
| MDL | 1 : 1 |
| MXN | 1 : 1 |
| MYR | 1 : 1 |
| NGN | 1 : 1 |
| NIO | 1 : 1 |
| NOK | 1 : 1 |
| NPR | 1 : 1 |
| NZD | 1 : 1 |
| pTTT | 1 : 1 |
| PEN | 1 : 1 |
| PHP | 1 : 1 |
| PK5 | 1 : 1 |
| PKR | 1 : 1 |
| PLN | 1 : 1 |
| RUB | 1 : 1 |
| SEK | 1 : 1 |
| SGD | 1 : 1 |
| SSP | 1 : 1 |
| THB | 1 : 1 |
| TMT | 1 : 1 |
| TND | 1 : 1 |
| TRY | 1 : 1 |
| TZS | 1 : 1,000 |
| uTTT | 1 : 1 |
| UAH | 1 : 1 |
| UGX | 1 : 1,000 |
| USD | 1 : 1 |
| USDT | 1 : 1 |
| UZS | 1 : 1,000 |
| XAF | 1 : 1 |
| XBT | 1,000,000:1 |
| XOF | 1 : 1 |
| ZAR | 1 : 1 |
| ZMW | 1 : 1 |
Update Records
NAdded、UUpdated、DDeleted
v1.9.8
2025/10/14
N Added Game API Message Code Info 13 game not found
v1.9.7
2025/10/13
N Added、 Languages Bengali Hindi French
v1.9.6
2025/02/20
N Added Inquire Bet Record Attention
v1.9.5
2024/6/25
N Added、 Game Settings Status parameter latest,hot,weight
v1.9.4
2022/5/26
U Updated Member Login in Game parameter level
v1.9.3
2022/1/13
U Updated Bet Record parameter event_id, event_amount
v1.9.2
2021/12/2
U Updated Member Login in Game maintenance Attention
v1.9.1
2021/10/12
U Updated Inquire Bet Record Attention
v1.9.0
2021/10/4
N Added Bet Records Summary by Agent
v1.8.1
2021/9/6
U Updated Get Bet Record URL for Details parameter id
D Deleted Get Bet Record URL for Details parameter round_id
v1.8.0
2021/1/25
N Added Online Member List with Balance
v1.7.1
2021/1/25
U Updated login_game returns result.code 1 while under maintenance
v1.7.0
2020/11/03
U Updated Member Login in Game bet level parameters max_bet,min_bet
v1.6.5
2020/10/27
U Updated Supported Currencies
v1.6.3
2020/10/21
N Added*Win/Lose Statistics*
v1.6.2
2020/8/13
U Updated extra locking straight screen
v1.6.1
2020/7/27
N Added Demo Example
v1.6.0
2020/5/22
N Added Game Status
v1.5.0
2020/5/6
U Updated Member Login in Game parameter extra
v1.4.0
2020/4/23
N Updated*API Format*parameter format
v1.3.2
2020/4/10
D Deleted*Bet Recordtimestamp of example
U UpdatedGet Bet Record*enforced
v1.3.1
2020/3/12
U Upsated*Member Login in Game* whether exit/record buttons be hidden
v1.3.0
2020/03/03
N Added Get Bet Record History URL
U Updated Member Login in Game demo option provided
v1.2.2
2020/02/25
D Deleted Random
v1.2.1
2019/12/23
U Updated Random into String
v1.2.0
2019/08/25
N Added Member Login in GameTo get the launch URL for members
D Deleted Enter Game
D Deleted Member Login
v1.0.5
2019/03/27
U Member Login-updated member account from 8~16 to 6~16. - and _ supported.
U Enter Game-Updated operator differentiation.(Optional)
v1.0.4
2019/03/20
U Game List-Updated 9 games and 1 lobby released on 2019/03/20
v1.0.3
2019/03/12
U Bet record define-Updated description of payout_amount