# \[Name] x inabit - Integration Guide

## Overview

This guide outlines the end-to-end integration flow between **Pragmatic Solutions** and **inabit**, enabling seamless crypto payment operations for gaming operators through a jointly managed setup.

The integration is designed to provide operators with a compliant, secure, and scalable infrastructure for managing crypto transactions and treasury operations using inabit's infrastructure, paired with Pragmatic's front-end gaming platform and back-office systems.

Operators onboard through inabit and gain access to a streamlined API-based system where **Pragmatic Solutions acts as the technical integrator**, managing API credentials, infrastructure components (like the inabit Approver Docker), and widget configurations on behalf of the operator.

#### Key Highlights of the Integration:

* **Dual API setup** under the operator’s inabit account to separate admin and signing roles.
* **Flexible deployment** of inabit’s Approver Docker by either Pragmatic or the operator.
* **Mobile app pairing flow** to securely authorize API access and infrastructure linkage.
* **Customizable widgets** set up and maintained by Pragmatic to reflect operator preferences (coins, sweep frequency, expiry, etc.).
* **Live data sync** via webhook and pull APIs for real-time balance updates and transaction visibility.

This integration ensures that the operator benefits from **full automation, visibility, and control**, while Pragmatic handles the complexity of configuration and ongoing updates, offering a plug-and-play experience for crypto enablement in gaming.

### API Introduction

Our API is based on **GraphQL**, allowing clients to query exactly the data they need with maximum flexibility and efficiency. This enables streamlined integration and reduces over-fetching or under-fetching of data.

{% hint style="info" %}
If you'd like to learn more, you're welcome to refer [here](/api-reference/introduction-to-graphql/what-is-graphql.md) for more information.
{% endhint %}

### Additional Reference

We highly advise taking a look at the following pages as you start developing:

