Gateway (1.1.0)

Download OpenAPI specification:

API for depositing and withdrawal

Overview

You can easily and securely process payments from your customers using either the:

  1. Payment API (This is a hosted checkout that will provide you will all payment options)
  2. Direct Integration API (This is a hosted checkout where the user will be taken directly to the payin provider)

The Payments API helps you to process payments of your customers using a variety of payment methods and a single API Endpoint.

Merchants can also access your transaction analytics and manage accounts within the merchant portal.

Before you begin

All requests must use HTTPS. Authentication is achieved using an API Key, passed headers, namely X-Api-Key.

Get your API and Secret Keys

The API’s use a dedicated Merchant API key for all requests. You can create an API under the merchant portal.

The API’s can be generated under Settings - Credentials

Error Handling

We use HTTP statuses for our response as per the HTTP specification

Status range Description
2xx indicates a successful request
4xx indicates there is a problem with the client's request
5xx indicates there is a problem with our servers/infrastructure. In this case it is our responsibility to fix the issue


If you receive a 4xx HTTP status response, it is safe to retry the request after fixing the root cause of the problem (either your request parameters or your account configuration).

If you receive a 5xx HTTP status response, please contact our support with the request information so we can investigate.

Gateway specific codes

For a 400 Bad Request we will provide specific codes and descriptions in the body of the response.

Error code Message
1009 User hasn't confirm bank details yet
1016 Credential not found
1018 Transaction ID is invalid
1021 Transaction ID is missing
1025 An error has occurred. Please try again later.
1026 API Key is missing
1027 API Key not found
1028 API Key has expired
1036 Mode is not valid. Please use 'test' or 'prod' mode.
1037 Tracking Id is missing
1039 This transaction does not exists in our database
1051 Email is missing
1052 Country Code is missing
1062 User Id is missing
1063 First name is missing
1064 Last name is missing
1065 Phone Country is invalid. Use ISO 3166-1 alpha-2 codes
1066 Phone number is missing
1067 Prefix number is missing
1068 Missing Body
1069 Currency is missing
1070 This currency is not supported
1074 IP is missing
1075 Amount is required and should be greater than 0
1076 You can't change this transaction
1086 KYC status is invalid
1089 Client Transaction ID is missing
1094 Max withdrawal limit has been reached for today
1095 Provider ID is missing
1106 Beneficiary name is missing
1107 Bank name is missing
1116 You have reached your daily deposit limit
1117 You have reached your weekly deposit limit
1118 You have reached your monthly deposit limit
1121 DOB is missing
1122 Address is missing
1123 City is missing
1124 Zip Code is missing
1129 You can't cancel this transaction
1130 Min. withdrawal limit is {{amount}}
1142 Transaction is already processed
1153 Invalid Date
1174 Max. deposit limit for this provider is {{amount}} {{currency}}
1175 Min. deposit limit for this provider is {{amount}} {{currency}}
1177 Max. user deposit for today is {{amount}} {{currency}}
1178 Min. user deposit is {{amount}} {{currency}}
1179 Max. user deposit is {{amount}} {{currency}}
1187 Provider Id is required
1200 Domain is not allowed
1208 The provided email has invalid format
1215 Invalid Exp. date
1216 Your KYC needs to be approved
1228 DOB format is wrong
1229 Your Webhook URL is not available at this time
1230 Card Number is required
1231 CVC is required
1232 Exp. month is required
1233 Exp. year is required
1234 Invalid Card Number
1235 Invalid CVC
1236 Routing Id is required
1237 Holder Name is required
1276 This user is restriced to access this provider
1282 Maximum difference between from and to dates must be 7 days
1295 Your IP is blocked
1305 You can't use these credentials because your account has been deleted
1306 S2S is not activated on this account
1329 Provider has been disabled
1384 You're using production credentials but the mode is test
1385 You're using sandbox credentials but the mode is prod
1387 This provider isn't configured to support payouts
1388 This provider isn't supported for S2S payouts
1389 Cardholder name format is invalid
1411 Multiple transactions match this id. Send the transaction_id instead
1412 {{field}} must be a text value
1413 {{field}} is too long. Maximum {{max}} characters
1414 Country code is invalid. Use ISO 3166-1 alpha-2 codes

Error response format

Validation errors are nested under error:

  {
    "error": {
      "code": 1178,
      "message": "Min. user deposit is 10.00 EUR",
      "data": "Min. user deposit is 10.00 EUR",
      "params": { "amount": "10.00", "currency": "EUR" }
    }
  }

