API
Quick guide on Apps integration

Integration scheme

1 Player comes to the page with the game and loads game-client from the section “Games”
2 Site proxies download the game-client to Amazon S3.
3 Game Client loads the state of the game from the site.
4 Site proxies a request to our game server.
56 Game server requests the billing about the balance change.
78 Billing processing the change and sending the balance to the game-server.
9 Game-server returns the result of the game to the site.
10 Game Client gets changes from the site. Player sees the results.

Step 1. Implementation of withdrawal/refilling method in your billing system

During the game Games Server communicates with your website billing system using POST /.../do method to change player's balance as soon as it's changing because of the spin or winning. This method accepts JSON as an argument with the following fields:


"method"  - "do"     - operation of withdrawal/replenishment;
"session"            - game session ID; (see Step 2);
"minus"              - 0 or the withdrawal sum as a positive number, which stands for the withdrawal sum in kopecks or roubles (it's set on Games Server);
"plus"               - 0 or the refilling sum as a positive number, which stands for the refilling sum in kopecks or roubles (it's set on Games Server);
"trx_id"             - unique transaction number (string), which can include a UUID or a positive integer;
"sign"               - unique sign to queries from Games Server to your website billing system (used optionally from your request). Check authenticity for Sign must be performed on your website billing system (for more detail see below *);
"tag"                - operation target containing the nested structure with the following optional fields:
    //для Slots:
    {
        "game": "slot",
        "game_id": "a_op",            // Game source (see Additional information)
        "game_uuid": 100001,          // Spin ID in the system (for more detail see below **)
        "lines": 1,                   // Lines
        "bet": 1,                     // Bets
        "denomination": 100           // Denomination index
    }

    //for EGames:
    {
        "game": "egame",
        "game_id": "turbokeno",      // Game source (see Additional information)
        "game_uuid": "AA-BB-CC",     // Bet ID in the system**
        "bets": [                    // Bets
            "[0]:1000",              // Bet:amount
            ...
        ],
        "result": [1,2,3,4,5,6,7...] // Game result
    }

    //for Bets:
    {
        "game": "bet",
        "game_id": "1009",           // Game source (see Additional information)
        "game_uuid": "AA-BB-CC",     // Bet ID in the system**
        "round": 10000,              // Round
        "bets": [                    // Bets
            "[0]:1000",              // Bet:amount
            ...
        ],
        "result": [1,2,3,4,5,6,7...] // Game result
    }
	
All fields in query must be filled, exception - balance request, for which parameter "game_id" in field "tag" can be empty.

* To check Sign authencity you have to use request variables session, trx_id and secret word $salt (administrators provide this unique word on your request). For getting control line you must use code below (it takes md5 summ of line $str 45 times):
$str = "do::".$json['session']."::".$json['trx_id']."::".$salt;
for($i=1; $i<=45; $i++) {$str = md5($str);}

If sign received from Games Server does not match calculated line $str, then your website billing system must reply with:
{”status”: "sign_not_found"}

**game_uuid — a unique identifier, which allows to associate a bet event with a win event.
In every round for slots one bet comes with unique game_uuid, and in the case the bet won, the winning comes with the same game_uuid.
For egames one bet and then its winning come with the same game_uuid every round.
For  bets in every round multiple bets and/or bet packages may be recieved:
1) Requests for bet registration may be sent to the billing in packages or one by one. A single bet or the whole package is assigned a unique game_uuid.
2) Requests for bet cancelation may refer to a single bet, part of the package or the whole package (game_uuid matches point 1).
If all bets within the package were canceled, then the null request for the win payout isn’t sent.
3) Requests for win payouts may refer to a single bet, or the package (the canceled bets and not excluded from the package).
In the case that all bets in the package are losing, there is a request for win payout with a null amount (game_uuid matches point 1).
If the package contains both winning and losing bets, their info is sent as a single transaction for all of them (game_uuid matches point 1). For losing bets the win payout is equal to null.

