Overview
The DS integration System of Game
DS API uses gRPC as protocol
Related guide: gRPC.
Game Provider applys for the information from the DS before implement it.
- Protobuf files
- {DS_JWT_Token} for Verify Signature Public Key
- {access_token_here} for Authorization
- Game Provider Implement Client side from Protobuf files
- Game Provider offers a game list to DS
- Game Provider offers game launch domain, could be many, repeat and could change the weight.(the weight is bigger, the more possibility to be chosen)
- Game Provider and DS The amount in the system is multiply 10000
- The Min Bet in the system is 100
Request consistency
DS API requests have to be idempotent. All requests contain a request_uuid field.
Authentication
- DS uses API keys to allow access to the API. our will generate a DS API key, and provides the DS API key to You.
- DS expects for the API key to be included in all API requests to the server in a header that looks like the following:
METADATA:
{
"authorization":"bearer eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJpYXQiOjE2MDA3NTc0NjcsImlzcyI6InRlc3QwMSIsInBpZCI6MTA4OH0.yOMeXZCkO_bcFxhn6NmM1YBwU2lC11Vbz8oasud8Q7WGBPvcooJYiQpCPXdK8Xf8Zm_iW9bJoATAFqYXF8QnsA"
}
Authorization: bearer {access_token_here}
Related guide: gRPC Authentication.
Gameplay
DS_JWT_Token
{DS_JWT_Token} PAYLOAD:DATA:
{
"exp": 1601304335,
"t": "5f71f5e34be9eaba4b5cfefb",
"demo": true
}
| Parameter | Description |
|---|---|
| exp | JWT expiration time |
| t | Login Token |
| demo | is Demo |
Support Languages
| Parameter | Description |
|---|---|
| zh_cn | Simplified Chinese |
| en_us | English |
| vi_vn | Vietnamese |
| th_th | Thailand |
| id_id | Indonesian language |
Once you meet the prerequisites, the process is as follows:
- DS offers a game luanch url, Game Provider has to implement the url domain/login/game_id/{DS_JWT_Token}?lang={lang}
- Game Provider auth the {DS_JWT_Token} after receiving the url, and uses the token to call member login api to get member's information.
- Game Provider uses DS Wallet API to interact the event in the game.
DEMO
Below is an example of interaction flow to open the game in DEMO mode:
- in demo mode DS will set demo = true inside the {DS_JWT_Token}, and remove the token parameter.
- When the game URL is returned, the Operator uses it to direct the user to the game (for example, launch it in iframe or redirect the user to the URL)
- In DEMO mode, DS expects no wallet calls.
REAL
Sequence diagram:
Below is an example of interaction flow between the Player, Operator, DS, and game provider in REAL mode:
- DS generates and stores a unique game session {DS_JWT_Token}.
- DS makes a Game URL login/game_id/{DS_JWT_Token} and passes the generated {DS_JWT_Token} along with the request parameters.
- When the game URL is returned, the Operator uses it to direct the user to the game (for example, launch it in an iframe or redirect the operator to the URL).
- When the game URL is loaded in the browser, Game Provider server makes an API Login and balance call to the DS server.
- DS verifies the token against the stored token and returns the users balance. The user can then place a bet.
- When the user attempts to place a bet, a Wallet API call bet is triggered on DS server.
- Then DS verifies the token, forwards the request to the wallet API which ensures that the user has enough money to place this bet, decreases the users balance by the bet amount, and returns the updated user balance, which is forwarded as a response to the game provider.
- If the user wins, the game provider is expected to trigger a payout call to DS server using the Wallet API.
- DS verifies the token, forwards the request to the operator, who ensures an increase in the users balance by the win amount and returns the updated user balance, which is forwarded as a response to the game provider.
- Behaviour in case of player's loss depends on game providers internal logic. Possible options:
- Nothing is sent
- Sent a payout with amount 0
Member
Member Structure:
message Member {
string id = 1;
string account = 2;
string owner_id = 3;
string agent_id = 5;
string wallet_token = 6;
// for display
int64 balance = 7;
string currency_code = 8;
// Bet Limit
int64 max_bet = 9 ;
int64 min_bet = 10 ;
}
Member information will be returned after successful call login
| Parameter | Description |
|---|---|
| id | DS Unique Member Id in DS's system |
| account | Member Account |
| owner_id | Owner Id |
| agent_id | Agent Id |
| wallet_token | Wallet Token |
| balance | Current Balance |
| currency_code | Currency |
| max_bet | Max Bet |
| min_bet | Min Bet |
Login
This endpoint login.
gRPC Request
Method:
rpc login (LoginInfoReq) returns (LoginInfoRes) {}
method api.gateway.MemberProtocolService.login
Query Parameters
Query Parameters :
message LoginInfoReq {
string request_id = 1;
string token = 2;
string game_id = 3;
}
| Parameter | Enforce | Description |
|---|---|---|
| request_id | true | Request Id |
| token | true | Token for Login |
| game_id | true | Game Id |
Response
Response :
message LoginInfoRes {
string request_id = 1;
RS status = 2;
Member member = 3;
}
| Parameter | Description |
|---|---|
| request_id | Request Id |
| status | Response Statuses |
| member | Member Infomation |
Logout
This endpoint logout.
gRPC Request
Method:
rpc logout (LogoutInfoReq) returns (LogoutInfoRes) {}
method api.gateway.MemberProtocolService.logout
Query Parameters
Query Parameters :
message LogoutInfoReq {
string request_id = 1;
// When logined in successfully, use memberId and walletToken to kick out the member
string member_id = 2;
string wallet_token = 3;
// When the login fails, use the login token to logout the member
string token = 4;
}
| Parameter | Enforce | Description |
|---|---|---|
| request_id | true | Request Id |
| member_id | false | Ref 1 |
| wallet_token | false | Ref 1 |
| token | false | Ref 2 |
Response
Response :
message LogoutInfoRes {
string request_id = 1;
RS status = 2;
}
| Parameter | Description |
|---|---|
| request_id | Request Id |
| status | Response Statuses |
WatchKick
- Use stream
subscribed a notification from DS that a member is kicked
gRPC Request
Method:
rpc watchKick (KickReq) returns (stream KickRes) {}
method api.gateway.MemberProtocolService.watchKick
Query Parameters
Query Parameters :
message KickReq {
}
no need any parameter
Response
Response :
message KickRes {
string member_id = 3;
}
| Parameter | Description |
|---|---|
| member_id | Member Id |
Wallet
Bet
This endpoint bet.
gRPC Request
Method:
rpc bet (WalletReq) returns (walletRes) {}
method api.gateway.WalletProtocolService.bet
Query Parameters
Query Parameters :
message WalletReq {
string request_id = 1;
string member_id = 2;
string game_id = 3;
string serial = 4;
int64 bet_amount = 5;
int64 payout_amount = 6;
int64 valid_amount = 7;
int64 fee_amount = 8;
string wallet_token = 9;
}
| Parameter | Enforce | Description |
|---|---|---|
| request_id | true | Request Id |
| member_id | true | Member Id |
| game_id | true | Game Id |
| serial | true | Round number, Mongo ObjectId is required ObjectId |
| wallet_token | true | Wallet token |
| bet_amount | true | Bet amount |
| valid_amount | true | Valid amount |
Response
Response :
message walletRes {
string request_id = 1;
RS status = 6;
int64 balance = 7;
}
| Parameter | Description |
|---|---|
| request_id | Request Id |
| status | Response Statuses |
| balance | Member Balance |
Payout
This endpoint Payout.
gRPC Request
Method:
rpc payout (WalletReq) returns (walletRes) {}
method api.gateway.WalletProtocolService.payout
Query Parameters
Query Parameters :
message WalletReq {
string request_id = 1;
string member_id = 2;
string game_id = 3;
string serial = 4;
int64 bet_amount = 5;
int64 payout_amount = 6;
int64 valid_amount = 7;
int64 fee_amount = 8;
string wallet_token = 9;
}
| Parameter | Enforce | Description |
|---|---|---|
| request_id | true | Request Id |
| member_id | true | Member Id |
| game_id | true | Game Id |
| serial | true | Round number, Mongo ObjectId is required |
| wallet_token | true | Wallet token |
| bet_amount | true | Bet amount |
| valid_amount | true | Valid amount |
Response
Response :
message walletRes {
string request_id = 1;
RS status = 6;
int64 balance = 7;
}
| Parameter | Description |
|---|---|
| request_id | Request Id |
| status | Response Statuses |
| balance | Member Balance |
Rollback
This endpoint Rollback.
gRPC Request
Method:
rpc rollback (WalletReq) returns (walletRes) {}
method api.gateway.WalletProtocolService.rollback
Query Parameters
Query Parameters :
message WalletReq {
string request_id = 1;
string member_id = 2;
string game_id = 3;
string serial = 4;
int64 bet_amount = 5;
int64 payout_amount = 6;
int64 valid_amount = 7;
int64 fee_amount = 8;
string wallet_token = 9;
}
| Parameter | Enforce | Description |
|---|---|---|
| request_id | true | Request Id |
| member_id | true | Member Id |
| game_id | true | Game Id |
| serial | true | Round number, Mongo ObjectId is required |
Response
Response :
message walletRes {
string request_id = 1;
RS status = 6;
int64 balance = 7;
}
| Parameter | Description |
|---|---|
| request_id | Request Id |
| status | Response statuses |
| balance | Member balance |
Balance
This endpoint balance.
gRPC Request
Method:
rpc balance (BalanceReq) returns (BalanceRes) {}
method api.gateway.WalletProtocolService.balance
Query Parameters
Query Parameters :
message BalanceReq {
string member_id = 1;
string game_id = 2;
string wallet_token = 3;
}
| Parameter | Enforce | Description |
|---|---|---|
| member_id | true | Member Id |
| game_id | true | Game Id |
| wallet_token | true | Wallet Token |
Response
Response :
message BalanceRes {
int64 balance = 2;
RS status = 3;
}
| Parameter | Description |
|---|---|
| status | Response Statuses |
| balance | Member Balance |
Watch Balance
- use stream
there is notification after a user's balance changed, then using Balance api to get the user's newest balance.
The command returns Body structured like this:
{
"member_id": 2
}
gRPC Request
Method:
rpc watchBalance (BalanceReq) returns (BalanceRes) {}
method api.gateway.WalletProtocolService.watchBalance
Query Parameters
no need any parameter
Response
Response :
message BalanceRes {
string member_id = 1;
int64 balance = 2;
RS status = 3;
}
| Parameter | Description |
|---|---|
| member_id | Member Id |
Record
Record URL for Details
{DS_JWT_Token} PAYLOAD:DATA:
{
"exp": 1600853001,
"g": "F1001",
"gs": "5f6b03745451a17e528b3275"
}
| Parameter | Description |
|---|---|
| exp | JWT expiration time |
| g | Game Id |
| gs | Game Serial |
- DS offers a url of bet record to show the detail, Game Provider have to implement the url domain/detail/{DS_JWT_Token}?lang={lang}
- Game Provider auth the {DS_JWT_Token} after receiving the url, and according to the parameter to show the detail of the record.
Response Statuses
The DS API uses the following Response Statuses codes:
To Response Statuses, use this code:
syntax = "proto3";
package api.gateway;
// Response Statuses
enum RS {
ERROR_UNKNOWN = 0;
OK = 1;
ERROR_INVALID_AGENT = 2;
ERROR_INVALID_TOKEN = 3;
ERROR_INVALID_GAME = 4;
ERROR_WRONG_CURRENCY = 5;
ERROR_NOT_ENOUGH_MONEY = 6;
ERROR_USER_DISABLED = 7;
ERROR_INVALID_SIGNATURE = 8;
ERROR_TOKEN_EXPIRED = 9;
ERROR_WRONG_SYNTAX = 10;
ERROR_WRONG_TYPES = 11;
ERROR_DUPLICATE_TRANSACTION = 12;
ERROR_TRANSACTION_DOES_NOT_EXIST = 13;
ERROR_TRANSACTION_ROLLED_BACK = 14;
ERROR_TRANSACTION_ALREADY_PAYOUT = 15;
}
| StatusCode | Enum | Description |
|---|---|---|
| 0 | ERROR_UNKNOWN | General error status, for cases without a special error code. |
| 1 | OK | Successful response. |
| 2 | ERROR_INVALID_AGENT | Their agent is disabled or incorrect agent_id is sent. |
| 3 | ERROR_INVALID_TOKEN | Token unknown to DS system. Please, note that there is a different status for expired tokens. |
| 4 | ERROR_INVALID_GAME | Unknown game_id. |
| 5 | ERROR_WRONG_CURRENCY | Transaction currency differs from User's wallet currency. |
| 6 | ERROR_NOT_ENOUGH_MONEY | Not enough money on User's balance to place a bet. Please send the actual balance together with this status. |
| 7 | ERROR_USER_DISABLED | User is disabled/locked and can't place bets. |
| 8 | ERROR_INVALID_SIGNATURE | DS couldn't verify signature on request from Game Provider. |
| 9 | ERROR_TOKEN_EXPIRED | Session with specified token has already expired. |
| 10 | ERROR_WRONG_SYNTAX | Received request doesn't match expected request form and syntax. |
| 11 | ERROR_WRONG_TYPES | Type of parameters in request doesn't match expected types. |
| 12 | ERROR_DUPLICATE_TRANSACTION | A transaction with same transaction_uuid was sent. |
| 13 | ERROR_TRANSACTION_DOES_NOT_EXIST | Returned when the bet referenced in win request can't be found on DS (wasn't processed or was rolled back). If you received rollback request and can't find the transaction to roll back, respond OK |
| 14 | ERROR_TRANSACTION_ROLLED_BACK | DS received rollback request for a transaction which was already rolled back. This status is for cases when the transaction_uuid of the second rollback is different from the initial. If it's same transaction_uuid, then ensure idempotency and respond as you responded initially. |
| 15 | ERROR_TRANSACTION_ALREADY_PAYOUT | DS received payout request for a transaction which was already payout. |