Payment Service Providers

Guide describing how PSPs integrate with inabit’s our Terminal Gateway API

Overview

This guide describes the end-to-end integration between a PSP and inabit to power crypto payments for multiple merchants under a single PSP-owned account. The integration provides a compliant, secure, and scalable self-custodial setup using inabit’s infrastructure, paired with the PSP’s front-end and back-office systems.

Key Highlights

  • Single PSP account on inabit; each merchant is mapped to its own widget

  • Treasury owned by the PSP: automatic sweeping, crypto-to-crypto swaps, withdrawals, and off-ramping executed under PSP policy and compliance.

  • Remote Approver App (Approver Docker) hosted by the PSP or managed by inabit to enforce policy-based approvals.

  • Operational visibility via webhooks plus safety-net API polling for deposits/withdrawals, enabling accurate settlement and reconciliation per merchant.

This approach gives the PSP full operational control and compliance ownership while delivering fast merchant onboarding, reliable settlement, and transparent status updates—without requiring merchants to manage crypto infrastructure.

2. Architecture & Concepts

Before integrating, it is critical to understand the three main components of the inabit ecosystem:

A. Wallet Hierarchy

inabit utilizes a dual-wallet system to separate customer deposits from treasury operations:

  • API Wallets (Deposit Addresses): These are generated programmatically for every transaction or customer. They serve as the entry point for funds and automatically sweep received assets into your central treasury.

  • UI Wallets (Treasury & Operations): These are the permanent wallets managed via the Inabit Dashboard or Admin API (e.g., Master Wallet, Operational Wallet). They are used to aggregate funds, manage liquidity, and execute settlements.

Important: For the mandatory architecture regarding how to separate your Master Wallet (Cold/Treasury) from your Operational Wallet (Hot/Settlement), please refer to the [Wallet Structures Best Practices] guide.

B. The Approver (Security Layer)

inabit utilizes a "Remote Approver App" (Approver Docker) to enforce security policies.

  • Function: It cryptographically signs transactions based on your defined policies (e.g., "Auto-approve transfers under $10k").

  • Deployment: You can Self-Host (recommended for full control) or use inabit-Hosted (managed service).

C. API Structure

The integration uses a hybrid API approach:

  • GraphQL API: Used for backend operations (Withdrawals, Wallet Management, Reporting).

  • REST API (Terminal): Used for frontend payment intent creation and widget rendering.

3. API Credentials