The service is waiting for one of the following replies:

Provided that an operation was successful:

    { "status":"OK", "balance":195650, "currency": "FUN" }

Provided that there was an error:

    { "status":"not_enough_money", "balance":2, "currency": "FUN" } - when player does not have sufficient money;
{ "status":"session_not_found" } - when session is not found or invalid;
{ "status":"sign_not_found" } - when a sign received from Games Server mismatches the one computed by your server

No other replies or types of errors are accepted.

Game calls this method after each event affecting player's balance.

Notice: If the reply is not received, our server will make 10 more call attempts. Your billing system must control that the balance is not withdrawn or refilled more than once if you receive several requests with same trx_id. If two requests with same trx_id are received then answer to the second one with the current balance without taking any additional actions.
By default for protection from unforeseen technical problems, billing system will be blocked for 1 minute after 10 consecutive failed requests. At your request, we can increase this period or give you an option to unblock the system with api.

The simplest example of API billing implementation can be downloaded here: for PHP, for Python.

Implement this method on your billing server and provide its link to our manager (implementation must be checked on a test server before deploying to production).

After that your unique partner ID ${customer_id} will be provided by the manager.

The frequency of data exchange between server Games Server and game:
With query initialization (init) a game examines our Game Server for changes in player's balance or session_id once in two seconds. This is necessary to deliver to a player information about his current balance and to check if another session exists for this player (to prevent undesired operations performed using multiple sessions on one player's account).


Interaction between server Games Server and your billing system:
In standby mode Games Server examines your billing system once in a minute, when there are changes to send - more often. This is done to prevent situations when your billing system might consider often queries from our Games Server as a DDoS-attack.


Information about calculated bets:
Games Server transfers a summarized amount of all bets in the request as a withdrawal/refilling value. If it is necessary to handle results for each bet individually, we can provide you with calculation logic (values in $tag filed are used for this purpose).

Step 2. Creating web page containing a game

To embed a game, you should put the following code into the page:

<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1" />
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0, user-scalable=no, minimal-ui" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<script type="text/javascript" src="${path_to_storage}/prod_flash_data.js"></script>
<script src="${path_to_storage}/loader/build/app.js"></script>
<script type="text/javascript">
window.init_loader({
            path: "${path_to_storage}/",
            game: "${application}",
            billing: "${customer_id}",
            token: "${session}",
            kf: "${denomination}",
            kf_list: [${kf_list}],				
            currency: "${currency}",
            language: "${language}",
            home_page: "${home_page}"
});
</script>
<div id="game-content"></div>

Here:

