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 Wallet API address, Wallet API public key, and Agent Account.
- Please provide IP that connect to us before you get started.(Please filled up in MIF.)
- The integration transmit formation is Json. And is encoded by UTF-8.
Authentication
Generate public key and private key
example_private.pem:
-----BEGIN RSA PRIVATE KEY-----
MIICXgIBAAKBgQC33DHVHpT4IKLzLb59ZcxcmPvUsIO3+s8qd8aAM1le/DHVHmYi
Vp39af0dF+maQ+1NfikmVBfl7HfygCVLb/PtFrfM52zyXXurdM99Ijmgotit3S8X
C0jImrlyCR9TmrSNyN/IadfNby1wFN0jitka3Z7JuFw2ieY3PO2AGh7hewIDAQAB
AoGAUHZ8FIHKvgBCb9wgFm7bjdaht0X8jyKjUTmT1H0kao5CHLuuBO8VO1cMH5Rc
dlet3ZEN3ylEQCpJoAX2zFnVTLmsoH484ODCJkHxuMN0ONzPRiSeJSvgmHj7ko/L
D+19bWe4u0ru216w5Th0etGYNEsYw6BeTNDHK0571vvhjoECQQDno90GAqR6t4xQ
Bkvv2z67hIMPkrw8ahvD1b94jTlkK5pBCnQ4kBx8I0BbFSKOH1NDjpVFifwtOhqo
XDtC7f5BAkEAyzID8BzYar/9J02by6/PNVRxvwO51y6KMX6ZccDd80IeCKYX9Jnw
gUBwI83iLL8C3cF9sTQ9focj7enBO4wouwJBAJruVNTCS7Tws16K95t0Lx9I4Eg4
QsK9zdhMTQaanrpLF59NGLMEYKj/AvpoxnX8qbpT0a9zPUIazN2y4sg/WoECQQCJ
h9LOhFee+U+ZeJgIp3hyOjO6/ASfNqrmkS++pLIVYhz98Z2pO0Bj23+LXGDHtIl2
Gu6+MAOnTkTtVRgq+9TdAkEAqQYCvTifS07C1/9f7bd3EFv2UtCpBiugvLPeTzFK
pAbaXZeMX61rw69V1cVEM5jVBrVW0I66VMJIDlMtuwePrQ==
-----END RSA PRIVATE KEY-----
example_public.pub:
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC33DHVHpT4IKLzLb59ZcxcmPvU
sIO3+s8qd8aAM1le/DHVHmYiVp39af0dF+maQ+1NfikmVBfl7HfygCVLb/PtFrfM
52zyXXurdM99Ijmgotit3S8XC0jImrlyCR9TmrSNyN/IadfNby1wFN0jitka3Z7J
uFw2ieY3PO2AGh7hewIDAQAB
-----END PUBLIC KEY-----
Request Signing
Encryption/Decryption Example:
using System;
using System.IO;
using System.Net;
using System.Text;
using System.Text.Json;
using System.Security.Cryptography;
namespace seamless
{
public class SendData
{
public string channel { get; set; }
public string agent { get; set; }
public string account { get; set; }
}
class Program
{
public static string api_url = "<url>"; // This is a example Url, please fill in the right Url from the MIF
public static string channel = "00746280"; // This is a example Channel, please fill in the right Channel from the MIF
public static string agent = "SeamlessEx01"; // This is a example Agent, please fill in the right Agent from the MIF
public static byte[] HashAndSignBytes(byte[] DataToSign)
{
try
{
// Create a new instance of RSACryptoServiceProvider using the
// key from RSAParameters.
RSACryptoServiceProvider RSAalg = new RSACryptoServiceProvider(1024);
using (var stream = File.OpenRead("example_private.pem")) // Please Change the example_private.pem to your rsaPrivateKey
using (var reader = new PemUtils.PemReader(stream))
{
var rsaParameters = reader.ReadRsaKey();
RSAalg.ImportParameters(rsaParameters);
}
// Hash and sign the data. Pass a new instance of SHA256
// to specify the hashing algorithm.
return RSAalg.SignData(DataToSign, SHA256.Create());
}
catch(CryptographicException e)
{
Console.WriteLine(e.Message);
return null;
}
}
public static void CreateMember()
{
SendData _data = new SendData()
{
channel = channel, // this is a channel
agent = agent, // this is a agent
account = "example001" // This is a example Account, please fill in the right Account from the MIF
};
string Json = JsonSerializer.Serialize<SendData>(_data);
var post_data = Encoding.UTF8.GetBytes(Json);
var signedData = HashAndSignBytes(post_data);
var Signature = Convert.ToBase64String(signedData);
var request = (HttpWebRequest)WebRequest.Create("https://"+ api_url +"/v1/member/create");
request.Method = "POST";
request.ContentType = "application/json";
request.Headers.Set("X-Ds-Signature", Signature);
request.ContentLength = post_data.Length;
using (var stream = request.GetRequestStream())
{
stream.Write(post_data, 0, post_data.Length);
}
var response = (HttpWebResponse)request.GetResponse();
var responseString = new StreamReader(response.GetResponseStream()).ReadToEnd();
Console.WriteLine(responseString);
}
static void Main(string[] args)
{
CreateMember();
}
}
}
package main
import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha256"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"fmt"
"io/ioutil"
"net/http"
)
type CreateMemberRequest struct {
Channel string `json:"channel"`
Agent string `json:"agent"`
Account string `json:"account"`
}
func main() {
apiDomain := "<url>" // This is a example Url, please fill in the right Url from the MIF
rsaPrivateKey := getPrivateKey("./example_private.pem") // Please Change the example_private.pem to your rsaPrivateKey
createMemberReq := CreateMemberRequest{
Channel: "00746280", // This is a example Channel, please fill in the right Channel from the MIF
Agent: "SeamlessEx01", // This is a example Agent, please fill in the right Agent from the MIF
Account: "example001", // This is a example Account, please fill in the right Account from the MIF
}
data, err := json.Marshal(&createMemberReq)
if err != nil {
panic(err)
}
signature, err := sign(rsaPrivateKey, data)
if err != nil {
panic("sing error, err: " + err.Error())
}
base64Signature := base64.StdEncoding.EncodeToString(signature)
url := fmt.Sprintf("https://%s/v1/member/create", apiDomain)
post(url, base64Signature, data)
}
func getPrivateKey(path string) *rsa.PrivateKey {
privateBytes, err := ioutil.ReadFile(path)
if err != nil {
panic("read file error, err: " + err.Error())
}
block, _ := pem.Decode(privateBytes)
if block == nil {
panic("pem decode block nil")
}
switch block.Type {
case "RSA PRIVATE KEY":
rsaPrivateKey, err := x509.ParsePKCS1PrivateKey(block.Bytes)
if err != nil {
panic("x509.ParsePKCS1PrivateKey error, err: " + err.Error())
}
return rsaPrivateKey
default:
panic("block type is not RSA PRIVATE KEY, type: " + block.Type)
}
}
func sign(privateKey *rsa.PrivateKey, data []byte, ) ([]byte, error) {
h := sha256.New()
h.Write(data)
d := h.Sum(nil)
return rsa.SignPKCS1v15(rand.Reader, privateKey, crypto.SHA256, d)
}
func post(url, xDSSignature string, requestBody []byte) (statusCode int, body string) {
req, err := http.NewRequest("POST", url, bytes.NewBuffer(requestBody))
req.Header.Set("X-Ds-Signature", xDSSignature)
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("response Status:", resp.Status)
fmt.Println("response StatusCode:", resp.StatusCode)
responseBody, _ := ioutil.ReadAll(resp.Body)
fmt.Println("response Body:", string(responseBody))
return resp.StatusCode ,string(responseBody)
}
package com.seamless;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.io.ObjectInputFilter.Status;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.io.File;
import java.nio.charset.Charset;
import java.util.Base64;
import java.nio.file.Files;
import java.security.Signature;
import org.bouncycastle.asn1.ASN1Sequence;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;
import java.security.spec.RSAPrivateKeySpec;
import java.security.KeyFactory;
import java.security.PrivateKey;
public class Seamless {
public static final String api_url = "<url>"; // This is a example Url, please fill in the right Url from the MIF
public static final String channel = "00746280"; // This is a example Channel, please fill in the right Channel from the MIF
public static final String agent = "SeamlessEx01"; // This is a example Agent, please fill in the right Agent from the MIF
// Please add your privateKey path
public static final String PRV_PATH = "seamless/java/example_private.pem"; // Please Change the example_private.pem to your rsaPrivateKey
public static String signSHA256RSA(String data) {
try {
File file = new File(PRV_PATH);
String strPk = new String(Files.readAllBytes(file.toPath()), Charset.defaultCharset());
String realPK = strPk.replaceAll("-----BEGIN RSA PRIVATE KEY-----", "")
.replaceAll("-----END RSA PRIVATE KEY-----", "")
.replaceAll("\n", "");
byte[] b1 = Base64.getDecoder().decode(realPK);
ASN1Sequence asn1Data = (ASN1Sequence) ASN1Sequence.fromByteArray(b1);
RSAPrivateKeyStructure asn1PrivKey = new RSAPrivateKeyStructure(asn1Data);
RSAPrivateKeySpec rsaPrivKeySpec = new RSAPrivateKeySpec(asn1PrivKey.getModulus(), asn1PrivKey.getPrivateExponent());
KeyFactory kf = KeyFactory.getInstance("RSA");
PrivateKey privateKey = kf.generatePrivate(rsaPrivKeySpec);
// sign with SHA256withRSA
Signature privateSignature = Signature.getInstance("SHA256withRSA");
privateSignature.initSign(privateKey);
privateSignature.update(data.getBytes("UTF-8"));
byte[] s = privateSignature.sign();
byte[] SignatureData = Base64.getEncoder().encode(s);
return new String(SignatureData);
} catch (java.lang.Exception e) {
System.out.println(e);
}
return "";
}
public static void createMember() {
try{
String data = "{\"agent\":\""+ agent +"\", \"channel\":\""+ channel +"\", \"account\":\"example001\"}"; // This is a example Account, please fill in the right Account from the MIF
System.out.println(data);
String SignatureData = signSHA256RSA(data);
// Create connection
URL url = new URL("https://"+ api_url +"/v1/member/create");
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoOutput(true);
connection.setDoInput(true);
connection.setRequestMethod("POST");
connection.setUseCaches(false);
connection.setInstanceFollowRedirects(true);
connection.setRequestProperty("Content-Type","application/json; charset=UTF-8");
connection.setRequestProperty("X-Ds-Signature",SignatureData);
connection.connect();
// post request
DataOutputStream out = new DataOutputStream(connection.getOutputStream());
out.write(data.getBytes("UTF-8"));
out.flush();
out.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(
connection.getInputStream()));
String lines;
StringBuffer sb = new StringBuffer("");
while ((lines = reader.readLine()) != null) {
lines = new String(lines.getBytes(), "utf-8");
sb.append(lines);
}
System.out.println(sb);
reader.close();
// close connection
connection.disconnect();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String[] args) {
createMember();
}
}
class EXAMPLE
{
protected $api_url = "<url>"; // This is a example Url, please fill in the right Url from the MIF
protected $channel = "00746280"; // This is a example Channel, please fill in the right Channel from the MIF
protected $agent = "SeamlessEx01"; // This is a example Agent, please fill in the right Agent from the MIF
protected $ds_sign = "";
public function encrypt($data)
{
// import your private key
$privateKeyId = openssl_pkey_get_private(file_get_contents('example_private.pem')); // Please Change to your rsaPrivateKey
// sign data with your private key
openssl_sign($data, $signature, $privateKeyId, 'RSA-SHA256');
// encode into base64
$ds_sign = base64_encode($signature);
$this->ds_sign = $ds_sign;
// you may free up memory after, but I wouldn't recommend, since you are going to make many requests and sign each of them.
// importing key from file each time isn't brightest idea
openssl_free_key($privateKeyId);
echo "signature: \n" . $ds_sign . "\n";
return $ds_sign;
}
public function decrypt($data)
{
// importing public key
$ds_pub_key = openssl_pkey_get_public(file_get_contents('example_public.pub')); // Please Change to your rsaPublicKey
// verifying signature for $data and imported public key
// note that signature firstly was decoded from base64
$valid = openssl_verify($data, base64_decode($this->ds_sign), $ds_pub_key, 'RSA-SHA256');
if ($valid == 1){
echo "signature is valid \n";
} else {
echo "signature is NOT valid\n";
}
// same thing about freeing of key
openssl_free_key($ds_pub_key);
}
public function CreateMember()
{
$data = [
"channel" => $this->channel, // This is a Channel
"agent" => $this->agent, // This is a Agent
"account" => "example001", // This is a example Account, please fill in the right Account from the MIF
];
$content = json_encode($data);
$signature = $this->encrypt($content);
$header = [
'Content-type: application/json',
'X-Ds-Signature: '.$signature,
];
$curl = curl_init("https://".$this->api_url."/v1/member/create");
curl_setopt($curl, CURLOPT_HEADER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $content);
$json_response = curl_exec($curl);
$status = curl_getinfo($curl, CURLINFO_HTTP_CODE);
if ( $status != 200 ) {
die("Error: failed with status $status, response $json_response, curl_error " . curl_error($curl) . ", curl_errno " . curl_errno($curl));
}
curl_close($curl);
$response = json_decode($json_response, true);
print_r($response);
}
}
$example = new EXAMPLE();
$example->CreateMember();
import json
import requests
from Crypto.Hash import SHA256
from Crypto.Signature import PKCS1_v1_5
from Crypto.PublicKey import RSA
import base64
api_url = 'https://<url>/' # This is a example Url, please fill in the right Url from the MIF
api = 'v1/member/create'
example_agent = "SeamlessEx01" # This is a example Agent, please fill in the right Agent from the MIF
example_channel = "00746280" # This is a example Channel, please fill in the right Channel from the MIF
example_account = "example001" # This is a example Account, please fill in the right Account from the MIF
def SignData(d, f):
digest = SHA256.new()
digest.update(d.encode())
private_key = open(f, 'rb').read()
prkey = RSA.importKey(private_key)
signer = PKCS1_v1_5.new(prkey)
sig = signer.sign(digest)
return base64.b64encode(sig)
def VerifyData(d, s, f):
digest = SHA256.new()
digest.update(d.encode())
public_key = open(f, 'rb').read()
pbkey = RSA.importKey(public_key)
signer = PKCS1_v1_5.new(pbkey)
return signer.verify(digest, s)
def SignAndVerify():
data = {"channel": example_channel ,"agent": example_agent, "account": example_account}
print ("Sign: ", SignData(json.dumps(data), "example_private.pem")) # Please Change the example_private.pem to your rsaPrivateKey
print ("Verify result: ", VerifyData(json.dumps(data), base64.b64decode(SignData(json.dumps(data), "example_private.pem")), "example_public.pub")) # Please Change the example_private.pem to your rsaPrivateKey, and change the example_public.pub to your rsaPublicKey
def CreateMember():
data = {"channel": example_channel ,"agent": example_agent, "account": example_account}
headers = {
'content-type': "application/json",
'X-Ds-Signature': SignData(json.dumps(data), "example_private.pem") # Please Change the example_private.pem to your rsaPrivateKey
}
resp = requests.request("POST", api_url + api, headers=headers, json=json.loads(json.dumps(data)))
print (resp.text)
SignAndVerify()
CreateMember()
// nodejs example
const request = require("request").defaults({});
var crypto = require("crypto");
var fs = require("fs");
const api_url = "<url>"; // This is a example Url, please fill in the right Url from the MIF
const channel = "00746280"; // This is a example Channel, please fill in the right Channel from the MIF
const agent = "SeamlessEx01"; // This is a example Agent, please fill in the right Agent from the MIF
function CreateMember() {
const data = {
channel: channel, // This is a Channel
agent: agent, // This is a Agent
account: "example001", // This is a example Account, please fill in the right Account from the MIF
};
var dataString = JSON.stringify(data);
return new Promise((done) => {
fs.readFile("example_private.pem", function (err, privateKey) {
// Please Change the example_private.pem to your rsaPrivateKey
var signerObject = crypto.createSign("RSA-SHA256");
signerObject.update(dataString);
var signature = signerObject.sign({ key: privateKey }, "base64");
var sendData = JSON.parse(dataString);
var options = {
url: "https://" + api_url + "/v1/member/create",
headers: {
"X-Ds-Signature": signature,
},
method: "Post",
json: sendData,
};
request(options, (err, res, body) => {
console.log(body);
});
});
});
}
CreateMember();
API Data Signing Method
- All Games API requests have to be signed by Operator.
- All Wallet API requests have to be signed by Dragoon Soft.
- All Wallet API request must be practiced and verified by the Operator.
Encryption Method and Process
Example:
POST /v1/member/create HTTP/1.1
Content-Type: application/json
X-Ds-Signature: QNng1bL9YEXE5yLH6MSCuZ9u34GC3ACrt/EeCltCKGDxwQp3EF/IwpdUlVf/h+DFanLzCirFygiRkwFP09yNHCg6DpZZUc+c0mEmPF7r6xu4Zx4BcRKmBe6hBxUVFHtIdnmvXwuEf5xKAa2/pa0+udyQ+z/YJ14FZcNb8iEfLUI=
{"agent":"agent01","account":"player001","token":"1ceda4754e7e413592a6450fb224165f"}
- Both parties should verify all requests will be signed with RSA-SHA256.
- Before the integration, the Operator generates a private/public key pair, and provides the public key to Dragoon Soft.
- Dragoon Soft generates a RSA private/public key pair, and provides the public key to operator. (RSA KEY lenth should be 1024 or 2048)
- The body of all requests will be signed with RSA-SHA256 using the respective private key and encoded to BASE64
- Body JSON sort shouldn't be changed.
- The signature should be placed in the X-Ds-Signature request header.
- The Operator needs to verify all Wallet API requests using the public key provided by Dragoon Soft.
- Dragoon Soft verifies all Games API requests using the public key provided by the Operator.
- The body of all requests will be signed with
RSA-SHA256using the respectiveprivatekey and encoded to BASE64, the signature should be placed in theX-Ds-Signaturerequest header.
- golang-api-encryption-example
- csharp-api-encryption-example
- java-api-encryption-example
- php-api-encryption-example
- python-api-encryption-example
- nodejs-api-encryption-example
Wallet API-Wallet Operation
Operator should execute wallet API
Wallet API
Get Balance
To get the balance of member
HTTP Request
POST https://<url>/api/wallet/balance
Example:
{
"agent": "agent01",
"account": "player001",
"token": "e278a9ea38da42dd9b84148c2f99a031",
"amount": 0,
"game_id": "100",
"owner_account": "owner01"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| token | String | Yes | wallet access token |
| amount | Number | No | amount |
| game_id | String | Yes | game id |
| owner_account | String | No | owner agent account |
The above command returns JSON structured like this:
{
"balance": 99999.1,
"status": 1
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| balance | Number | member balance PS: support to 2nd decimal place |
| status | Number | wallet message code |
Bet And Payout Request
The operator must first decrease the bet_amount (check if the balance is enough to decrease the bet_amount),
then the operator increases the payout_amount,
and return new balance.
HTTP Request
POST https://<url>/api/wallet/bet_n_pay
Example:
{
"trans_id": "6475bec9b187af9ab5884e30",
"agent": "agent01",
"account": "player001",
"game_id": "1001",
"owner_account": "owner01",
"token": "88406af3628342f19cea6042d0cb2267",
"bet_amount": 10,
"payout_amount": 20,
"valid_amount": 10,
"feature_buy": "FG1:2",
"bet_id": "65ea8c1554e79819302d68e5"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| trans_id | String | Yes | transaction id PS: Mongo ObjectId |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| game_id | String | Yes | game id |
| owner_account | String | No | owner agent account |
| token | String | Yes | wallet access token |
| bet_amount | Number | Yes | transaction bet_amount PS: support to 2nd decimal place |
| payout_amount | Number | Yes | transaction payout_amount PS: support to 2nd decimal place |
| valid_amount | Number | Yes | valid amount |
| feature_buy | String | No | Feature Buy Type:Bet Level ex: FG1:2 |
| bet_id | String | Yes | bet record id PS: Mongo ObjectId |
The above command returns JSON structured like this:
{
"trans_id": "6475bec9b187af9ab5884e30",
"balance": 4000,
"status": 1
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| trans_id | String | transaction id PS: equal to transaction id requested |
| balance | Number | member balance PS: support to 2nd decimal place |
| status | Number | bet_n_pay accepted status |
bet_n_pay accepted status
| Status | Description |
|---|---|
| 1 | payout successful |
| 2 | The user does not exist (deemed as a payout failure) |
| 3 | Failed to sign(deemed as a payout failure) |
| 5 | Balance Insufficient(deemed as a payout failure) |
| If other than status is returned, bet_n_pay will be resent |
bet_n_pay flowchart
Bet Request
Called when the member bets.
Operator is expected to decrease member's balance by amount and return new balance.
HTTP Request
POST https://<url>/api/wallet/bet
Example:
{
"trans_id": "6475bec9b187af9ab5884e30",
"amount": 8000,
"agent": "agent01",
"account": "player001",
"token": "88406af3628342f19cea6042d0cb2267",
"game_id": "1001",
"owner_account": "owner01"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| trans_id | String | Yes | transaction id PS: Mongo ObjectId |
| amount | Number | Yes | transaction amount PS: support to 2nd decimal place |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| token | String | Yes | wallet access token |
| game_id | String | Yes | game id |
| owner_account | String | No | owner agent account |
The above command returns JSON structured like this:
{
"trans_id": "6475bec9b187af9ab5884e30",
"balance": 4000,
"status": 1
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| trans_id | String | transaction id PS: equal to transaction id requested |
| balance | Number | member balance PS: support to 2nd decimal place |
| status | Number | wallet message code |
Payout Request
Called when the User wins.
Operator is expected to increase member's balance by amount and return new balance.
Before any altering of User's balance, operator has to check that win wasn't processed or canceled before.
HTTP Request
POST https://<url>/api/wallet/payout
Example:
{
"trans_id": "6475bec9b187af9ab5884e30",
"amount": 8000,
"agent": "agent01",
"account": "player001",
"game_id": "1001",
"owner_account": "owner01",
"token": "88406af3628342f19cea6042d0cb2267",
"valid_amount": 10,
"feature_buy": "FG1:2",
"bet_id": "65ea8c1554e79819302d68e5"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| trans_id | String | Yes | transaction id PS: equal to transaction id requested |
| amount | Number | Yes | transaction amount PS: support to 2nd decimal place |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| game_id | String | Yes | game id |
| owner_account | String | No | owner agent account |
| token | String | No | wallet access token |
| valid_amount | Number | Yes | valid amount |
| feature_buy | String | No | Feature Buy Type:Bet Level ex: FG1:2 |
| bet_id | String | Yes | bet record id PS: Mongo ObjectId |
The above command returns JSON structured like this:
{
"trans_id": "6475bec9b187af9ab5884e30",
"balance": 4000,
"status": 1
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| trans_id | String | transaction id PS: equal to transaction id requested |
| balance | Number | transaction amount PS: support to 2nd decimal place |
| status | Number | Wallet Message Code |
Cancel Request
Cancel request would be sent instantly if had not received status code 1
HTTP Request
POST https://<url>/api/wallet/cancel
Example:
{
"trans_id": "6475bec9b187af9ab5884e30",
"amount": 8000,
"agent": "agent01",
"account": "player001",
"game_id": "1001"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| trans_id | String | Yes | transaction id PS: equal to transaction id requested |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| game_id | String | Yes | game id |
| amount | Number | Yes | transaction amount PS: support to 2nd decimal place |
| owner_account | String | No | owner agent account |
| token | String | No | wallet access token |
The above command returns JSON structured like this:
{
"trans_id": "6475bec9b187af9ab5884e30",
"balance": 4000,
"status": 1
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| trans_id | String | transaction id PS: equal to transaction id requested |
| balance | Number | transaction amount PS: support to 2nd decimal place |
| status | Number | wallet Message Code |
Game API
Member
To Register Members in DS
To register a new member by API
HTTP Request
POST https://<url>/v1/member/create
Example:
{
"channel": "53346874",
"agent": "agent01",
"account": "player001"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 |
Member Login in Game
To get the launch URL for members
HTTP Request
POST https://<url>/v1/member/login_game
Example:
{
"channel": "91213456",
"game_id": "1001",
"lang": "zh_cn",
"is_demo": true
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| agent | String | Yes | agent account |
| account | String | Yes | member account |
| token | String | Yes | wallet operating token |
| game_id | String | Yes | game id |
| 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 the sheet below |
| max_bet | Number | No | maximum of bet level |
| min_bet | Number | No | minimum of 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"
}
Member Logout
To logout member by API.
HTTP Request
POST https://<url>/v1/member/logout
Example:
{
"channel": "53346874",
"agent": "AG000001",
"account": "Username002"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 |
To Inquire Online Status of Members
Member online information
HTTP Request
POST https://<url>/v1/member/login_info
Example:
{
"channel": "53346874",
"agent": "AG000001",
"account": "Username002"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 Member List
The list of online members.
HTTP Request
POST https://<url>/v1/member/online_list
Example:
{
"channel": "53346874",
"agent": "AG000001"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| agent | String | Yes | agent account |
The above command returns JSON structured like this:
{
"result": {
"code": 1,
"msg": "SUCCESS"
},
"list": [
{
"agent": "game01",
"account": "Username002",
"game_id": "0000",
"login_time": "2020-11-05T08:14:37.929977473Z"
}
]
}
Response Parameters
| Parameter | Type | Description |
|---|---|---|
| code | Number | message code |
| msg | String | message |
| list | OnlineMemberList[] | online member list info |
OnlineMemberList Structure Definition
| Parameter | Type | Description |
|---|---|---|
| agent | String | agent account |
| account | String | member account |
| game_id | String | game id |
| login_time | String | login time |
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 | serial for games |
| 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 Bet Record
To inquire bet records of members belong to agent in a time range.
HTTP Request
POST https://<url>/v1/record/get_bet_records
Example:
{
"channel": "53346874",
"finish_time": {
"start_time": "2018-10-19T08:54:14+01:00",
"end_time": "2018-10-20T11:47:08+01:00"
},
"index": 0,
"limit": 10
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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": "4604283",
"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 items |
| rows | Record[] | bet record rows |
game_type
| Code | Descryption |
|---|---|
| 1 | FISHING |
| 3 | SLOT |
| 4 | ARCADE |
| 99 | SYSTEM |
Get Bet Record URL for Details
To inquire the URL for bet details
HTTP Request
POST https://<url>/v1/record/get_bet_detail_page
Example:
{
"channel": "53346874",
"game_id": "2001",
"game_serial": "23134242",
"lang": "zh_cn",
"session_id": "1001_iEZYLBHs3I8yDAnR:5f3db5dd96009684de9e22e3_5f3dbd055839025095efa8be"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 |
| session_id | String | No | game round id for particular operator |
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 | url for member to use |
Get Bet Record History URL
To inquire the URL for bet history.
HTTP Request
POST https://<url>/v1/member/bet_history
Example:
{
"channel": "53346874",
"agent": "AG0000001",
"account": "MB03",
"game_id": "2001",
"lang": "zh_cn"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 |
| session_id | String | No | game round id for particular operator |
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:
{
"channel": "53346874",
"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 |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 |
Bet Records 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:
{
"channel": "53346874",
"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 |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
| 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 | BetRecordsSummaryByAgent[] | Bet Records Summary by Agent info |
BetRecordsSummaryByAgent 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
Game Status
To inquiry the status of game
HTTP Request
POST https://<url>/v1/config/get_game_info_state_list
Example:
{
"channel": "53346874"
}
URL Parameters
| Parameter | Type | Enforce | Description |
|---|---|---|---|
| channel | String | Yes | channel(provided in MIF) |
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
Game API Message Code Info
| 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 | member cannot be found |
| 11 | agent cannot be found |
| 12 | content type error |
| 13 | game not found |
| 16 | request limit reached |
| 1000 | signature failed |
| 1003 | verification failed |
| 1004 | data base access failed |
| 1005 | wallet not found |
| 1006 | transaction not found |
| 1007 | processing failed |
| 1012 | time is out of range |
Wallet API Message Code Info
| Status | Description |
|---|---|
| 0 | unknown error. bet received will execute cancel process. payout received will enter process to wait payout next time. cancel received will enter process to wait cancel next time. |
| 1 | succeeded |
| 2 | member doesn't exist |
| 3 | verification failed |
| 4 | transaction duplicated |
| 5 | balance insufficient |
| 6 | transaction number doesn't exist. while oprator received payout and cancel request, if there is no bet record with the same id, this code should be returned. |
Format
API Format
| Parameter Key | Type | Format |
|---|---|---|
| account | String | 0~9 , a~z , A~Z , - , _ , length from 4 to 36 |
| token | String | 0~9 , a~z , A~Z , - , length from 20 to 36 |
| serial | String | 0~9 , a~z , A~Z , - , _ , length from 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 | Thailand |
| 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.12.5
2025/10/14
N Added Game API Message Code Info 13 game not found
D Deleted Cancel request would be sent instantly if had not received status code 1 only for Bet Request.
v1.12.4
2025/10/13
N Added Languages Bengali Hindi French
v1.12.3
2025/02/20
N Added Inquire Bet Record Attention
v1.12.2
2024/6/25
N Added Game Settings Game Status parameter latest,hot,weight
v1.12.1
2024/3/7
N Add Wallet API-Bet And Payout Request parameter bet_id
N Add Wallet API-Payout Request parameter bet_id
v1.12.0
2023/7/18
N Add Wallet API-Bet And Payout Request
U Updated Wallet API-Payout Request parameter valid_amount, feature_buy
v1.11.5
2022/5/26
U Updated Member Login in Game parameter level
v1.11.4
2022/4/29
D Deleted API-Payout Request important information Cancel request would be sent instantly if had not received status code 1
v1.11.3
2022/1/13
U Updated Bet Record parameter event_id, event_amount
v1.11.2
2021/12/2
U Updated Member Login in Game maintenance Attention
v1.11.1
2021/10/12
U Updated Inquire Bet Record Attention
v1.11.0
2021/10/4
N Added Bet Records Summary by Agent
v1.10.12
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.10.11
2021/7/1
N Added To Inquire Online Status of Members
v1.10.10
2021/5/12
U Updated Wallet API-Cancel Request parameters
v1.10.9
2021/5/4
U Updated Wallet API-Get Balance, Bet Request, Payout Request parameters
D Deleted login_game parameter group_id
v1.10.8
2021/1/25
U Updated login_game returns result.code 1 while under maintenance
v1.10.7
2021/1/8
U Updated Online Member List URL
v1.10.6
2020/12/7
N Added Online Member List
v1.10.5
2020/10/27
U Updated Supported Currencies
v1.10.4
2020/10/21
N Added Win/Lose Statistics
v1.10.3
2020/9/8
U Updated session_id game round id for particular operator
v1.10.2
2020/8/13
U Updated extra locking straight screen
v1.10.1
2020/7/27
N Added Demo Example
v1.10.0
2020/5/22
N Added Game Status
v1.9.0
2020/5/6
U Updated Member Login in Game parameter extra
v1.8.0
2020/4/23
N Added*API Format* description
v1.7.4
2020/3/12
U Updated Member Login in Game whether exit/record buttons be hidden
v1.7.3
2020/3/03
N Added Get Bet Record History URL
U Updated Member Login in Game demo option provided
v1.7.2
2019/10/25
N Added Member Logout
v1.7.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.6.0
2019/05/01
U Updated URL for directing
D Deleted Game List
v1.5.0
2019/04/18
N Added Get Bet Record URL for Details
v1.4.1
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.4
2019/03/20
U Game List-Updated 9 games and 1 lobby released on 2019/03/20
v1.3.1
2019/03/12
U Bet record define-Updated description of payout_amount