Messages that quote a limit are built from a template, so match on code and read the values from params rather than parsing the message text.

API key failures are answered by the authentication layer in a different shape, without a code:

  { "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, authentication failures included.

Field validation

Text fields are checked for shape as well as presence. A field you leave out stays optional - these rules apply to what you do send.

Type. A value must be text. A number is accepted and read as text, so a numeric zip code or phone number is fine. An object, an array, a boolean or a non-finite number is rejected with 1412, naming the field in error.params.field.

Length. Values are trimmed, then measured. Over the limit is rejected with 1413, which reports the field and its maximum in error.params.

Field Maximum
user_id, tracking_id 100
first_name, last_name 100
email 100
address, city 100
zip_code 20
phone.number 20
phone.prefix 5

Email. customer.email must be a valid address; a malformed one is rejected with 1208.

Country. customer.country_code must be a two-letter ISO 3166-1 alpha-2 code and must be a real country - a well-formed code that does not exist, such as FF, is rejected with 1414. Send XX when the country is genuinely unknown; it is accepted and resolved later. customer.phone.country follows the same rules but reports 1065.

Normalisation. Values are stored trimmed, with country codes upper-cased. The cleaned values are what appear on the hosted page, on webhooks and on the transaction endpoints, so a name sent with stray spaces comes back without them.

Language

Every hosted page can be shown in en, de, fr, es, tr or ru. Set request.language when you create the checkout. A regional form is reduced to its base language, so fr-CA and fr_CA both give French, and an unsupported value falls back to English rather than failing the request.

Send language: "auto" to use the language the player's browser asks for, read from its Accept-Language header. The header is never read unless you ask for it this way, so a partner that sends no language keeps English for every player.

Testing

Test accounts allow you to test and process API transactions that mirror the production environment.

Payment transactions processed in the Test environment are executed on a simulator. To create a test payments call the URL does not change. You will just need to ensure you use a DEV API key which can be created under Settings – Credentials

Webhook

When integrating with our system, you will receive webhooks every time the status of a transaction changes. These webhooks are a convenient way to stay up to date with the latest information about your transactions in real-time. If your webhook URL is temporarily inaccessible when we send notifications, our system will automatically retry every five minutes, up to a maximum of 15 attempts.

Below is an example of the payload you will receive in these webhooks:

  {
    "transaction_id": "bbds7128hdha",
    "user_id": "123",
    "tracking_id": "kshdhay6381623",
    "status": "successful",
    "currency": "EUR",
    "amount": "200.00",
    "transaction_type": "withdrawal",
    "provider": "simulator",
    "rejected_reason": "Insufficient funds"
  }

A card deposit carries the card it was paid with:

  {
    "transaction_id": "i2izognxw9jtoai",
    "user_id": "123",
    "tracking_id": "6062e803-a99e-4263-9a17-5c4ef9fc809d",
    "status": "successful",
    "currency": "GBP",
    "amount": "20.00",
    "transaction_type": "deposit",
    "provider": "paysafe",
    "card_details": {
      "masked_number": "51676797****3951",
      "expiry": "02/2029",
      "holder_name": "Samantha Mary Paul",
      "type": "Mastercard",
      "fingerprint": "95f3f7589d68c380061ce6d295038cc92df9bf3b683bc27cc9a26a07da725775"
    }
  }

Webhook Payload Explanation

  • transaction_id: The unique identifier for the transaction in our side.
  • user_id: The user ID associated with the transaction.
  • tracking_id: The unique identifier in your side, which was send when you made the request.
  • status: The current status of the transaction, which can be:
    • expired
    • rejected
    • successful
    • pending
  • currency: The currency in which the transaction is conducted (e.g. EUR).
  • amount: The amount of the transaction (e.g., "200.00").
  • transaction_type: Describes the type of transaction, such as "withdrawal" or "deposit".
  • provider: The payment provider used for the transaction. You will receive this when available.
  • rejected_reason: The reason why the transaction was rejected. You will receive this when the transaction is rejected and we have the reason available.
  • payment_type: Present for bank transfer and wallet providers only, as "bank_transfer" or "wallet". Card providers do not send it.
  • code: The gateway error code behind a rejection. You will receive this when the transaction is rejected and a code is available.
  • card_details: The card the transaction was paid with. Sent on every card provider and on the simulator, once the card is known - so it is absent from the first "pending" webhook of a deposit and present on the ones that follow. It contains:
    • masked_number: The card number with the middle digits masked, e.g. "51676797****3951".
    • expiry: Expiry as "MM/YYYY".
    • holder_name: The cardholder name as it was entered.
    • type: The card brand, e.g. "Visa" or "Mastercard".
    • fingerprint: A stable identifier for the card. The same card always produces the same value, so you can recognise a returning card without storing the number. Sent only when the card has been fingerprinted.
  • name_match: Sent as false when the cardholder name does not match the customer name you registered. It is never sent when the names do match.
  • details: Accompanies name_match with the reason, when one is available.
  • to_wallet / from_wallet: The wallet address or account used, on providers that move funds between wallets.

Webhook Signature

New fields are only ever appended to the payload; existing fields never change or move. The signature covers the whole body, so verify it over the raw request string rather than over re-serialised JSON.

To ensure the integrity and authenticity of the data in these webhooks, it's crucial to verify the included signature. This guide explains how to verify the webhook signature generated by our system. When you receive a webhook, it will include an "x-signature" header in the HTTP request. To generate signature you must use the SHA-1 hashing algorithm. Update the hash with the payload, and then convert it to a hexadecimal representation in uppercase.

Signature sample (NodeJs):

      const crypto = require("crypto");
      const data = /* Data object from the webhook payload */;
      const signaturePassword = /* Your secret signature password that can be find in BACK OFFICE under Credentials page */;
      const payloadForHash = JSON.stringify(data) + signaturePassword;
      const localSignature = crypto
        .createHash("sha1")
        .update(payloadForHash)
        .digest("hex")
        .toUpperCase();

Example:

  payload = 
    {
      "transaction_id":"r21nmrtpcmrcava",
      "user_id":"1111222",
      "tracking_id":"b8f04416-116a-11ed-861d-0242ac120002",
      "status":"rejected",
      "currency":"GBP",
      "amount":"200.00",
      "transaction_type":"withdrawal"
    }
  
  signature_password = spg_test_companyxxxxQyGAheyMqcHVmp8ZMQtkYcev27sCu7RF

Calculated Hash: "5FDDA8F46411C132DCFBEE53C39BA06298CB48BC"

Payment

Hosted Checkout (Recommended)

This endpoint facilitates an all in one cashier, this will provide a one time integration solution that will show all the available providers.

Request origin

The Origin of the call must be registered against your account under Settings - Domains. An unregistered origin is rejected with 1200 (Domain is not allowed).

Error format

Validation errors are returned as:

{
  "error": {
    "code": 1070,
    "message": "This currency is not supported...",
    "data": "This currency is not supported..."
  }
}

Messages that quote a limit also carry the substituted values under error.params. API key failures are answered by the authentication layer in a different shape, with no code:

{ "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, including authentication ones.

Mode must match the API key

A test (sandbox) API key may only create test transactions and a production key only prod transactions. A mismatch is rejected with 1384 or 1385 before anything else is validated.

Amount and limits

amount is only validated when amount_restricted is true. With the flag absent or false the player chooses the amount on the hosted page, and none of the amount checks below run - they are applied on the page instead.

When amount_restricted is true the amount must be greater than 0 (1075) and is checked against your account minimum and maximum (1178 / 1179) and the player's daily, weekly and monthly deposit limits (1116 / 1117 / 1118).

header Parameters
x-api-key
required
string
Example: api_key
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "request": {
    }
}

Response samples

Content type
application/json

Direct Integration

This endpoint facilitates Direct Integration payments, This hosted checkout allows users to be redirected directly to the payment provider for processing. You will need to specify the provider ID which you can find under settings - providers.

Request origin

The Origin of the call must be registered against your account under Settings - Domains. An unregistered origin is rejected with 1200 (Domain is not allowed).

Error format

Validation errors are returned as:

{
  "error": {
    "code": 1070,
    "message": "This currency is not supported...",
    "data": "This currency is not supported..."
  }
}

Messages that quote a limit also carry the substituted values under error.params. API key failures are answered by the authentication layer in a different shape, with no code:

{ "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, including authentication ones.

Provider

provider_id is required (1187). The provider must be active on your account: a disabled or deleted credential is rejected with 1329, and a player excluded from that provider with 1276.

Providers can also carry their own deposit limits, checked after your account limits: 1174 (above the provider maximum) and 1175 (below the provider minimum).

Always-required customer fields

Unlike the hosted checkout, first_name, last_name and email are always required here, even when the customer details step is enabled on your account.

header Parameters
x-api-key
required
string
Example: api_key
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "request": {
    }
}

Server To Server

This endpoint facilitates Server-to-Server (S2S) payments, providing a straightforward integration process. Below, you will find details on its implementation. Upon successful invocation, the response will include two key attributes: url and transaction_status. Check the url on the response; if it is not empty, redirect the user to complete the 3DS process. Additionally, if the transaction_status is rejected, an error attribute will accompany the response.

Request origin

The Origin of the call must be registered against your account under Settings - Domains. An unregistered origin is rejected with 1200 (Domain is not allowed).

Error format

Validation errors are returned as:

{
  "error": {
    "code": 1070,
    "message": "This currency is not supported...",
    "data": "This currency is not supported..."
  }
}

Messages that quote a limit also carry the substituted values under error.params. API key failures are answered by the authentication layer in a different shape, with no code:

{ "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, including authentication ones.

Server-to-server must be enabled

S2S is off by default. If it has not been switched on for your account the call is rejected with 1306 before anything else is checked - contact your account manager to have it enabled.

Card validation

The card is validated before the payment is attempted: holder_name (1237) must contain no digits (1389) and is trimmed of repeated whitespace, card_number (1230) must pass the card number check (1234), cvc (1231 / 1235), and exp_month / exp_year (1232 / 1233) must form a valid expiry no more than 10 years in the future (1215).

Always-required customer fields

first_name, last_name and email are always required here, even when the customer details step is enabled on your account.

header Parameters
x-api-key
required
string
Example: api_key
Request Body schema: application/json
object

Responses

Request samples

Content type
application/json
{
  • "request": {
    }
}

Response samples

Content type
application/json
Example
{
  • "url": "{{url}}",
  • "transaction_status": "pending"
}

Payout

Request Payout

This endpoint facilitates an all in one cashier for withdrawals. This will provide a one time integration solution that will show all the available payout providers. You can configure the payout providers in Settings - Provider Rules

Request origin

The Origin of the call must be registered against your account under Settings - Domains. An unregistered origin is rejected with 1200 (Domain is not allowed).

Error format

Validation errors are returned as:

{
  "error": {
    "code": 1070,
    "message": "This currency is not supported...",
    "data": "This currency is not supported..."
  }
}

Messages that quote a limit also carry the substituted values under error.params. API key failures are answered by the authentication layer in a different shape, with no code:

{ "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, including authentication ones.

Amount and limits

amount is always required and must be greater than 0 (1075). It is checked against the minimum withdrawal configured on your API key (1130, which quotes the limit) and the player's daily withdrawal total (1094).

Skipping the bank details step

The bank_details block is only used when beneficiary_name is present; without that field the whole block is ignored and the player is asked for their details on the hosted page as usual.

A rejected request also sends a webhook

When this endpoint returns an error it also posts a rejected webhook to your status_url, with an empty transaction_id, so a failed call is reported twice: once in the HTTP response and once on the webhook.

header Parameters
x-api-key
required
string
Example: xxxx
Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "request": {
    }
}

Response samples

Content type
application/json
{}

Server-to-Server Payout (Limited Support)

Processes a payout server-to-server using bank details and an explicit provider_id, without showing the hosted cashier. .

The S2S payout supports 3 different approval modes. You have to contact your account manager so it can be configured for you:

  • default — Uses our built-in approval logic.
  • automatic — Always dispatched to the provider immediately. All approval checks are skipped.
  • manual — Always queued with status pending. Must be approved via the back office or /v1/withdrawal/approve.

A pending transaction_status in the response means the payout has been queued; any other value reflects the immediate provider result.

Request origin

The Origin of the call must be registered against your account under Settings - Domains. An unregistered origin is rejected with 1200 (Domain is not allowed).

Error format

Validation errors are returned as:

{
  "error": {
    "code": 1070,
    "message": "This currency is not supported...",
    "data": "This currency is not supported..."
  }
}

Messages that quote a limit also carry the substituted values under error.params. API key failures are answered by the authentication layer in a different shape, with no code:

{ "status": false, "error": { "message": "API Key is missing" } }

All failures use HTTP 400, including authentication ones.

Supported providers

Only Turbo Havale, LuqaPay Havale and Nixxe Simulator can be used. A provider that is not one of those is rejected with 1388, and a provider that is not configured for payouts at all with 1387.

Bank details

beneficiary_name (1106) and bank_name (1107) are always required. Which of the remaining fields are needed depends on the provider and the destination country.

Limits

amount must be greater than 0 (1075) and is checked against the minimum withdrawal on your API key (1130) and the player's daily withdrawal total (1094). kyc_status is required when your account is configured to check KYC (1086).

header Parameters
x-api-key
required
string
Example: xxxx

API key for authentication

Request Body schema: application/json
required
object

Responses

Request samples

Content type
application/json
{
  • "request": {
    }
}

Response samples

Content type
application/json
Example
{
  • "transaction_id": "abc123xyz456789",
  • "transaction_status": "successful"
}

Reject Payout

If there are any pending payouts, this endpoint can be used to reject them from the client side.

Identifying the transaction

transaction_id accepts either your own tracking_id or the gateway transaction_id. Your tracking id is matched first. Because a tracking id is not guaranteed to be unique, a value that matches more than one transaction is refused with 1411 rather than acting on an arbitrary one - resend the request using the gateway transaction_id, which is always unique.

When a payout can be rejected

A payout can only be rejected while the gateway still holds it. The request is refused with 1129 once the payout has been sent to the provider - that is, once it has been processed or has a provider transaction id - or once it has reached a final status.

1142 is different from 1129: it means a back-office operator is working on the payout right now (approving it, or changing its payment method). Nothing was changed, and the request can be retried shortly.

header Parameters
x-api-key
required
string
Example: xxxx

API key for authentication

Request Body schema: application/json
transaction_id
required
string

Either your own tracking_id or the gateway transaction_id. The tracking id is matched first; if it matches more than one transaction the request is refused with 1411 and must be resent with the gateway transaction_id.

Responses

Request samples

Content type
application/json
{
  • "transaction_id": "fb832194-34e1-4e6c-8494-d88034cf3e47"
}

Response samples

Content type
application/json
{
  • "message": "Withdrawal has been rejected successfully"
}

Approve Payout

If there are any pending payouts, this endpoint can be used to approve them from the client side.

Identifying the transaction

transaction_id accepts either your own tracking_id or the gateway transaction_id. Your tracking id is matched first. Because a tracking id is not guaranteed to be unique, a value that matches more than one transaction is refused with 1411 rather than acting on an arbitrary one - resend the request using the gateway transaction_id, which is always unique.

When a payout can be approved

The payout must still be waiting for approval; one that is not is refused with 1076. A payout that has already been sent to the provider, or that a back-office operator is working on at that moment, is refused with 1142.

For providers that require the player to confirm their bank details, a payout whose details are still unconfirmed is refused with 1009.

header Parameters
x-api-key
required
string
Example: xxxx

API key for authentication

Request Body schema: application/json
transaction_id
required
string

Either your own tracking_id or the gateway transaction_id. The tracking id is matched first; if it matches more than one transaction the request is refused with 1411 and must be resent with the gateway transaction_id.

Responses

Request samples

Content type
application/json
{
  • "transaction_id": "fb832194-34e1-4e6c-8494-d88034cf3e47"
}

Response samples

Content type
application/json
{
  • "message": "Transaction Withdrawal has been approved successfully",
  • "transaction_status": "pending"
}

Transactions

Transaction Status

This endpoint can be used to get the latest infromation regarding a specific transaction.

A transaction that failed on the provider side may be reported as failed. A transaction that is still on its way may report a value other than the ones listed, so treat any status you do not recognise as still in progress rather than final.

path Parameters
id
required
string

Unique transaction id in your system

header Parameters
x-api-key
required
string
Example: xxxx

API key for authentication

Responses

Response samples

Content type
application/json
{
  • "transaction_status": "rejected",
  • "rejected_reason": "Insufficient funds"
}

Transaction List

This endpoint retrieves transactions. You can specify a date range using from and to query parameters. If no date range is specified, it will return transactions for the current date. Maximum range between dates it’s 7 days

Both from and to must be supplied together; if either is missing the current day is returned. Dates use DD-MM-YYYY; an unparseable value is rejected with 1153 and a range wider than seven days with 1282.

Every transaction that is still in progress is reported as pending on this endpoint.

query Parameters
from
string
Example: from=01-08-2024

(optional) The start date for the date range in DD-MM-YYYY format.

to
string
Example: to=01-08-2024

(optional) The end date for the date range in DD-MM-YYYY format.

header Parameters
x-api-key
required
string
Example: xxxx

API key for authentication

Responses

Response samples

Content type
application/json
[
  • {
    }
]