Once onboarding is complete, inabit generates the following keys. (except for the widget API key, that is generated upon widget's creation) You must use the correct key for the specific task:

Which key do I use, and when?

Action
Use this key
Why / Scope
Provided when
Tiny header example

Create/list UI wallets create withdrawals,view wallets, open new wallet, add coins

API Admin (GraphQL)

Platform-level ops & governance

At account opening - provided by inabit Support

Authorization: Bearer <API_ADMIN_TOKEN>

Org-wide Terminal reads (e.g., get all widgets, get all customers), org-scoped deposit lookups

Terminal Organization API Key (REST)

Organization-level Terminal access across widgets/customers

When Terminal is enabled - provided by inabit Support

Authorization: Bearer <TERMINAL_ORG_API_KEY>

Single-widget reads (e.g., get widget details, purchase and deposit statuses)

Terminal Widget API Key (REST)

Per-widget access; safer for widget-scoped services

During widget setup - shown on the widget implementation instructions page in the platform

Authorization: Bearer <TERMINAL_WIDGET_API_KEY>

Additional Reference

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

  • API Login Access / Authentication

  • Remote & Automatic Approvals (Docker Configuration)

  • Automate Signing Transactions

  • Supported Blockchains & Assets

4. Onboarding to inabit

a. Open account + pairing

b. signs up: https://use.inabit.com/create_account

c. Pair the owner’s mobile device (key custody + approvals). Device pairing enables secure, policy-enforced approvals for sensitive actions.

d. inabit Enables API Access

inabit automatically generates two API users.

  • API Signer

    • Created for the sole purpose of serving as the "Approver" to sign transactions using inabit's Approvals Docker.

  • API Admin

    • Serves as the API key/access user for inabit's API endpoints.

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

Learn more about API User Roles in this dedicated guide.

e. Open UI wallets

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

For recommended best-practice wallet structures, see here: For inabit wallet types guide, see here

f .Implement Remote Approver App

The Remote Approver App (Approver Docker) enables policy-based, automated approvals for API wallets only (it does not apply to UI wallets).

Deployment options

  • Self-hosted (recommended default): One-time Docker setup via the inabit CLI on your own infrastructure.

  • inabit-hosted (managed): inabit can host and operate the Remote Approver App for you

  • For inabit-hosted contact inabit support

When to choose which?

  • Choose self-hosted if you require full infrastructure control or have strict internal hosting policies.

  • Choose inabit-hosted to reduce ops overhead; in this managed mode, API wallets can transfer funds only to internal wallets within your organization, and you still retain self-custody via your approval policies and paired identities.

5. Enabling Terminal

To enable inabit Terminal, contact our Support.

6. Creates & Configures Widgets

Widget Creation

Widgets are created and managed directly in the inabit Terminal UI. The PSP creates a separate widget for each merchant, and configures its parameters (supported blockchains, assets, visual settings) and generates the widget-specific API key and snippet, which is then embedded.

Widget Configuration

Choosing the Right Widget Type:

The PSP selects and configures the widget per merchant use case. inabit supports two types: Purchase Address and Customer Address.”

Example use case
Widget type to use
Why

One-time payment per transaction (e.g., single bet, fixed-price checkout, specific game session)

Purchase Address

Creates a time-boxed, amount-bound address per purchase with clear success/expiry states.

Funding a customer wallet / account balance with flexible amounts used across sessions

Customer Address

Provides a persistent address per customer for ongoing top-ups and balance management.

Dedicated address per customer for recurring deposits, reconciliation, and linking on-chain flows to a user profile

Customer Address

Stable, per-customer address simplifies reconciliation and KYC/accounting.

Quick picker:

  • Need exact amount + expiry for a single transaction? → Purchase Address

  • Need recurring or flexible deposits tied to a customer? → Customer Address

Implementation notes:

  • Both types support: confirmations policy, auto-sweep to Master Wallet, and coin/chain allow-lists.

  • Typically: shorter expiry for Purchase Address; no expiry (or long TTL) for Customer Address.

For a full description of widget types, their behavior, and recommended use cases, see here :


Functionality Settings

Once the widget type is chosen, customize the widget based on the merchant’s 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 – (Purchase Address only)

  • 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/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 (Purchase Address only) – Configure how long each payment request remains valid.

  • Blockchain Confirmations – Configure the required number of confirmations per chain.

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

For the full list of available settings and best practices, refer to:

  • Creating Widgets Guide

  • Advanced Widget Settings

Customizing the Widget Interface / UX

By default, you can adjust the following UI parameters:

  • Widget Name – A unique name to identify your widget (e.g., “Basic Plan Payment”).

  • Description (Optional) – Short text explaining what this widget is used for.

  • Merchant Name (Optional) – Merchant name displayed to the end user (if applicable).

If further customization is required:

Is required (logos, fonts, colors, layout, etc.), you can override the widget’s CSS.

The merchant (or the PSP on their behalf) can also decide whether to let the end user select the asset & blockchain inside the widget. The widget can always be reviewed in preview mode before going live to ensure it looks and behaves as expected.

(Example widget preview details and images remain as in the original guide.)


Installs Widgets

inabit supports multiple, straightforward implementation methods per widget type. Choose the approach that best fits your stack and UX-each method is intuitive and easy to set up.

Purchase Address Widget (one-time, amount-bound)

Supported methods:

  1. Redirect

  2. API:

A. Redirect-API (hosted flow)

  • How it works: Create a purchase via API → receive a hosted URL → redirect the customer. Full flow.

B. Embedded-API (embedded/open on demand)

Customer Address (persistent address per customer)

Supported methods:

  1. Redirect

  2. iframe

  3. API

A. Redirect (hosted flow):

  • How it works: Create/obtain the Customer Address session or token → redirect the user to the hosted page tied to that customer. Widget implementation guide

B. iframe (embedded hosted UI):

  • How it works: Generate the Customer Address URL (session/token) server-side → embed in an <iframe> in your account page. Widget implementation guide

C. Fully API:

  • How it works: Use inabit’s APIs to create or fetch the customer’s persistent address, show it in your UI, and track status via webhooks. Widget implementation guide


Deposit Management

How Will the PSP Stay Up-to-Date on Incoming Deposits?

In many industries 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 merchant 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.

Best practice for monitoring deposits: use a hybrid of webhooks and API polling for real-time state changes, plus periodic polling as a safety net (e.g., to recover from missed callbacks or network hiccups). See the full guidance here.

To keep the PSP in sync, inabit emits webhook callbacks for each deposit event and any status change, enabling real-time tracking and deterministic, status-based logic within the PSP’s environment.

List of Potential Deposit Statuses:

Purchase Address - only

  • 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.

  • 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.

For both widget types (Purchase Address & Customer Address):

  • 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).

  • Completed – The required number of blockchain confirmations has been received, and the deposit is finalized successfully.

  • PendingFork - Tx confirmed on a forked block; credit on hold until reorg resolves. After settlement, the deposit may complete or fail.

  • Failed - The deposit cannot be credited (e.g., transaction invalid/dropped, double-spent or replaced via RBF to a different address). The payment attempt should be considered unsuccessful.

Get deposit by UUID for merchant:

GET https://api.inabit.biz/v1/merchant/purchase/{{purchaseId}}

(Sample JSON response as in the original guide.)


Withdrawal Process

How Are Withdrawals Handled?

Withdrawals are processed centrally from the Master Wallet, which acts as the secure treasury account for each merchant. 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 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 merchant’s Master Wallet at predefined intervals (e.g., hourly, daily). Refer to our docs to learn more about Gas Fees and Sweeping.

  2. Withdrawal Execution Once the funds are consolidated in the Master Wallet, withdrawals can be initiated. The PSP can trigger a withdrawal using inabit’s APIs or the UI

Creating a Withdrawal via API

Initiate a mutation to create an asset transfer request to send for approval from the Master Wallet.

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

Headers

  • Content-Type: application/json

  • Authorization: Bearer <token>

Body (WithdrawalCreateInput object)

  • wallet.id (String, required) – Master Wallet ID

  • financialAsset.id (String, required) – Asset ID

  • address (String, required) – Destination address (To)

  • amount (Integer, required) – Transfer amount

  • blockchain.id (String, required) – Blockchain ID

  • note (String, optional) – Transaction note

  • priority (String, optional) – Transaction priority (Slow, Medium, Fast, etc.)

Example body:

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

Response

  • id (String) – Withdrawal ID

Real-Time Visibility

inabit provides real-time status updates on withdrawal requests, including initiation, signing, blockchain confirmation, and completion, allowing the psp to reflect up-to-date information within its platform and back office.

To find out how to subscribe to Withdrawal Webhooks, please visit our Webhooks page.

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 withdrawal

Last updated

Was this helpful?