* [API Login Access / Authentication](/api-reference/develop-with-inabit-api/getting-started/authentication.md)
* [Remote & Automatic Approvals (Docker Configuration)](broken://spaces/fUjQQn0pomEUaPpV3fnI/pages/ccXJuwRwg2gczKSBaHay)
* [Automate Signing Transactions](broken://spaces/fUjQQn0pomEUaPpV3fnI/pages/0VYX2RSRtyBlvXJfXQqb)
* [Supported Blockchains & Assets](/what-we-support/blockchains.md)

## Technical Architecture: Operator Onboarding

<figure><img src="/files/wPgCTSsi8aKAIP5QetT3" alt=""><figcaption></figcaption></figure>

### Operator Onboarding Flow Explained

When a new Operator is onboarded to inabit, the process begins with registration and device pairing using the inabit mobile app.

Once the Operator is registered and paired:

* **inabit automatically generates two API users** under the Operator’s account:
  * **API Signer** (used by Pragmatic/Operator)
  * **API Admin** (used by Pragmatic)

The **Operator owner** then receives an approval request on their **inabit mobile app** and must approve the newly created API users.

After the API users are approved:

* **inabit securely shares the API credentials with Pragmatic Solutions**, enabling the next steps in the onboarding process.

Next, **Pragmatic installs the inabit Approver Docker** and pairs the **API Signer**.

> Note: The Operator can choose to host the Docker either on their own servers or let Pragmatic manage it.

To complete the pairing process:

* The **Operator enters a pairing code** into their inabit mobile app that is received from Pragmatic (via direct communication).

Now that pairing is done:

* **Pragmatic opens a Master Wallet** with the required blockchains.\
  (This is an inabit wallet used as a central aggregator for the Operator)

Pragmatic then proceeds to **configure the inabit POS widget/s** based on the Operator’s requirements, including:

* Supported coins
* Sweeping frequency
* Expiration time
* And more.

After configuration, inabit supplies the implementation guide, and Pragmatic integrates the widget into the Operator’s platform using the provided code or script.

> #### Now that the flow is clear, let's review the implementation process step by step! :sparkles:

### 1. Operator Onboards to inabit

The Operator begins by creating an account on the inabit platform.

#### Step-by-Step:

1. **As an Operator, visit the onboarding URL:**\
   <https://use.inabit.com/create_account?channel=pragmatic>
2. On the **Plan Selection** screen, select **Enterprise**.\
   This ensures the Operator is granted access to advanced platform features and API capabilities required for the Wallet as a Service integration.
3. Complete **Device Pairing**:\
   As the final onboarding step, the Operator must pair their mobile device with the inabit platform. This process is critical for enabling **self-custody**—meaning the Operator remains the sole custodian of their customers' funds.

   The paired device acts as a cryptographic key manager and approval layer, ensuring secure signing of all transactions and operations on the platform.

{% hint style="info" %}

#### [How to Perform Device Pairing](/guides/devices-pairing.md)

{% endhint %}

### 2. inabit Enables API Access

Inabit allowing access its API for Pragmatic by generating 2 API users under the operator's account.

1. **API Signer**:
   1. This user is created for the sole purpose of serving as the "Approver" to sign transactions using inabit's "Approvals Docker".
2. **API Admin**:
   1. In a nutshell, this user serves essentially as the API Key/Access for inabit's API endpoints.

Note that the owner operator will need to approve the creation of these users on their inabit mobile app.

{% hint style="info" %}
Learn more about API User Roles [here](https://docs.inabit.com/guides/user-roles-in-inabit#api-user-roles).
{% endhint %}

### 3. inabit Sends Access Tokens to Pragmatic

After the API users are approved:

* **inabit shares the API credentials with Pragmatic Solutions**, enabling the next steps in the onboarding process.
* Sharing the access tokens of both users will occur only on a secured channel of Pragmatic's preference.

### 4. Pragmatic Implements inabit Remove Approver App

In order to automate signing transactions on behalf of the operator, Pragmatic needs to install inabit's Remote Approver App and pair the API Signer user.

Please refer to the full guide explaining the Docker's setup and configuration here:

> ### :construction: [Remote Approver App Setup](https://docs.inabit.com/api-reference/remote-approver-app/setup-and-configuration)&#x20;

### 5. Pragmatic Sends Pairing Code to the Operator

Once the docker is up and running, the pairing process will commence as follows:

1. Docker issues a **Pairing Code** in the docker logs.

```bash
{
  level: 'info',
  message: 'Approver needs to be paired, starts a pairing process...',
  metadata: { timestamp: '2024-02-21T08:54:16.071Z' },
  timestamp: '2024-02-21T08:54:16.071Z'
}
{
  level: 'info',
  message: 'Getting a pairing token.',
  metadata: { timestamp: '2024-02-21T08:54:16.075Z' },
  timestamp: '2024-02-21T08:54:16.075Z'
}
{
  level: 'info',
  message: 'Getting a pairing code',
  metadata: { timestamp: '2024-02-21T08:54:17.555Z' },
  timestamp: '2024-02-21T08:54:17.555Z'
}
{
  level: 'info',
  message: 'Pairing code: c754ce6d209dcc1b6f2312903ef31f0ac297b63e5dead29a6b877ecad8c77ada',
  metadata: { timestamp: '2024-02-21T08:54:17.560Z' },
  timestamp: '2024-02-21T08:54:17.560Z'
}
```

1. Docker proceeds to send an approval request to the owner to authorize the approver app (just like any other user).
2. Pragmatic sends the **Pairing Code** to the operator via secured channel of choice.
3. Operator inserts code on the mobile app to complete the pairing process.![](/files/fukfY9cshffX71rWe15t)

### 6. Pragmatic Creates a Master Wallet in Operator's inabit Account

Once device pairing is completed, Pragmatic proceeds to create a **Master Wallet** for the Operator through the inabit's API

#### What is a Master Wallet?

The Master Wallet serves as the **central aggregator** for all crypto transactions and funds flow. It is a secure, self-custody wallet fully accessible by the Operator.

**Supported Blockchains**

During wallet creation, Pragmatic selects the required **blockchains** (e.g., Ethereum, Tron, Polygon) that the Operator will support for their clients. Each blockchain comes with its own address and supports its respective tokens (e.g., USDT on Tron, ETH on Ethereum).

**How to Create a Master Wallet?**

The `CreateWalletWithInabit` mutation allows API admins to create a new inabit wallet (that is accessible in the platform's interface, unlike API wallets) with a designated address for a given asset & blockchain.

> Remember to authenticate to call our GraphQL API using an access token (bearer) with your **API** **Admin** credentials. (If you're not sure how, refer to [Authentication](https://docs.inabit.com/api-reference/develop-with-inabit-api/getting-started/authentication))

```
mutation CreateWalletWithInabit($data: WalletCreateWithInabitInput!) {
  createWalletWithInabit(data: $data) {
    id
    name
  }
}
```

#### **Headers**

| Name          | Value              |
| ------------- | ------------------ |
| Content-Type  | `application/json` |
| Authorization | `Bearer <token>`   |

#### **Body (**<mark style="color:orange;">WalletCreateWithInabitInput</mark> object)

| Name                                             | Type   | Description                      |
| ------------------------------------------------ | ------ | -------------------------------- |
| name<mark style="color:red;">\*</mark>           | string | Name of the wallet               |
| organizationId<mark style="color:red;">\*</mark> | string | ID of the organization in inabit |

Example body:

```graphql
{
  "data": {
    "name": "My Inabit Wallet",
    "organization": {
      "id": "clu6oj0kg0004r4ub98guo82u"
    }
  }
}
```

#### Response

Return values:

| Name | Type   | Description         |
| ---- | ------ | ------------------- |
| id   | String | Created Wallet ID   |
| name | String | Created Wallet Name |

{% tabs %}
{% tab title="🟢 Success" %}

```graphql
{
  "data": {
    "createWalletWithInabit": {
      "id": "clvw5p0oj000er47qhe3atv9d",
      "name": "My Inabit Wallet",
    }
  }
}
```

{% endtab %}

{% tab title="🔴 Failure" %}

```graphql
{
  "error": "Invalid request"
}
```

{% endtab %}
{% endtabs %}

In the mutation's response, you will receive the created API wallet ID including the associated blockchain address.

#### Try it out!

{% embed url="<https://studio.apollographql.com/sandbox/explorer?endpoint=https://api.inabit.app/graphql&explorerURLState=N4IgJg9gxgrgtgUwHYBcQC4RxighigSwiQAIBhAJwXwQHVcAbBhFWglACwEklcAjdgAoAJGHy50JekxaVqKOu268BKHgAccAQgCUJYAB1SJKFRrTmrJT35CxeSaPF7DxkiQJgj7970TeSAF8jQJAAGhAAN1wKAn5mAGcMEHCQdQgElAAzBgIAcw4UAHl1BAp8IiQAZVMCdTRMEECgA>" %}

### 7. Pragmatic Creates & Configures Widgets

### Widget Creation

Pragmatic will create & edit new widgets via a dedicated endpoint that inabit will provide them upon integration kickoff.

### Widget Configuration

#### **Functionality Settings:**

Pragmatic customizes the inabit POS widget based on the Operator’s specific requirements.

inabit offers **robust, per-widget configuration options** that allow fine-tuning of how each widget behaves. Key parameters include:

* **Supported Coins** – Define which cryptocurrencies the widget will accept.
* **Deposit Amount** – This can either be:
  * **Predefined**: The widget displays a specific amount to be deposited by the end-customer.
  * **Flexible**: The widget does not enforce a specific deposit amount, allowing users to send any amount to the assigned address.\
    In this mode, the deposit address remains the same for that customer or session, and **any funds received at that address will be credited** accordingly.
* **Sweeping Frequency** – Set how often received funds are automatically moved to the Master Wallet.
* **Expiration Time** – Configure the time limit for each payment request to remain valid.
* **Blockchain Confirmation** - Configure the required amount of blockchain confirmations per chain.

These and other advanced options allow for flexible and secure integration into any existing flow.

> 👉 For the full list of available settings and best practices, refer to:
>
> * [Creating Widgets Guide](https://docs.inabit.com/inabit-terminal/terminal-guide/creating-widgets)
> * [Advanced Widget Settings](https://docs.inabit.com/inabit-terminal/terminal-guide/creating-widgets/advanced-settings)

#### Customizing The Widget Interface/UX

* By default, you can change the following settings on the widget:
  * **Widget Name**
    * A unique name to identify your widget (e.g., *Basic Plan Payment*).
  * **Description (Optional)**
    * A short explanation of what this widget is used for.
  * **Merchant Name (Optional)**
    * Name of the merchant displayed to the end user (if applicable).
* In case you require additional changes to the styling of the widgets interface (such as adding logos, changing fonts, etc.), you can simply **overwrite** the CSS of the widget.

Note - You/the operator can also decide to let the end-user select an asset & blockchain of their choice yourself:

<figure><img src="/files/x8iiithzL8n8AQTiExko" alt=""><figcaption></figcaption></figure>

The operator also has a chance to look at the widget in a preview mode to see how it will look like:

In the example widget preview:

* Widget Name = "Payment"
* Description = "Transfer funds now"
* Merchant Name = (isn't visible to customer, can be left empty)
* Asset = USDT
* Blockchain/Network = Tron (TRC-20)

<figure><img src="/files/gOlSGsG4BC0XIT9vXTMX" alt=""><figcaption></figcaption></figure>

### 8. Pragmatic Installs Widgets on the Operator's Platform

#### Instructions for Widget Implementation

To implement the widget on the operator's site, please adhere to the following instructions.

**Step 1: Implement Server-Side Terminal Call**

Example:

```
curl --location https://api-prod.inabit.biz/api/v1/purchase
--header Content-Type: application/json
--Authorization: Bearer 3a162afed1d8501f47bdc3f63ea159e315d6da81794c92c57dfac9b0c5e51889
data-row-{
  title: <Your title goes here>,
  subTitle: <your subtitle goes here>,
  siteName: <your siteName goes here>,
  purchaseIdentifier: <your purchase identifier goes here>,
  fiatAmount: <fiat amount goes here>,
  fiatCurrency: <fiat currency goes here>
}
```

**API Key:**

Can be provided via the API/Terminal interface.

**Step 2: Add Script Tag to page Header**

Add a script tag to your page header.

Example:

```javascript
<script src="https://prod.inabit.biz/widget.js" ></script>
```

**Step 3:  Call open.widget Function**

Call `openwidget` function with purchase id (deposit id), should open in popup After the customer clicks on the button (buy with crypto for example )

```markup
// purchaseId is the id from response of previous step, and openInNewWindow is a
boolean that determines if the widget should be opened in a new window or not.
window.openWidget(purchaseId, openInNewWindow);
```

{% hint style="info" %}
Need Help? Feel free to [reach out to us ](mailto:support@inabit.com)if you encounter any issues during the widget implementation process!
{% endhint %}

The operator can also retrieve the above information themselves by accessing the terminal through their inabit account by logging into our platform.

<figure><img src="/files/a8sJcMZG4IQ7ilxuCXns" alt=""><figcaption></figcaption></figure>

### Deposit Management (Webhooks) :bell:

#### How Will Pragmatic Stay Up-to-Date on Incoming Deposits?

In the **iGaming industry**, it's common practice to **lock funds once a deposit transaction is detected on-chain**, even before it has been fully confirmed. This provides a better user experience by showing a successful deposit immediately—while still protecting the operator by making the funds **non-withdrawable** until sufficient blockchain confirmations are received.

inabit's system fully supports this flow: once a transaction is detected, it updates the widget with a pending confirmation status, allowing the platform to reflect the deposit in the UI while ensuring risk mitigation through backend-level enforcement of fund availability only after confirmation.

To keep Pragmatic in sync, **inabit sends webhook callbacks** for each deposit event and any change in deposit status, enabling real-time tracking of user payments and status-based logic within Pragmatic’s environment.

**List of potential Deposit Statuses:**

* **`Initiated`** – The deposit request has been created, but no blockchain deposit address has been assigned yet.
* **`Allocated`** – A unique blockchain address has been successfully generated and linked to the deposit.
* **`Undercharge`** – The customer deposited **less** than the expected amount, but the deposit window is still active, allowing them to complete the payment.
* **`UnderchargeExpired`** – The customer deposited less than the required amount, **and the payment window has expired**, meaning the transaction cannot be completed.
* **`Confirming`** – The full amount has been received, and the system is now waiting for the required number of blockchain confirmations to mark the deposit as successful.
* **`Unconfirmed`** – A deposit has been detected on the blockchain **but has not yet been included in a block** (only relevant for UTXO-based networks such as Bitcoin).
* **`Overcharge`** – The customer deposited **more** than the required amount. The deposit will still be processed, and the system may handle the excess according to predefined rules (e.g., ignore, credit, or refund).
* **`Expired`** – The customer did not complete the payment within the allowed time window, and the transaction is no longer valid.
* **`Completed`** – The required number of blockchain confirmations has been received, and the deposit is finalized successfully.

```json
Get deposit by UUID for merchant
{{base_url}}/v1/merchant/purchase/{{purchaseId}}
{
    "data": {
        "id": "057590e2-002d-4c3b-b646-6a9fbcda89b0",
        "title": "Payment Title X",
        "subTitle": "The payment description XXX",
        "siteName": "Merchant Site",
        "asset": "TRX",
        "blockchain": "tron",
        "address": "TSRgRsSagJkeTza5Ei2bamDHp3sscbWhud",
        "transactions": [
            "302ae537cde6d88bafc5f84f8406ffab48f973bd31cce40de15b66d9adcfb00a"
        ],
        "fiatAmount": 2.5,
        "fiatCurrency": "USD",
        "currentDate": "2025-05-02T10:52:02.871Z",
        "confirmationAmount": 20,
        "amount": 10.174252,
        "plannedAmount": 10.174252,
        "baseCurrency": "USD",
        "baseCurrencyAmount": 2.499494,
        "plannedBaseCurrencyAmount": 2.499979,
        "creationDate": "2025-04-29T15:28:48.742Z",
        "allocationDate": "2025-04-29T15:29:07.974Z",
        "expirationDate": "2025-04-29T15:39:07.974Z",
        "status": "Completed",
        "acceptPartialPayment": true,
        "widgetName": "MyFirstWidget9",
        "sweepingStatus": "TBD",
        "sweepingFee": "TBD",
        "merchantName": "Merchant #1",
        "redirectUrl": "https://dev-merchant.aybabtu.xyz/",
        "widgetId": "8157eb9f-0ace-45ae-b8c9-7953637896cf",
        "purchaseIdentifier": "customer@gmail.com"
    }
}
}
```

### Operator Withdrawal Process

#### How Are Withdrawals Handled?

Withdrawals are processed **centrally from the master wallet**, which acts as the secure treasury account for each operator. This wallet receives funds via **automatic sweeps** from all the individual deposit wallets (API wallets) that are generated through inabit’s POS widgets.

Here's How It Works:

1. **Deposit Collection & Sweeping**\
   Each time a user deposits via a POS widget, a unique blockchain address (API wallet) is created. Once a deposit is confirmed, **inabit automatically sweeps** the funds from these individual wallets to the operator’s [**master wallet**](#id-6.-pragmatic-creates-a-master-wallet-in-operators-inabit-account) at predefined intervals (e.g., hourly, daily).

{% hint style="info" %}
Refer to our documentation to learn more about "[Gas Fees](/inabit-terminal/terminal-guide/gas-features.md)" and "[Sweeping](/inabit-terminal/terminal-guide/gas-features/gas-sweeping.md)".
{% endhint %}

1. **Withdrawal Execution**\
   Once the funds are consolidated in the master wallet, withdrawals can be initiated.\
   Pragmatic or the operator can trigger a withdrawal using inabit’s APIs.\
   \
   **Creating a Withdrawal via API**

   Initiate a mutation to create an assets transfer request to send for approval from the master wallet.<br>

   ```graphql
   mutation CreateWithdrawal($data: WithdrawalCreateInput!) {
     createWithdrawal(data: $data) {
       id
     }
   }
   ```

   **Headers**

   | Name          | Value              |
   | ------------- | ------------------ |
   | Content-Type  | `application/json` |
   | Authorization | `Bearer <token>`   |

   **Body (**<mark style="color:orange;">**WithdrawalCreateInput**</mark>**) object**

   | Name                                                  | Type    | Description                                                  |
   | ----------------------------------------------------- | ------- | ------------------------------------------------------------ |
   | id<mark style="color:red;">\*</mark>                  | String  | Master Wallet ID                                             |
   | id<mark style="color:red;">\*</mark> (financialAsset) | String  | Asset ID                                                     |
   | address<mark style="color:red;">\*</mark>             | String  | Destination Address (To)                                     |
   | amount<mark style="color:red;">\*</mark>              | Integer | Transfer amount                                              |
   | id<mark style="color:red;">\*</mark> (blockchain)     | String  | Blockchain ID                                                |
   | note                                                  | String  | Transaction Note                                             |
   | priority                                              | String  | <p>Transaction Priority</p><p>(Slow, medium, fast, etc.)</p> |

   \
   Example body:

   ```graphql
   {
   	"data": {
   		"wallet": {
   			"id": "clol7o576002oaz011mmtnvru"
   		},
   		"financialAsset": {
   			"id": "clefn78gv011olc6rcwtt0wel"
   		},
   		"address": "0x7582f3483116105e0b7845ac1a0df5eb0c8cd062",
   		"amount": 5,
   		"blockchain": {
   			"id": "clefn78em00mslc6r3lzf3h5a"
   		},
   		"note": "",
   		"priority": "Medium"
   	}
   }
   ```

   ### Response

   Return values:

   | Name | Type   | Description   |
   | ---- | ------ | ------------- |
   | id   | String | Withdrawal ID |

2. **Real-Time Visibility**\
   inabit provides real-time status updates on withdrawal requests, including initiation, signing, blockchain confirmation, and completion, allowing Pragmatic to reflect up-to-date information within its platform and back office.

{% hint style="info" %}
To find out how to subscribe to Withdrawal Webhooks, please visit our [Webhooks](/api-reference/remote-approver-app/webhooks.md) page.
{% endhint %}

3. **Security and Policy**\
   All outgoing transactions undergo **approval logic** (via the Approver Docker and mobile app).\
   Only authorized signers (e.g., the API Signer configured during onboarding) can approve withdrawals.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.inabit.com/pragmatic.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