<div id="game-content"></div> - div container, that will contain embedded game, container ID should not be changed;
${customer_id}     - system ID, issued in Step 1;
${session}         - game session ID (for more detail see below *);
${denomination}    - cost of one credit in kopecks (100 = 1 rub), this parameter is ignored for the bets;
${kf_list}         - array of values for the denomination switcher (100 = 1 rub) - maximum of 12 values in the array (for example: kf_list: [1,10,100,500]), the value may be unspecified, in this case the default value will be used [1,5,10,50,100,500], the value parameter is ignored for betting games;
${application}     - game ID, taken from file prod_flash_html5.json. Game ID is the key in JSON object "applications" (for example, a_ec, a_h, etc.)
${currency}        - currency shown in the app;
${language}        - app language, en_US for English, ru_RU for Russian, es_ES for Spanish, pt_PT for Portuguese, pt_BR for Brazilian, fr_FR for French;
${home_page}       - option for going back to main page by clicking Home icon in mobile version (for example "/"). Any other URL can be specified;
${path_to_storage} - proxy server address (for more detail see Step 3. By default - /media;

For more details on prod_flash_html5.json file structure see «List of applications».

* Game session ID “session” is a key using which billing will perform operations with the account. It is recommended to change the key for each player once per day. It has open access so it is recommended to use a cryptographic procedure to create it, like this:

function getSlotSession() {
    $tokens = array($this->getUserId(), session_id());
    $tokens[] = md5($tokens[0] . "," . $tokens[1] . ",some_secret_message");
    return implode('|', $tokens);
}

Step 3. Proxy queries setting

For proper app operation, proxy settings are required for following requests:

Example of configuration for nginx:

        location ${path_to_storage}/
        {
            proxy_pass http://flashslots.s3.amazonaws.com/;
            proxy_redirect  off;
            proxy_set_header        X-Real-IP       $remote_addr;
            proxy_set_header        Host            flashslots.s3.amazonaws.com;
            proxy_set_header Authorization "";
        }

        location /${customer_id}/api/
        {
            proxy_pass http://flash-api.status200.io:8080;
            access_log /var/log/nginx/slot_api.access_log mainext;
            proxy_redirect  off;
            proxy_set_header        X-Real-IP       $remote_addr;
        }

Example of configuration for apache:

        <Location ${path_to_storage}>
            RewriteEngine On
            RewriteCond %{REMOTE_HOST} (.+)
            RewriteRule . - [E=RH:%1]
            RequestHeader set X-Real-IP %{RH}e
            ProxyPass http://flashslots.s3.amazonaws.com
            ProxyPassReverse http://flashslots.s3.amazonaws.com
        </Location>

        <Location /${customer_id}/api/>
            RewriteEngine On
            RewriteCond %{REMOTE_HOST} (.+)
            RewriteRule . - [E=RH:%1]
            RequestHeader set X-Real-IP %{RH}e
            ProxyPass http://flash-api.status200.io:8080/${customer_id}/api/
            ProxyPassReverse http://flash-api.status200.io:8080/${customer_id}/api/
        </Location>

Congratulations! If you have followed these three steps, the game should work correctly.

Additional information

List of Apps

The whole list of apps and the app server address (${gameserver_address}) can be always found here:
http://flashslots.s3.amazonaws.com/prod_flash_html5.json

ATTENTION: 
The file is updated after the release of new games. 
The file should be downloaded from the server from time to time.

File structure:

{
    "api": "http://flash-api.status200.io:8080/", /* App server address ${gameserver_address} */
    "applications": {
        "a_op": { /* Game ID */
            "html5":{"app": ["a_op-201707051645"], "mainjs": "game.js"}, /* Html5 App folder name */
            "loader": "a_op", 
            "name": [ /* The name of the game */
                    {
                        "en": "Ocean Pearl"
                    }
            ],
            "position": "1", /* 1 - rotation function switched off in landscape-mode for mobile devices; 2 - switched on. */	
            "lines": "9", /* Number of lines for slots. */	
            "source": "a_op", /* Game source */				
            "preview": "thumb/a_op.png", /* Path to the game icon  http://${path_to_storage}/thumb/a_op.png */
            "type": "slot" /* App type */
        },
        "e_keno": {
            "html5":{"app": ["turbokeno-201707201722"], "mainjs": "game.js"},
            "lang": [
                    "en"
            ],
            "loader": "e_keno",                                              
            "name": [
                    {
                        "en": "Turbo Keno"
                    }
            ],
            "position": "2"
            "source": "turbokeno", /* Game source */				
            "preview": "thumb/e_keno.png",									
            "type": "egame"
        },
        ...
    },
    "container": "http://flashslots.s3.amazonaws.com/", /* Path to the container */
    "container_name": "flashslots", /* Container name */
}

The  "type" field can be used for grouping of apps. At the moment there are the following types: “slot” - drum, “egame” – with generation, “betting” – live bets.

Adding Gift Spins

http://flashslots.s3.amazonaws.com/info/api_instructions_giftspins_new_EN.html

Demo Server

http://apigames.status200.io/

Configuration

Configuration file:
http://flashslots.s3.amazonaws.com/prod_flash_html5.json

s3_bucket:
http://flashslots.s3.amazonaws.com/