# Introduction

## Introduction

### What is Tylt

Tylt is a crypto-asset infrastructure provider that enables businesses to accept, move, and settle value globally using stablecoins.

Tylt provides APIs and payment rails for:

* Accepting crypto payments (on-chain transfers)
* Executing crypto payouts and transfers
* Converting fiat to crypto and crypto to fiat via local payment methods
* Managing treasury and internal settlement flows

Tylt operates at the crypto transaction layer. All fiat payment processing is handled by regulated third-party partners. Tylt does not hold or safeguard fiat funds.

<figure><img src="https://3025527084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1faQQ9zk1XcGCYD5rVeI%2Fuploads%2FFA8a4FoUQ9hjkNehWEF5%2FWhat%20is%20Tylt.png?alt=media&amp;token=edd8a6c9-898a-452b-8560-f5b57ab42f10" alt=""><figcaption></figcaption></figure>

***

### Why Tylt

Global payments are fragmented across currencies, banking systems, and settlement timelines. Traditional cross-border payment infrastructure often introduces delays, elevated costs, fragmented liquidity, and operational complexity.

Tylt provides a unified settlement layer using stablecoins, enabling businesses to:

* Settle transactions globally in near real-time
* Reduce dependency on correspondent banking networks
* Simplify multi-currency operations
* Access multiple payment and conversion rails through a single API

<figure><img src="https://3025527084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1faQQ9zk1XcGCYD5rVeI%2Fuploads%2FfGzkqmrkJS7c0SjVrB8z%2FWhy%20Tylt.png?alt=media&amp;token=081e1540-8c2c-4e46-80b0-ec15ea1ca4ff" alt=""><figcaption></figcaption></figure>

### Service Stack

Tylt operates across three core infrastructure layers:

#### 1. Payment Layer (Crypto Payments)

Handles the creation and processing of crypto-denominated payment and transfer flows. This includes:

* Deposit address generation
* Payment tracking
* On-chain confirmation handling

***

#### 2. Conversion Layer (Fiat ↔ Crypto)

Enables conversion between fiat and crypto using local payment methods such as:

* PIX (Brazil)
* Open Banking (EUR/GBP)
* QRPH (Philippines)

Settlement is performed in stablecoins, including USDT and USDC.

***

#### 3. Settlement & Treasury Layer

Manages the movement of funds within the Tylt system, including:

* Internal wallet balances
* Merchant ledgering
* Transfers across supported blockchain networks

Fiat funds are processed externally via licensed partners. Tylt operates strictly within the crypto transaction layer.

***

### Who is this for

This documentation is intended for:

* Payment platforms and payment service providers (PSPs) extending into crypto rails
* Marketplaces and fintech applications
* Merchants accepting or sending crypto payments
* Developers building programmable payment infrastructure

Familiarity with REST APIs, webhooks, and payment system design is assumed.

***

### Core Concepts

Understanding the following terms is essential before integrating:

| Term            | Definition                                                                    |
| --------------- | ----------------------------------------------------------------------------- |
| **Instance**    | A transaction session created via API                                         |
| **Trade**       | The lifecycle object representing a transaction through its processing states |
| **Transaction** | A financial movement (credit or debit)                                        |
| **Account**     | A merchant balance within Tylt                                                |

These objects are used consistently across APIs, webhooks, and reporting

***

### Key Integration Principles

#### Event-Driven Architecture

Tylt follows a webhook-first model. All transaction state changes are delivered via webhook callbacks. Integrators are expected to consume and process these events to track transaction lifecycle updates.

***

#### Separation of Fiat and Crypto Layers

Fiat flows are executed via licensed payment partners. Tylt operates exclusively at the crypto transaction and settlement layer and does not process or hold fiat funds.

***

#### Stablecoin-Based Settlement

All settlement and internal accounting are performed using stablecoins, including USDT and USDC..


# Getting Access to Tylt

<figure><img src="https://3025527084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1faQQ9zk1XcGCYD5rVeI%2Fuploads%2FNFbeNdtZJRymoLsWLhlt%2FGetting%20Access%20to%20Tylt.png?alt=media&amp;token=aa65a6d1-7ff1-425b-a250-cf850723d222" alt=""><figcaption></figcaption></figure>

#### Overview

This guide walks you through the steps required to integrate with Tylt, from onboarding to processing your first transaction. Tylt follows a KYB-gated production model with a separate demo environment for integration and testing.

***

#### Merchant Onboarding (KYB)

To access Tylt’s production environment, merchants are required to complete onboarding and Know Your Business (KYB) verification. This process includes the submission of company and operational details, a review of the business model and use case, and a compliance and risk assessment.

Upon successful KYB approval, a production account is created, access to the Tylt Dashboard is enabled, and production API keys are issued.

***

#### Demo Environment (For Integration & Testing)

To enable faster integration, Tylt provides a demo environment for testing and validation. This environment allows merchants to test core services, including Crypto Payments (CPG), Fiat ↔ Crypto (CrossRamp), and swap functionality, while also simulating transaction flows and validating webhook handling.

Depending on the service being tested, some transactions are fully simulated, while others may require coordination with the Tylt team to facilitate controlled test transactions

{% hint style="warning" %}
Please contact the Tylt team to obtain demo account credentials and enable the required services.
{% endhint %}

***

#### Acceptable Use Policy (AUP)

All merchants integrating with Tylt are required to comply with the following Acceptable Use Policy as part of onboarding and continued use of Tylt’s services.

Tylt’s infrastructure may only be used for lawful, ethical, and compliant activities. Merchants must ensure that their business model, transaction flows, and end-user activity adhere to all applicable laws and regulatory requirements.

***

#### **Prohibited Activities**

| Category            | Description                                                                        |
| ------------------- | ---------------------------------------------------------------------------------- |
| Financial Crime     | Money laundering, terrorist financing, or sanctions evasion                        |
| Fraud & Deception   | Fraud, scams, deceptive practices, or misrepresentation                            |
| Unauthorised Use    | Use of stolen or unauthorised funds, accounts, or digital assets                   |
| Unlicensed Services | Provision of unlicensed or illegal financial, investment, or payment services      |
| Misrepresentation   | Concealment or misrepresentation of the source, ownership, or destination of funds |
| Legal Violations    | Any activity that is illegal in the jurisdiction of the merchant or its users      |

***

#### **Restricted Business Categories**

The following categories require explicit written approval from Tylt

| Category                     | Description                                                                     |
| ---------------------------- | ------------------------------------------------------------------------------- |
| Adult Services               | Adult content, escort services, or sexually explicit material                   |
| Gambling                     | Gambling, betting, or lottery services without valid licensing                  |
| Controlled Substances        | Narcotics, controlled substances, or related products                           |
| Weapons                      | Weapons, ammunition, or military-related goods or services                      |
| High-Risk Financial Services | Unregulated forex, brokerage, binary options, or speculative investment schemes |
| Crowdfunding & Political     | Unverified charitable, political, or crowdfunding activities                    |
| Corporate Structures         | Shell companies or opaque ownership structures                                  |
| Privacy Tools                | Mixers, tumblers, or anonymisation services                                     |
| Crypto Speculation           | NFT/token projects primarily used for speculation, wash trading, or obfuscation |

***

#### **Sanctions & Jurisdictional Restrictions**

Tylt does not provide services to individuals, entities, or jurisdictions subject to international sanctions, including those imposed by the European Union, United Nations, United States (OFAC), or the United Kingdom (HMT). Transactions involving high-risk or non-cooperative jurisdictions may be restricted.

***

#### **Merchant Responsibilities**

Merchants are responsible for:

* Providing accurate and complete information during onboarding and ongoing use
* Maintaining up-to-date KYC/KYB and beneficial ownership details
* Cooperating with compliance, audit, and due diligence requests
* Implementing appropriate internal controls to prevent misuse

***

#### **Monitoring & Enforcement**

Tylt monitors transactions and account activity using automated systems and manual review, including blockchain analytics and sanctions screening.

Tylt reserves the right to:

* Suspend, restrict, or terminate access to its services
* Freeze funds pending investigation
* Report suspicious activity to relevant authorities

***


# Generating API Keys

<figure><img src="https://3025527084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1faQQ9zk1XcGCYD5rVeI%2Fuploads%2FHwuqpVhzUEcQ9IANGmGq%2FGenerating%20API%20Keys.png?alt=media&amp;token=f093b877-e85c-48cd-afcc-975aa52fa293" alt=""><figcaption></figcaption></figure>

#### **Introduction**

To use the Tylt API, you must generate a pair of credentials: an API Key and a Secret Key. API credentials are issued per service. Each enabled service has its own unique set of API keys and must be generated separately.

***

#### **Generating API Keys**

1. Navigate to Settings → API Keys in your Tylt Dashboard
2. Select the relevant service
3. Click Generate Key

A new set of credentials will then be issued for that service:

* **API Key:** Used in the `Authorization` header of API requests to identify your account and service.
* **Secret Key:** Used to generate HMAC-SHA256 signatures for request authentication and webhook verification. This key must be kept confidential and must never be exposed in client-side code.

***

#### **Important Notes**

* Each service has its own separate API Key and Secret Key
* API keys are environment-specific (Demo and Production)
* Generating a new key for a service may invalidate the previously issued key for that service
* Secret keys are only visible at the time of creation

***

#### **Storing Your API Keys**

Immediately after generating your API credentials, ensure they are stored securely.

* API and Secret Keys cannot be retrieved after generation
* If lost or compromised, new keys must be regenerated
* Do not store keys in source code or expose them in frontend applications

{% hint style="danger" %}
**Security Requirement:**\
Store API credentials in a secure environment such as a secrets manager or encrypted storage. If you suspect any compromise, regenerate your keys immediately and update all integrations.
{% endhint %}


# Signing API Payloads

<figure><img src="https://3025527084-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F1faQQ9zk1XcGCYD5rVeI%2Fuploads%2Fse9w00SOU5gVtuQSAU0P%2FSigning%20API%20Payloads.png?alt=media&amp;token=24fdf8c7-1d7d-4857-a6d8-d2ca1da3bbf6" alt=""><figcaption></figcaption></figure>

#### Overview

To ensure the security and integrity of API requests, all requests to Tylt must be signed using your API Secret Key. Each request includes a signature generated using HMAC-SHA256, allowing Tylt to verify:

* The authenticity of the request
* That the payload has not been tampered with

***

#### How Signing Works

1. Prepare the request payload
2. Convert the payload into a string
3. Generate a signature using HMAC-SHA256 with your API Secret Key
4. Include the signature in the request headers

***

#### Signature Function

```javascript
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};
```

***

#### Signing a POST Request

For POST requests:

* Convert the request body to a JSON string
* Use the exact same string for:
  * request body
  * signature generation

```javascript
const sendPostRequest = async (url, body) => {
    const raw = JSON.stringify(body);
    const signature = createSignature(apiSecret, raw);
    const headers = {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await axios.post(url, body, { headers });
    return response.data;
};
```

***

#### Signing a GET Request

For GET requests:

* Convert query parameters into a query string
* Use the same query string for signature generation

```javascript
const sendGetRequest = async (url, params) => {
    const raw = new URLSearchParams(params).toString();
    const signature = createSignature(apiSecret, JSON.stringify(params));
    const headers = {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await axios.get(`${url}?${raw}`, { headers });
    return response.data;
};
```

***

### Headers

All requests must include:

| Header            | Description                          |
| ----------------- | ------------------------------------ |
| `X-TLP-APIKEY`    | Your API Key                         |
| `X-TLP-SIGNATURE` | HMAC-SHA256 signature of the request |

***

### Important Rules

* The string used for signature must exactly match the payload sent
* Any difference in formatting, spacing, or encoding will result in signature mismatch
* Always generate signatures on the server side only
* Never expose your API Secret Key in frontend applications

***

### Security Best Practices

* Store API credentials in a secure environment (e.g., secrets manager)
* Rotate keys immediately if compromised
* Restrict API usage to trusted backend systems

***

### **Example Codes**

Here’s how you can sign requests using different programming languages:

{% tabs %}
{% tab title="Common" %}

```javascript
// Common function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};
```

{% endtab %}

{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Function to send a POST request
const sendPostRequest = async (url, body) => {
    const raw = JSON.stringify(body);
    const signature = createSignature(apiSecret, raw);
    const headers = {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await axios.post(url, body, { headers });
    return response.data;
};

// Function to send a GET request
const sendGetRequest = async (url, params) => {
    const raw = new URLSearchParams(params).toString();
    const signature = createSignature(apiSecret, JSON.stringify(params));
    const headers = {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await axios.get(`${url}?${raw}`, { headers });
    return response.data;
};
```

{% endtab %}

{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a POST request
def send_post_request(url, body):
    raw = json.dumps(body, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, raw)
    headers = {
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }
    response = requests.post(url, headers=headers, data=raw)
    return response.json()
    
send_post_request('https://domain.com/path', body = {"orderId":"UUID-order-id"})

# Function to send a GET request
def send_get_request(url, params):
    raw = '&'.join([f"{key}={value}" for key, value in params.items()])
    body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, body_string)
    headers = {
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }
    response = requests.get(f"{url}?{raw}", headers=headers)
    return response.json()
send_get_request('https://domain.com/path',  params = {"orderId":"UUID-order-id"})
```

{% endtab %}

{% tab title="JavaScript" %}

<pre class="language-javascript"><code class="lang-javascript">const crypto = require('crypto');

// Function to send a POST request
const sendPostRequest = async (url, body) => {
    const raw = JSON.stringify(body);
    const signature = createSignature(apiSecret, raw);
    const headers = {
        "Content-Type": "application/json",
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: raw,
    });
    return response.json();
};

// Function to send a GET request
<strong>    const sendGetRequest = async (url, params) => {
</strong>    const raw = new URLSearchParams(params).toString();
    const signature = createSignature(apiSecret, raw);
    const headers = {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature
    };
    const response = await fetch(`${url}?${raw}`, {
        method: 'GET',
        headers: headers,
    });
    return response.json();
};
</code></pre>

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Keep Your Keys Secure**: Always use environment variables or secure storage for sensitive information like your API Secret Key.
* **Regenerate Keys if Compromised**: If your API keys are exposed or compromised, regenerate them immediately and update your secure storage.
  {% endhint %}


# Tylt CrossRamp: Fiat ↔ Crypto Solutions

***

Tylt CrossRamp enables merchants to embed on-ramp and off-ramp functionality within their applications, allowing end users to acquire and dispose of stablecoins using local payment methods. CrossRamp operates as an embedded crypto exchange and transfer layer, enabling merchants to integrate fiat-to-crypto and crypto-to-fiat flows without directly handling fiat processing.

***

#### How It Works

CrossRamp separates fiat and crypto flows:

* End users initiate fiat transactions through supported local payment methods&#x20;
* Tylt facilitates the corresponding crypto-asset conversion and manages the transfer of stablecoins

***

#### Supported Flows

CrossRamp supports two primary interaction flows:

(i) end users acquire stablecoins via the embedded on-ramp and transfer the resulting crypto-assets to the merchant; and&#x20;

(ii) merchants transfer stablecoins to end users, who subsequently convert the received crypto-assets into fiat via supported off-ramp methods.

***

#### Supported Payment Methods

CrossRamp supports region-specific payment methods, including:

* PIX (Brazil)
* Open Banking (EUR / GBP)
* QRPH (Philippines)

***

#### Key Characteristics

* **Embedded crypto exchange layer**\
  Facilitates acquisition and disposal of stablecoins
* **Crypto-native settlement**\
  All balances and settlement occur in stablecoins (e.g., USDT/USDC)
* **Separation of fiat and crypto layers**\
  Fiat transactions are executed by regulated banking and payment partners. Tylt operates exclusively at the crypto layer
* **Unified API integration**\
  Single integration across multiple regions and payment methods
* **Webhook-driven lifecycle**\
  Transaction state updates are delivered via event-driven callback

***

#### Merchant Use Cases

Merchants can use CrossRamp to:

* Facilitate end-user on-ramp flows, where fiat payments are converted into stablecoins via Tylt’s embedded crypto exchange layer and transferred to the merchant
* Facilitate end-user off-ramp flows, where stablecoins are transferred to Tylt, converted into fiat, and paid out to end users via local payment methods
* Integrate local payment rails into a unified crypto settlement and transfer infrastructure

***


# EU (Open Banking):

Tylt CrossRamp enables merchants to embed on-ramp and off-ramp functionality using Open Banking rails across the EU and UK, with settlement in USDC.

CrossRamp operates as an embedded crypto exchange and transfer layer, allowing end users to acquire and dispose of stablecoins via local bank transfers, while merchants receive and manage balances in USDC.

***

#### Low-Code Integration (Open Banking)

Tylt CrossRamp provides a low-code integration for embedding Open Banking-based on-ramp and off-ramp flows within merchant applications.

This approach enables:

* Rapid integration with minimal development effort
* Pre-built payment interface for end-user interaction
* Standardised flows across supported regions
* Integrated compliance stack, including AML, KYC, and Travel Rule requirements
* Reduced implementation complexity for merchants

***

#### Open Banking Settlement Model

CrossRamp enables end users to initiate account-to-account transfers via Open Banking, which are used to facilitate crypto-asset acquisition and disposal flows.

Under the daily settlement model:

* Fiat transactions are completed via Open Banking partners
* Corresponding crypto-asset conversions are performed within Tylt
* Resulting balances are aggregated and settled to the merchant in USDC

Settlement is processed once daily at 2:00 AM UTC, with the merchant’s USDC balance updated accordingly. Merchants may subsequently use their USDC balance for transfers, payouts, or treasury operations.

***

#### Settlement Summary

| Feature                      | Open Banking (EU/UK)                       |
| ---------------------------- | ------------------------------------------ |
| **Settlement Frequency**     | Daily (2:00 AM UTC)                        |
| **Settlement Currency**      | USDC                                       |
| **Fiat Currency (On-Ramp)**  | EUR, GBP                                   |
| **Fiat Currency (Off-Ramp)** | EUR                                        |
| **Payment Method**           | Open Banking (account-to-account transfer) |
| **Integration Type**         | Low-code widget                            |
| **Supported Region**         | EU and UK                                  |


# Open Banking Payin (EUR / GBP → USDC)

This section provides a reference for integrating Tylt CrossRamp’s Open Banking **on-ramp flow** within merchant applications.

Through this integration, end users can initiate account-to-account transfers via Open Banking, which are used to facilitate the acquisition of stablecoins. The resulting USDC is transferred to the merchant’s Tylt wallet.

***

#### Conversion & Settlement Model

1. Each transaction is processed using a **real-time conversion quote**.
2. At the time of initiation, a EUR / GBP → USDC quote is generated. The end user reviews and accepts the quote, following which the transaction is initiated to acquire the corresponding crypto-assets and transfer them to the merchant, based on the provided transaction details.
3. The end user is then prompted to complete a fiat payment via Open Banking through
4. Upon successful completion of the fiat leg, the corresponding crypto-asset conversion is executed, and the resulting USDC is credited to the merchant’s Tylt wallet.
5. Settlement is finalised through a daily reconciliation cycle, ensuring that all transactions are fully reflected in the merchant’s balance no later than **2:30 AM UTC**.

***

#### Settlement Summary

| Attribute               | Description                                                 |
| ----------------------- | ----------------------------------------------------------- |
| **Quote Model**         | Real-time quote per transaction                             |
| **Credit Timing**       | USDC credited upon successful completion of the transaction |
| **Settlement Finality** | Fully reconciled no later than 2:30 AM UTC daily            |
| **Settlement Currency** | USDC                                                        |
| **Destination**         | Merchant Tylt Wallet                                        |

***

#### What You’ll Find in the API Reference

**1. Open Banking On-Ramp Flow**\
Guidance for enabling end users to initiate EUR / GBP bank transfers and complete on-ramp transactions, including tracking transaction lifecycle and status.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and sample requests.

**3. Request & Response Formats**\
Structured JSON examples, parameter definitions, and HTTP status codes for accurate implementation.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other supported languages.

**5. Error Handling**\
Common error scenarios, causes, and recommended handling strategies to ensure reliable integration.

***

### Summary

This API enables merchants to embed Open Banking-based on-ramp functionality, allowing end users to acquire stablecoins via local bank transfers, with settlement managed in USDC through Tylt’s crypto-asset infrastructure.


# Create a Pay-in Instance

This endpoint allows you to create a new payment instance and receive a URL that can be used to launch the Tylt CrossRamp Open Banking Pay-In widget. Through the widget, the merchant's end customer can make a deposit or payment to the merchant using Open Banking. The payment is settled in USDC into the merchants wallet.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payin`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)<br></li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).</p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to deposit in EUR, GBP.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Mandatory. Supported Currency is "EUR" , "GBP" only.</td></tr><tr><td><code>transferType</code></td><td><code>string</code></td><td>Settlement destination. Supported values are <code>"internal"</code> and <code>"external"</code>. Defaults to <code>"internal"</code>.</td></tr><tr><td><code>settlementType</code></td><td><code>string</code></td><td>Settlement schedule. Defaults to <code>"instant"</code>. Other approved values may use the <code>T+N</code> format, such as <code>"T+1"</code></td></tr><tr><td><code>walletDetails</code></td><td><code>object</code></td><td>External wallet address to which the USDC, USDT settlement will be delivered. Required if settlementType is <code>"external"</code></td></tr><tr><td><p><code>walletDetails.address</code></p><p><br></p></td><td><code>string</code></td><td>External wallet address to which the USDC, USDT settlement will be delivered.</td></tr><tr><td><p><code>walletDetails.network</code></p><p><br></p></td><td><code>string</code></td><td>Blockchain network associated with the wallet address, such as <code>"ETH"</code> or <code>"BSC"</code> or  <code>"TRX"</code> or  <code>"POL"</code></td></tr><tr><td><code>merchantDetails</code></td><td><code>JSON Object</code></td><td><p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.<br><br>If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided<br><br>If the integrator is the end merchant, the details of its own business must be provided. <br><br>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong><br>The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong><br>The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong><br>A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.<br><br>Transactions with new <code>merchantDetails</code> go through an automated internal review process. </p></td></tr><tr><td><code>cryptoUi</code></td><td><code>number</code></td><td>Controls the visual mode of the hosted payment widget. Default is <code>1</code>. If set to <code>1</code>, the widget UI is adapted to showcase a crypto purchase flow. If set to <code>0</code>, the widget UI is adapted to showcase a fiat payment flow.</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="Internal Tansfer" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'EUR',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345" 
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Poland",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg"          
<strong>    }
</strong><strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payin', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}

{% tab title="External Transfer" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'EUR',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345" 
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Poland",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg"          
<strong>    },
</strong><strong>    transferType: "external",
</strong>    settlementType: "T+1"
    walletDetails: {
    address:"0x48AF3Bd03E9c707e037a3d8623eEXXXXXXXXXXB3",
    network:"POL"
    }
<strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payin', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Instance created successfully",
  "data": {
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "merchantOrderId": "ivytest1787206071196",
    "url": "https://app.tylt.money/prime-eur-instance/c8439580-1d48-4d47-9a0e-c4a559a35913",
    "userDetails": {
      "email": "s89.510922@gmail.com",
      "firstName": "John",
      "lastName": "Doe",
      "country": "DE",
      "dob": "1990-01-01"
    },
    "merchantDetails": {
      "merchantName": "Test Merchant Store",
      "merchantUrl": "https://teststore.com"
    },
    "fiatAmount": 5,
    "fiatCurrencySymbol": "EUR",
    "cryptoAmount": 5.84,
    "cryptoCurrencySymbol": "USDC",
    "toReleaseAmount": 5.47,
    "fees": 0.37,
    "rate": 0.8564,
    "effectiveRate": 0.9141,
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "cryptoSettlementDetails": {
      "Status": "Pending",
      "hash": "Pending",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "Network": "BSC",
      "transferType": "external",
      "settlementType": "T+1",
      "settlementTime": "Pending"
    }
  }
}

```

{% endtab %}

{% tab title="Response Fields" %}

| Field                                    | Type   | Description                                                                                                                              |
| ---------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `instanceId`                             | String | Unique identifier assigned by Tylt to the Pay-In instance.                                                                               |
| `merchantOrderId`                        | String | Unique order identifier provided by the merchant for transaction identification and reconciliation.                                      |
| `url`                                    | String | URL used to redirect the end user to the Tylt Open Banking Pay-In flow.                                                                  |
| `userDetails`                            | Object | End-user information associated with the transaction. This information is provided by the merchant at the time of user/account creation. |
| `merchantDetails`                        | Object | Merchant information associated with the transaction. This information is provided by the merchant at the time of account creation.      |
| `fiatAmount`                             | Number | Fiat amount to be paid by the end user.                                                                                                  |
| `fiatCurrencySymbol`                     | String | Fiat currency used for the transaction, such as `EUR` or `GBP`.                                                                          |
| `cryptoAmount`                           | Number | Gross crypto amount calculated for the transaction.                                                                                      |
| `cryptoCurrencySymbol`                   | String | Crypto asset applicable to the transaction, such as `USDC` or `USDT`.                                                                    |
| `toReleaseAmount`                        | Number | Net crypto amount to be credited or settled after applicable fees and pricing adjustments.                                               |
| `fees`                                   | Number | Total fees applied to the transaction, expressed in the crypto currency.                                                                 |
| `rate`                                   | Number | Base fiat-to-crypto conversion rate used for the transaction.                                                                            |
| `effectiveRate`                          | Number | Effective conversion rate after applicable fees, spread, or commercial pricing.                                                          |
| `walletDetails`                          | Object | Contains the destination wallet details for transactions requiring an external crypto transfer.                                          |
| `walletDetails.address`                  | String | Destination blockchain wallet address.                                                                                                   |
| `walletDetails.network`                  | String | Blockchain network to be used for the external transfer, such as `BSC`.                                                                  |
| `cryptoSettlementDetails`                | Object | Contains information relating to the crypto settlement of the transaction.                                                               |
| `cryptoSettlementDetails.Status`         | String | Current crypto settlement status, such as `Pending`.                                                                                     |
| `cryptoSettlementDetails.hash`           | String | Blockchain transaction hash. May be `Pending` until the external settlement transaction is initiated or broadcast.                       |
| `cryptoSettlementDetails.address`        | String | Destination wallet address for the crypto settlement.                                                                                    |
| `cryptoSettlementDetails.Network`        | String | Blockchain network used for settlement, such as `BSC`.                                                                                   |
| `cryptoSettlementDetails.transferType`   | String | Determines the settlement destination. `external` indicates transfer to an external wallet; `internal` indicates internal crediting.     |
| `cryptoSettlementDetails.settlementType` | String | Configured settlement schedule, such as `instant` or `T+1`.                                                                              |
| `cryptoSettlementDetails.settlementTime` | String | Settlement completion time or current settlement-time status. May be `Pending` until settlement is completed.                            |
| {% endtab %}                             |        |                                                                                                                                          |
| {% endtabs %}                            |        |                                                                                                                                          |


# Event Status Reference

Each Open Banking Pay-In transaction progresses through a payment lifecycle.

For transactions configured with **external settlement**, successful payment is followed by a separate crypto-settlement lifecycle.

For transactions configured with **internal settlement**, the transaction completes at `Payment Completed` (`eventId: 5`) and no separate settlement events are generated.

The `eventId` identifies the current state of the transaction.

Merchants should use the `eventId` received through webhooks or returned by the transaction-status endpoint as the primary transaction-status indicator.

***

### Event IDs

<table data-header-hidden><thead><tr><th align="right"></th><th></th><th width="128"></th><th></th><th align="center"></th></tr></thead><tbody><tr><td align="right"><code>eventId</code></td><td>Status Key</td><td>Display Text</td><td>Description</td><td align="center">Terminal State</td></tr><tr><td align="right"><code>1</code></td><td><code>created</code></td><td>Instance Created</td><td>The Pay-In instance has been created but the payment flow has not yet started.</td><td align="center">No</td></tr><tr><td align="right"><code>2</code></td><td><code>initiated</code></td><td>Order Created</td><td>The order has been created and the end user can proceed with the Open Banking payment flow.</td><td align="center">No</td></tr><tr><td align="right"><code>3</code></td><td><code>orderProcessing</code></td><td>Order Processing</td><td>The order is being processed and the Open Banking payment instruction is being prepared.</td><td align="center">No</td></tr><tr><td align="right"><code>4</code></td><td><code>paymentProcessing</code></td><td>Payment Processing</td><td>The end user has initiated the Open Banking payment and Tylt is waiting for confirmation from the payment provider.</td><td align="center">No</td></tr><tr><td align="right"><code>5</code></td><td><code>paymentCompleted</code></td><td>Payment Completed</td><td>The fiat payment has been successfully completed. For <code>internal</code> settlement this is the final transaction state. For <code>external</code> settlement the transaction proceeds to crypto settlement.</td><td align="center"><strong>Yes — Internal</strong> / <strong>No — External</strong></td></tr><tr><td align="right"><code>6</code></td><td><code>refundProcessing</code></td><td>Refund Processing</td><td>A refund or return of the fiat payment has been initiated and is awaiting completion.</td><td align="center">No</td></tr><tr><td align="right"><code>7</code></td><td><code>paymentRefunded</code></td><td>Payment Refunded</td><td>The fiat payment has been successfully returned to the sender.</td><td align="center">Yes</td></tr><tr><td align="right"><code>8</code></td><td><code>paymentFailed</code></td><td>Payment Failed</td><td>The payment failed because of a bank, payment-provider or processing error.</td><td align="center">Yes</td></tr><tr><td align="right"><code>9</code></td><td><code>expired</code></td><td>Order Cancelled or Expired</td><td>The order expired or was cancelled before successful payment completion.</td><td align="center">Yes</td></tr><tr><td align="right"><code>10</code></td><td><code>kycFailed</code></td><td>KYC Failed</td><td>The required identity verification failed, expired or was not completed within the permitted period.</td><td align="center">Yes</td></tr><tr><td align="right"><code>11</code></td><td><code>awaitingApprovael</code></td><td>awaiting payout approval</td><td>When <code>autoMerchantApproval</code> is set to 0, the payout pending approval is denoted by eventId 11 </td><td align="center">No</td></tr><tr><td align="right"><code>12</code></td><td><code>settlementInitiated</code></td><td>Settlement Initiated</td><td>External crypto settlement has been initiated following successful fiat payment.</td><td align="center">No — External only</td></tr><tr><td align="right"><code>13</code></td><td><code>settlementCompleted</code></td><td>Settlement Completed</td><td>External crypto settlement has been successfully completed.</td><td align="center">Yes — External only</td></tr><tr><td align="right"><code>14</code></td><td><code>hold</code></td><td>Hold</td><td>An error has occured during the external settlement process. The case will be manually reviewed for resolution. If resolved settlement will reinitiate else refund will be initiated.</td><td align="center">No</td></tr></tbody></table>

***

## Transaction Lifecycle

The lifecycle depends on the transaction's `settlementType`.

### Internal Settlement

Where:

```json
{
  "settlementType": "internal"
}
```

the successful lifecycle is:

```
Instance Created
      ↓
Order Created
      ↓
Order Processing
      ↓
Payment Processing
      ↓
Payment Completed
      ↓
   COMPLETE
```

For an internal-settlement transaction:

* `eventId: 5` is the final successful state.
* No `Settlement Initiated` event is generated.
* No `Settlement Completed` event is generated.
* `eventId: 11` and `eventId: 12` do not apply.
* The corresponding crypto amount is credited internally according to the merchant's configured Tylt settlement arrangement.

***

### External Settlement

Where:

```json
{
  "settlementType": "external"
}
```

the successful lifecycle is:

```
PAYMENT

Instance Created
      ↓
Order Created
      ↓
Order Processing
      ↓
Payment Processing
      ↓
Payment Completed

      ↓

EXTERNAL CRYPTO SETTLEMENT

Settlement Initiated
      ↓
Settlement Completed
      ↓
   COMPLETE
```

For an external-settlement transaction:

* `eventId: 5` confirms completion of the fiat payment.
* `eventId: 5` is not the final transaction state.
* External crypto settlement is processed separately.
* `eventId: 11` confirms that external settlement has started.
* `eventId: 12` confirms final completion of the transaction.

***

## Payment Lifecycle

### 1 — Instance Created

`eventId: 1`

The Open Banking Pay-In instance has been successfully created.

At this stage:

* The transaction exists within Tylt.
* The fiat payment amount has been defined.
* The applicable crypto quote may have been calculated.
* The Open Banking payment has not yet been initiated.
* Settlement has not started.

No fulfilment should occur at this stage.

***

### 2 — Order Created

`eventId: 2`

The Pay-In order has been successfully created.

The end user can proceed with the Open Banking payment flow.

Depending on the payment flow, the end user may now be redirected to or presented with the relevant Open Banking payment interface.

The transaction remains pending.

***

### 3 — Order Processing

`eventId: 3`

The order is currently being processed.

At this stage, Tylt and/or the payment provider may be:

* Preparing the Open Banking payment instruction.
* Establishing the payment session.
* Preparing the bank-selection or authorization flow.
* Performing processing required before the payment can proceed.

The transaction remains pending.

The merchant should continue waiting for the transaction to progress to `Payment Processing`, `Payment Completed` or another applicable event.

***

### 4 — Payment Processing

`eventId: 4`

The end user has initiated the Open Banking payment.

Tylt is waiting for confirmation from the payment provider that the payment has been successfully processed.

The transaction should continue to be treated as pending.

The merchant should not treat the transaction as successfully paid until `Payment Completed` has been received.

***

### 5 — Payment Completed

`eventId: 5`

The fiat payment has been successfully completed.

The meaning of this event depends on the transaction's `settlementType`.

#### Internal Settlement

Where:

```json
{
  "settlementType": "internal"
}
```

`Payment Completed` represents final successful completion of the transaction.

At this stage:

* The Open Banking payment has been successfully completed.
* Payment-side processing has completed.
* The applicable crypto amount has been determined.
* The corresponding crypto amount has been credited internally according to the configured settlement arrangement.
* No separate external blockchain settlement is required.
* No `Settlement Initiated` or `Settlement Completed` events will follow.

For internal settlement, merchants should treat `eventId: 5` as the authoritative final successful status.

***

#### External Settlement

Where:

```json
{
  "settlementType": "external"
}
```

`Payment Completed` confirms completion of the fiat-payment lifecycle only.

At this stage:

* The Open Banking payment has been successfully completed.
* Payment-side processing has completed.
* The applicable crypto amount has been determined.
* The transaction can proceed to external crypto settlement.
* The merchant should not yet treat the complete fiat-to-crypto transaction as settled.

The transaction will subsequently progress to:

```
Settlement Initiated
      ↓
Settlement Completed
```

For external settlement, merchants should wait for `eventId: 12` before treating the full transaction as complete.

***

## Amount and Conversion Information

Where returned by the API, transaction amount and conversion information is available under the `accounts` object.

| Field             | Description                                                               |
| ----------------- | ------------------------------------------------------------------------- |
| `fiatCurrency`    | Fiat currency used for the transaction, such as `EUR` or `GBP`.           |
| `fiatAmount`      | Fiat amount paid by the end user.                                         |
| `cryptoCurrency`  | Crypto asset applicable to the transaction, such as `USDT` or `USDC`.     |
| `cryptoAmount`    | Gross crypto amount calculated for the transaction.                       |
| `toReleaseAmount` | Net crypto amount to be credited or externally settled.                   |
| `rate`            | Base conversion rate used for the transaction.                            |
| `effectiveRate`   | Effective transaction rate after applicable commercial pricing.           |
| `fees`            | Fees applied to the transaction, where applicable.                        |
| `MDR`             | Commercial spread or MDR applicable to the transaction, where applicable. |

The interpretation of `toReleaseAmount` depends on the settlement type:

```
internal
→ Amount credited internally

external
→ Amount to be transferred through external crypto settlement
```

***

## External Settlement Lifecycle

The settlement lifecycle applies **only** where:

```json
{
  "settlementType": "external"
}
```

Following `Payment Completed`, Tylt processes the external transfer of the corresponding USDT or USDC.

The external settlement lifecycle is:

```
Payment Completed
      ↓
Settlement Initiated
      ↓
Settlement Completed
```

***

### 11 — Settlement Initiated

`eventId: 11`

The fiat payment has been successfully completed and external crypto settlement has been initiated.

This state indicates that Tylt has started the external settlement process but settlement has not yet completed.

At this stage:

* The fiat payment is complete.
* The crypto amount to be settled has been determined.
* The external settlement instruction has been initiated.
* The external transfer has not yet reached its final completed state.

The merchant should continue waiting for `Settlement Completed`.

This event does not apply to transactions where:

```json
{
  "settlementType": "internal"
}
```

***

### 12 — Settlement Completed

`eventId: 12`

The external crypto settlement has been successfully completed.

This represents final successful completion of an **external Open Banking Pay-In transaction**.

The USDT or USDC has been transferred to the external wallet address configured for the transaction.

Where applicable, settlement details may include:

| Field     | Description                                            |
| --------- | ------------------------------------------------------ |
| `Status`  | Current crypto-settlement status.                      |
| `hash`    | Blockchain transaction hash for the external transfer. |
| `address` | Destination external wallet address.                   |
| `Network` | Blockchain network used for settlement.                |
| `type`    | Settlement type.                                       |

Merchants should use `eventId: 12` as the authoritative confirmation that external settlement has completed rather than relying solely on the presence of a blockchain transaction hash.

This event does not apply to transactions where:

```json
{
  "settlementType": "internal"
}
```

***

## Settlement Model

The final successful event depends on `settlementType`.

| Settlement Type | Final Successful Event | Final `eventId` |
| --------------- | ---------------------- | --------------: |
| `internal`      | Payment Completed      |             `5` |
| `external`      | Settlement Completed   |            `12` |

Accordingly:

```
INTERNAL

Payment Completed
      ↓
   COMPLETE
```

and:

```
EXTERNAL

Payment Completed
      ↓
Settlement Initiated
      ↓
Settlement Completed
      ↓
   COMPLETE
```

***

## Refund Lifecycle

Where a fiat payment needs to be returned, the transaction enters the refund lifecycle.

```
Refund Processing
      ↓
Payment Refunded
```

A refund may be initiated after payment activity has started or after the payment has completed, depending on the reason for the return and the capabilities of the underlying payment rail.

***

### 6 — Refund Processing

`eventId: 6`

A refund or return of the fiat payment has been initiated and is awaiting completion.

This is not a terminal state.

The merchant should suspend any pending fulfilment and continue monitoring the transaction until the refund has completed.

Where external settlement has not yet occurred, settlement should not proceed.

Where settlement has already occurred, additional reconciliation or recovery procedures may be required separately.

***

### 7 — Payment Refunded

`eventId: 7`

The fiat funds have been successfully returned to the sender.

This is a terminal unsuccessful state for the original Pay-In transaction.

The transaction should not be treated as successfully completed.

***

## Other Terminal States

### 8 — Payment Failed

`eventId: 8`

The Open Banking payment failed because of a bank-side, payment-provider or processing error.

Possible causes may include:

* Bank rejection.
* Payment authorization failure.
* Payment-provider rejection.
* Technical failure.
* Payment-session failure.
* Payment-processing failure.

The transaction should not be fulfilled or settled.

If the end user wishes to try again, a new Pay-In transaction may be required depending on the integration flow.

***

### 9 — Order Cancelled or Expired

`eventId: 9`

The Pay-In order expired or was cancelled before successful payment completion.

This may occur where:

* The end user does not complete the payment within the permitted time.
* The Open Banking payment session expires.
* The end user cancels the transaction.
* The merchant cancels the transaction.
* The payment provider cancels or expires the payment flow.

The transaction should not be fulfilled or settled.

If the end user wishes to try again, a new Pay-In instance should generally be created.

***

### 10 — KYC Failed

`eventId: 10`

The required identity verification failed, expired or was not completed within the permitted period.

The transaction cannot proceed while the required KYC requirements remain unsatisfied.

The transaction should not proceed to payment or settlement unless the end user subsequently completes an approved verification flow and the transaction is permitted to continue.

***

## Hold

### 13 — Hold

`eventId: 13`

The external wallet settlement has been temporarily placed on hold.

A hold may be applied where additional processing, review or information is required before the external wallet settlement can continue.

Examples may include:

* Compliance review.
* Transaction-monitoring review.
* Additional KYC requirements.
* Customer-information requirements.
* Payment investigation.
* Bank or payment-provider review.
* Operational review.
* Settlement review.

`Hold` is **not a terminal state**.

While a transaction is on hold:

* The merchant should not treat the transaction as completed unless it had already reached its applicable final successful state.
* Any pending fulfilment should remain suspended.
* The merchant should continue monitoring webhook updates or query the latest transaction status.
* The transaction may subsequently resume from the appropriate lifecycle stage once the hold is released.

***

## Processing Event Updates

Tylt sends webhook notifications as the transaction progresses through its lifecycle.

The current event is returned under:

```json
{
  "eventDetails": {
    "eventId": 5,
    "description": "Payment Completed"
  }
}
```

Merchants should identify transactions using both the Tylt transaction identifier and the merchant's own order identifier.

For example:

```
data.instanceId
```

and:

```
data.merchantOrderId
```

For external-settlement transactions, settlement-specific information may be returned separately under:

```
data.cryptoSettlementDetails
```

***

## Recommended Merchant Handling

Merchants should:

* Use `eventId` as the primary transaction-status indicator.
* Process webhook notifications idempotently.
* Maintain the latest state for each transaction.
* Match the Tylt transaction identifier and `merchantOrderId` against the merchant's records.
* Treat `Instance Created` as confirmation that the Pay-In transaction has been created only.
* Treat `Order Created` as confirmation that the Open Banking payment flow is available to the end user.
* Treat `Order Processing` as an intermediate processing state.
* Treat `Payment Processing` as confirmation that payment activity is underway but has not yet been finally confirmed.
* Read `settlementType` when determining whether `Payment Completed` is terminal.
* For `settlementType: internal`, treat `Payment Completed` (`eventId: 5`) as final successful completion of the transaction.
* For `settlementType: internal`, do not expect `eventId: 11` or `eventId: 12`.
* For `settlementType: external`, treat `Payment Completed` (`eventId: 5`) as completion of the fiat-payment lifecycle only.
* For `settlementType: external`, wait for `Settlement Completed` (`eventId: 12`) before treating the full transaction as complete.
* Treat `Settlement Initiated` as confirmation that external crypto settlement is underway.
* Treat `Settlement Completed` as final successful completion of an external-settlement transaction.
* Treat `Refund Processing` as a pending return of the fiat funds.
* Treat `Payment Refunded` as final confirmation that the fiat payment has been returned.
* Treat `Payment Failed`, `Order Cancelled or Expired`, `KYC Failed`, and `Payment Refunded` as terminal unsuccessful outcomes.
* Treat `Hold` as a temporary non-terminal state.
* Where applicable, use `accounts.toReleaseAmount` as the net crypto amount to be credited or settled.
* Use `accounts.cryptoCurrency` to identify the applicable crypto asset.
* Use `cryptoSettlementDetails` for external settlement metadata where returned.
* Query the transaction-status endpoint when the latest state needs to be independently verified.

***

## Successful Transaction Summary

### Internal Settlement

For:

```json
{
  "settlementType": "internal"
}
```

the complete successful lifecycle is:

```
OPEN BANKING PAYMENT

Instance Created
      ↓
Order Created
      ↓
Order Processing
      ↓
Payment Processing
      ↓
Payment Completed
      ↓
   COMPLETE
```

Accordingly:

```
Fiat Payment Completed
        +
Internal Crypto Credit Completed
        =
Open Banking Pay-In Complete
```

The final successful event is:

```
eventId: 5
Payment Completed
```

***

### External Settlement

For:

```json
{
  "settlementType": "external"
}
```

the complete successful lifecycle is:

```
OPEN BANKING PAYMENT

Instance Created
      ↓
Order Created
      ↓
Order Processing
      ↓
Payment Processing
      ↓
Payment Completed

────────────────────────

EXTERNAL CRYPTO SETTLEMENT

Settlement Initiated
      ↓
Settlement Completed
      ↓
   COMPLETE
```

Accordingly:

```
Fiat Payment Completed
        +
External USDT / USDC Settlement Completed
        =
Open Banking Pay-In Complete
```

The final successful event is:

```
eventId: 12
Settlement Completed
```

***

## Final Status Logic

Merchants can determine successful completion using the following logic:

```
IF settlementType = internal
    AND eventId = 5
THEN
    Transaction = Complete
```

```
IF settlementType = external
    AND eventId = 12
THEN
    Transaction = Complete
```

For external transactions:

```
eventId = 5
```

means:

```
Payment Complete
Settlement Pending
```

For internal transactions:

```
eventId = 5
```

means:

```
Payment Complete
Transaction Complete
```


# Webhook for Tylt CrossRamp (Pay-in)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:

<table><thead><tr><th width="124.421875">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>Instance Created</td></tr><tr><td><strong><code>2</code></strong></td><td>Order Created</td></tr><tr><td><strong><code>3</code></strong></td><td>Order Processing</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment Processing</td></tr><tr><td><strong><code>5</code></strong></td><td>Payment Completed</td></tr><tr><td><strong><code>6</code></strong></td><td>Refund Processing</td></tr><tr><td><strong><code>7</code></strong></td><td>Payment Refunded</td></tr><tr><td><strong><code>8</code></strong></td><td>Payment Failed</td></tr><tr><td><strong><code>9</code></strong></td><td>Order Cancelled or Expired</td></tr><tr><td><strong><code>10</code></strong></td><td>KYC Failed</td></tr><tr><td><strong><code>11</code></strong></td><td>Settlement Initiated</td></tr><tr><td><strong><code>12</code></strong></td><td>Settlement Completed</td></tr><tr><td><strong><code>13</code></strong></td><td>Hold</td></tr></tbody></table>

1. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
2. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend web-hooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.isBuying == 1) {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 1,
      "description": "Instance Created"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "Pending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "Pending",
      "settlementType": "T+1"
    }
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 2,
      "description": "Order Created"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "Pending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "Pending",
      "settlementType": "T+1"
    }
  }
}

```

{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 3,
      "description": "Order processing"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "Pending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "Pending",
      "settlementType": "T+1"
    }
  }
}

```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 4,
      "description": "Payment processing"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "Pending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "Pending",
      "settlementType": "T+1"
    }
  }
}
```

{% endtab %}

{% tab title="eventId: 5" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 5,
      "description": "Payment Completed"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "Pending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "2026-08-21T00:00:00Z",
      "settlementType": "T+1"
    }
  }
}

```

{% endtab %}

{% tab title="eventId: 12" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 12,
      "description": "Settlement Pending"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "settlementPending",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "2026-08-21T00:00:00Z",
      "settlementType": "T+1"
    }
  }
}

```

{% endtab %}

{% tab title="eventId:13" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.37,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9141,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.47
    },
    "isBuying": 1,
    "instanceId": "c8439580-1d48-4d47-9a0e-c4a559a35913",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 13,
      "description": "Completed"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787206071196",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "0xc8e8df85173d52fc93d97acfc42afa99f84a8fa2fd7d9c83865626fca12ccecb",
      "Status": "completed",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "2026-08-20T06:21:52Z",
      "settlementType": "T+1"
    }
  }
}
```

{% endtab %}

{% tab title="eventId: 14" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.7,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9728,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.14
    },
    "isBuying": 1,
    "instanceId": "9d6b5178-ce35-400a-8dd7-326e01f3d692",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 14,
      "description": "Hold"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787202341649",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "hold",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "2026-08-20T05:11:58Z",
      "settlementType": "T+1"
    }
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

[<mark style="color:green;">**`GET`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  merchantOrderId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/v2/prime-fiat/instance/details??merchantOrderId?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.7,
      "rate": 0.8564,
      "fiatAmount": 5,
      "cryptoAmount": 5.84,
      "fiatCurrency": "EUR",
      "effectiveRate": 0.9728,
      "cryptoCurrency": "USDC",
      "toReleaseAmount": 5.14
    },
    "isBuying": 1,
    "instanceId": "9d6b5178-ce35-400a-8dd7-326e01f3d692",
    "callBackUrl": "https://gaming-demo.web.app/",
    "eventDetails": {
      "eventId": 14,
      "description": "Hold"
    },
    "walletDetails": {
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "network": "BSC"
    },
    "merchantOrderId": "ivytest1787202341649",
    "autoMerchantApproval": 1,
    "cryptoSettlementDetails": {
      "hash": "Pending",
      "Status": "hold",
      "Network": "BSC",
      "address": "0x82e679f09bfd0c28506314dd851e379a083b5094",
      "transferType": "external",
      "settlementTime": "2026-08-20T05:11:58Z",
      "settlementType": "T+1"
    }
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                                    | Type   | Description                                                                                                                              |
| ---------------------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `instanceId`                             | String | Unique identifier assigned by Tylt to the Pay-In instance.                                                                               |
| `merchantOrderId`                        | String | Unique order identifier provided by the merchant for transaction identification and reconciliation.                                      |
| `url`                                    | String | URL used to redirect the end user to the Tylt Open Banking Pay-In flow.                                                                  |
| `userDetails`                            | Object | End-user information associated with the transaction. This information is provided by the merchant at the time of user/account creation. |
| `merchantDetails`                        | Object | Merchant information associated with the transaction. This information is provided by the merchant at the time of account creation.      |
| `fiatAmount`                             | Number | Fiat amount to be paid by the end user.                                                                                                  |
| `fiatCurrencySymbol`                     | String | Fiat currency used for the transaction, such as `EUR` or `GBP`.                                                                          |
| `cryptoAmount`                           | Number | Gross crypto amount calculated for the transaction.                                                                                      |
| `cryptoCurrencySymbol`                   | String | Crypto asset applicable to the transaction, such as `USDC` or `USDT`.                                                                    |
| `toReleaseAmount`                        | Number | Net crypto amount to be credited or settled after applicable fees and pricing adjustments.                                               |
| `fees`                                   | Number | Total fees applied to the transaction, expressed in the crypto currency.                                                                 |
| `rate`                                   | Number | Base fiat-to-crypto conversion rate used for the transaction.                                                                            |
| `effectiveRate`                          | Number | Effective conversion rate after applicable fees, spread, or commercial pricing.                                                          |
| `walletDetails`                          | Object | Contains the destination wallet details for transactions requiring an external crypto transfer.                                          |
| `walletDetails.address`                  | String | Destination blockchain wallet address.                                                                                                   |
| `walletDetails.network`                  | String | Blockchain network to be used for the external transfer, such as `BSC`.                                                                  |
| `cryptoSettlementDetails`                | Object | Contains information relating to the crypto settlement of the transaction.                                                               |
| `cryptoSettlementDetails.Status`         | String | Current crypto settlement status, such as `Pending`.                                                                                     |
| `cryptoSettlementDetails.hash`           | String | Blockchain transaction hash. May be `Pending` until the external settlement transaction is initiated or broadcast.                       |
| `cryptoSettlementDetails.address`        | String | Destination wallet address for the crypto settlement.                                                                                    |
| `cryptoSettlementDetails.Network`        | String | Blockchain network used for settlement, such as `BSC`.                                                                                   |
| `cryptoSettlementDetails.transferType`   | String | Determines the settlement destination. `external` indicates transfer to an external wallet; `internal` indicates internal crediting.     |
| `cryptoSettlementDetails.settlementType` | String | Configured settlement schedule, such as `instant` or `T+1`.                                                                              |
| `cryptoSettlementDetails.settlementTime` | String | Settlement completion time or current settlement-time status. May be `Pending` until settlement is completed.                            |
| {% endtab %}                             |        |                                                                                                                                          |
| {% endtabs %}                            |        |                                                                                                                                          |


# Open Banking Payout (USDC → EUR)

This section provides a reference for integrating Tylt CrossRamp’s Open Banking off-ramp flow within merchant applications.

Through this integration, merchants can initiate transfers of stablecoins (USDC) to end users, who can subsequently convert the received crypto-assets into fiat via Open Banking rails.

{% hint style="warning" %}
Open loop Open-Banking Payouts are only available for EUR currency. Support for GBP will be available shorlty.
{% endhint %}

***

### Conversion & Settlement Model

1. Each transaction is processed using a **real-time conversion quote**.
2. At the time of initiation, a USDC → EUR quote is generated. The merchant initiates a transfer of stablecoins to the end user, who reviews and accepts the off-ramp quote and proceeds with the transaction based on the provided details.
3. The end user then completes the off-ramp flow, following which the corresponding crypto-asset conversion is executed and the resulting fiat amount is made available via SEPA Instant.
4. All transactions are reconciled through a daily settlement cycle, ensuring that balances are fully reflected no later than **2:30 AM UTC**.

***

### Settlement Summary

| Attribute               | Description                                       |
| ----------------------- | ------------------------------------------------- |
| **Quote Model**         | Real-time quote per transaction                   |
| **Debit Timing**        | USDC debited upon initiation of the off-ramp flow |
| **Settlement Finality** | Fully reconciled no later than 2:30 AM UTC daily  |
| **Settlement Currency** | USDC                                              |
| **Source**              | Merchant Tylt Wallet                              |

***

### What You’ll Find in the API Reference

**1. Off-Ramp Flow (USDC → EUR)**\
Guidance for initiating off-ramp flows, including transferring stablecoins to end users and enabling fiat conversion via Open Banking.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and sample requests.

**3. Request & Response Formats**\
Structured JSON examples, parameter definitions, and HTTP status codes for accurate implementation.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other supported languages.

**5. Error Handling**\
Common error scenarios, causes, and recommended handling strategies to ensure reliable integration.

***

### Summary

This API enables merchants to initiate Open Banking-based off-ramp flows, allowing end users to convert stablecoins into fiat via local bank transfers, with all crypto-asset conversion and settlement managed within Tylt’s infrastructure.


# Create a Pay-Out Instance

This endpoint creates a new Open Banking **off-ramp instance** and returns a widget launch URL. The merchant can use this URL to launch the Tylt CrossRamp Open Banking off-ramp widget, where the end user completes the off-ramp flow and receives fiat via Open Banking.

**Flow outcome:**

* The merchant initiates a transfer of USDC to the end user
* The end user completes the off-ramp flow via the hosted widget
* The corresponding fiat amount is made available to the end user via SEPA instant
* The merchant’s USDC balance is debited for the corresponding amount (including applicable fees, if any)

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)<br></li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).<br><br><strong>For Payouts the Reversed Keys are mandatory</strong></p></td></tr><tr><td><code>payeeDetails</code></td><td><code>JSON Object</code></td><td><p>Bank Account Details (Payout Destination)</p><p>Use this object to capture the user’s payout destination bank account—i.e., the bank account where fiat funds will be paid out.</p><p></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>iban</code> (string)<br></li></ul><p><strong>For Payouts the Reversed Keys are mandatory</strong></p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to withdraw in EUR.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Mandatory. Supported Currency is "EUR" only</td></tr><tr><td><code>merchantDetails</code></td><td><code>JSON Object</code></td><td><p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.<br><br>If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided.<br><br>If the integrator is the end merchant, the details of its own business must be provided. <br><br>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong><br>The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong><br>The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong><br>A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.<br><br>Transactions with new <code>merchantDetails</code> go through an automated internal review process. </p></td></tr><tr><td><code>cryptoUi</code></td><td><code>number</code></td><td>Controls the visual mode of the hosted payment widget. Default is <code>1</code>. If set to <code>1</code>, the widget UI is adapted to showcase a crypto purchase flow. If set to <code>0</code>, the widget UI is adapted to showcase a fiat payment flow.</td></tr><tr><td><code>autoMerchantApproval</code></td><td><code>bool</code></td><td><strong>Default: <code>1</code></strong><br><code>1</code> =  Auto-approved; payout processed automatically after customer submission and KYC where applicable<br><code>0</code> = payout queued for merchant approval after customer submission and KYC where applicable. Requires merchant approval via approvePayout to move to processing.</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'EUR',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345"
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Poland",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg",
<strong>    },
</strong><strong>   payeeDetails: {
</strong>            iban: "FR7630006000011234567890185"
    },
    autoMerchantApproval : 0,
<strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Ivy instance created successfully",
  "data": {
    "instanceId": "467153bc-72a8-466d-8fb1-59b080250554",
    "merchantOrderId": "merchant-test-gWsQ1fiLmk",
    "url": "https://app.tylt.money/prime-eur-instance/467153bc-72a8-466d-8fb1-59b080250554",
    "userDetails": {
      "firstName": "Test",
      "lastName": "User",
      "email": "testuser@testemail.com",
      "country": "Poland",
      "dob": "1990-01-01",
      "DocumentType": "Identity Card",
      "DocumentNumber": "426349253ZY8",
      "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
    },
    "payeeDetails": {
      "iban": "FR7630006000011234567890185"
    },
    "merchantDetils":{ 
      "merchantName": "Example Merchant Ltd",
      "merchantUrl": "https://www.examplemerchant.com",
      "merchantInternalId": "merchant-12345"
    },
    "fiatAmount": 4000,
    "fiatCurrencySymbol": "EUR",
    "cryptoAmount": 4686.58,
    "cryptoCurrencySymbol": "USDC",
    "rate": 0.8535
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type   | Description                                                                                    |
| ---------------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `instanceId`           | String | Unique identifier for the  Open Banking payment instance.                                      |
| `merchantOrderId`      | String | Merchant-provided order reference used for internal tracking and reconciliation.               |
| `url`                  | String | Hosted checkout URL where the customer is redirected to complete the EUR Open Banking payment. |
| `userDetails`          | Object | Merchant-supplied customer metadata returned exactly as provided in the request.               |
| `merchantDetails`      | Object | Object containing merchant identification information associated with the transaction.         |
| `payeeDetails`         | Object | Object containing users bank account details where the payment will be made.                   |
| `fiatAmount`           | Number | Amount to be paid by the customer.                                                             |
| `fiatCurrencySymbol`   | String | Fiat currency used in the transaction — always `EUR`.                                          |
| `cryptoAmount`         | Number | Amount of USDC to be debited from the merchant upon successful initiation of the payout.       |
| `cryptoCurrencySymbol` | String | Crypto currency used for settlement — always `USDC`.                                           |
| `rate`                 | Number | EUR → USDC conversion rate applied at the time the quote was generated.                        |
| {% endtab %}           |        |                                                                                                |
| {% endtabs %}          |        |                                                                                                |


# Approve Payout

The Approve Payout endpoint is used by the Merchant to explicitly approve a payout request before it is sent for processing. This step is required only when `autoMerchantApproval = 0`. Once approved, the payout transitions from a pending / queued state to processing, triggering the downstream fiat disbursement.

***

#### When to Use

Call this endpoint when:

* `autoMerchantApproval = 0`
* A payout has been created and is in a **pending / awaiting approval** state
* All required user inputs, KYC (where applicable), and validations are complete

***

#### Flow Context

1. Merchant creates a payout request
2. End user submits required details and completes KYC (if applicable)
3. Payout enters pending approval state
4. Merchant calls `approvePayout` (this endpoint)
5. Payout moves to processing
6. EUR is disbursed to beneficiary via Open Banking rails
7. Merchant’s USDC balance is debited accordingly

#### **Flow outcome:**

* The merchant initiates a transfer of USDC to the end user
* The end user completes the off-ramp flow via the hosted widget
* The corresponding fiat amount is made available to the end user via SEPA instant
* The merchant’s USDC balance is debited for the corresponding amount (including applicable fees, if any)

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout/approve`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>merchantOrderId</code></td><td><code>String</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3' // please use a unique order id per request
}
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout/approve', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Payout instance accepted successfully",
  "data": {}
}
```

{% endtab %}

{% tab title="Response Fields" %}

{% endtab %}
{% endtabs %}


# Disapprove Payout

The Disapprove Payout endpoint is used by the Merchant to explicitly disapprove a payout request before it is sent for processing. This step is required only when `autoMerchantApproval = 0`. Once disapproved, the payout transitions from a pending / queued state to expired state.

***

#### When to Use

Call this endpoint when:

* `autoMerchantApproval = 0`
* A payout has been created and is in a **pending / awaiting approval** state
* All required user inputs, KYC (where applicable), and validations are complete

***

#### Flow Context

1. Merchant creates a payout request
2. End user submits required details and completes KYC (if applicable)
3. Payout enters pending approval state
4. Merchant calls `disapprovePayout` (this endpoint)
5. Payout moves to Expired state

#### **Flow outcome:**

* The merchant disapproves the payout request
* The payout moves to **Expired** state
* The fiat disbursement does not start
* The merchant’s USDC balance remains unchanged

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout/disapprove`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>merchantOrderId</code></td><td><code>String</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3' // please use a unique order id per request
}
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout/disapprove', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Payout instance disapproved successfully",
  "data": {}
}
```

{% endtab %}

{% tab title="Response Fields" %}

{% endtab %}
{% endtabs %}


# Webhook for Tylt CrossRamp (Pay-Out)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:

<table><thead><tr><th width="124.421875">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>Instance Created</td></tr><tr><td><strong><code>2</code></strong></td><td>Order Created</td></tr><tr><td><strong><code>3</code></strong></td><td>Order Processing</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment Processing</td></tr><tr><td><strong><code>5</code></strong></td><td>Payment Completed</td></tr><tr><td><strong><code>8</code></strong></td><td>Payment Failed</td></tr><tr><td><strong><code>9</code></strong></td><td>Order Cancelled or Expired</td></tr><tr><td><strong><code>10</code></strong></td><td>KYC Failed</td></tr><tr><td><strong><code>11</code></strong></td><td>Pending Merchant Final Approval</td></tr></tbody></table>

1. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
2. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend web-hooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.isBuying == 1) {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 1, "description": "Instance Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 2, "description": "Order Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 3, "description": "Order Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 4, "description": "Payment Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 5" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 5, "description": "Payment Completed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId8" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 8, "description": "Order Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 9" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 9, "description": "Order Cancelled or Expired" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 10" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 10, "description": "KYC Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId:11" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 11, "description": "Awaiting Approval" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

[<mark style="color:green;">**`GET`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  merchantOrderId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/v2/prime-fiat/instance/details??merchantOrderId?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
    "msg": "Instance details fetched successfully.",
    "data": {
        "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
        "isBuying": 0,
        "eventId": 4,
        "eventDescription": "Payment Completed",
        "fiatAmount": 30,
        "fiatCurrencySymbol": "EUR",
        "rate": 1.3,
        "cryptoAmount": 39,
        "cryptoCurrencySymbol": "USDC",
        "fees": 0.78,
        "bankStatementReference": "irf482bca625d9a9d",
        "callBackUrl": "https://www.callback.com",
        "redirectUrl": "https://www.google.com",
        "userDetails": {
          "firstName": "Test",
          "lastName": "User",
          "email": "testuser@testemail.com",
          "country": "Poland",
          "dob": "1990-01-01",
          "DocumentType": "Identity Card",
          "DocumentNumber": "426349253ZY8",
          "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
        },
        "payeeDetails": {
          "iban": "FR7630006000011234567890185"
        },
        "merchantDetils":{ 
            "merchantName": "Example Merchant Ltd",
            "merchantUrl": "https://www.examplemerchant.com",
            "merchantInternalId": "merchant-12345"
            },
        "autoMerchantApproval": 1,
        "MDR": 2
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                    | Type   | Description                                                                  |
| ------------------------ | ------ | ---------------------------------------------------------------------------- |
| `instanceId`             | String | Unique identifier for the payment instance.                                  |
| `isBuying`               | Number | Indicates whether the transaction is a Pay-In (`1`) or Pay-Out (`0`).        |
| `eventId`                | Number | Numeric code representing the current transaction lifecycle state.           |
| `eventDescription`       | String | Human-readable description of the transaction status.                        |
| `fiatAmount`             | Number | Amount paid by the customer in fiat currency.                                |
| `fiatCurrencySymbol`     | String | Fiat currency symbol used in the transaction — always `"EUR"`.               |
| `rate`                   | Number | EUR → USDC conversion rate applied for the transaction.                      |
| `cryptoAmount`           | Number | Amount of USDC credited to the merchant after conversion.                    |
| `cryptoCurrencySymbol`   | String | Crypto currency used for settlement — always `"USDC"`.                       |
| `fees`                   | Number | Total fees charged for processing the transaction.                           |
| `bankStatementReference` | String | Unique reference shown in the customer’s bank statement.                     |
| `callBackUrl`            | String | Merchant-configured URL to receive payment or settlement callbacks.          |
| `redirectUrl`            | String | URL used to redirect the customer to complete or authorize the payment.      |
| `userDetails`            | Object | Merchant-defined metadata associated with the customer.                      |
| `merchantDetails`        | Object | Merchant-defined metadata associated with the merchant being paid.           |
| `payeeDetails`           | Object | Object containing users bank account details where the payment will be made. |
| `MDR`                    | Number | Merchant Discount Rate applied to the transaction (percentage).              |
| {% endtab %}             |        |                                                                              |
| {% endtabs %}            |        |                                                                              |


# Canada (Intrac):

## Canada (Interac e-Transfer)

Tylt CrossRamp enables merchants to embed on-ramp functionality for Canadian end users through Interac e-Transfer, with settlement in USDC/ USDT.

CrossRamp operates as an embedded crypto exchange and transfer layer, allowing end users to acquire stablecoins using local CAD payment rails while merchants or end-users receive and manage balances in USDC/ USDT.

### Low-Code Integration

Tylt CrossRamp provides a low-code integration for embedding Interac e-Transfer-based on-ramp flows within merchant applications.

This approach enables:

* Rapid integration with minimal development effort
* A pre-built payment interface for end-user interaction
* A standardised CAD on-ramp flow
* Integrated compliance controls, including AML, KYC and Travel Rule requirements
* Real-time transaction-status updates
* Reduced implementation complexity for merchants

### Interac e-Transfer Settlement Model

CrossRamp enables end users to initiate CAD payments through Interac e-Transfer. These payments are used to facilitate the acquisition of crypto-assets through Tylt.

Under the settlement model:

* The merchant creates a CAD pay-in instance through the Tylt API.
* The end user receives and completes an Interac e-Transfer payment request.
* The fiat payment is processed through Tylt’s Canadian payment partner.
* The corresponding crypto-asset conversion is performed within Tylt.
* The resulting USDC, USDT is credited to the merchant’s Tylt wallet or transferred to the end-users approved external wallet, where enabled.

Settlement timing is based on the merchant’s approved configuration. Supported settlement options may include instant settlement or an approved `T+N` settlement schedule, such as `T+1`.

Merchants and end-users may subsequently use their USDC, USDT balance for transfers, payouts, settlement or treasury operations.

### Settlement Summary

| Feature                       | Interac e-Transfer — Canada             |
| ----------------------------- | --------------------------------------- |
| Settlement frequency          | Instant or approved `T+N` schedule      |
| Settlement currency           | USDC, USDT                              |
| Fiat currency                 | CAD                                     |
| Transaction type              | On-ramp                                 |
| Payment method                | Interac e-Transfer                      |
| Integration type              | Low-code hosted payment flow            |
| Settlement destination        | Tylt wallet or approved external wallet |
| Supported region              | Canada                                  |
| Transaction notifications     | Signed webhook notifications            |
| Transaction verification      | Get Instance Information endpoint       |
| Successful transaction status | `eventId: 5` — Payment Completed        |

This can also be tightened further to match the exact length and formatting of the EU/UK GitBook page.


# Canada Interac e-Transfer On-Ramp

This section provides a reference for integrating Tylt CrossRamp’s Canada Interac e-Transfer on-ramp flow within merchant applications.

Through this integration, end users can initiate payments in Canadian dollars through Interac e-Transfer. These payments are used to facilitate the acquisition of stablecoins, with the resulting USDC/USDT settled to the merchant’s Tylt wallet or, where enabled, to an approved external wallet.

### Conversion and Settlement Model

Each transaction is processed using a real-time conversion quote.

At the time the pay-in instance is created, a CAD-to-USDC/USDT quote is generated. The end user reviews the applicable transaction details and proceeds with the Interac e-Transfer payment request.

The end user is then prompted to complete the CAD payment through their supported Canadian financial institution.

Once the fiat payment has been successfully received and confirmed, the corresponding crypto-asset conversion is completed. The resulting USDC/USDT is then credited according to the merchant’s configured settlement method.

Settlement may be completed:

* Internally, by crediting the merchant’s Tylt wallet; or
* Externally, by transferring USDC/USDT to an approved wallet address and supported blockchain network.

The applicable settlement timing is determined by the merchant’s approved configuration. Supported settlement types may include instant settlement or a permitted `T+N` settlement schedule, such as `T+1`.

### Settlement Summary

| Item                         | Description                                                         |
| ---------------------------- | ------------------------------------------------------------------- |
| Fiat currency                | CAD                                                                 |
| Payment method               | Interac e-Transfer                                                  |
| Settlement asset             | USDC/USDT                                                           |
| Conversion rate              | Real-time CAD-to-USDC/USDT quote                                    |
| Internal settlement          | USDC/USDT credited to the merchant’s Tylt wallet                    |
| External settlement          | USDC/USDT transferred to an approved external wallet, where enabled |
| Settlement timing            | Instant or an approved `T+N` settlement schedule                    |
| Transaction notifications    | Signed webhook notifications                                        |
| Transaction verification     | Get Instance Information endpoint                                   |
| Successful transaction state | `eventId: 5` — Payment Completed                                    |

### What You’ll Find in the API Reference

#### 1. Interac e-Transfer On-Ramp Flow

Guidance for enabling end users to initiate CAD payments through Interac e-Transfer and complete on-ramp transactions, including the creation of payment instances and the tracking of transaction status.

#### 2. Endpoint Descriptions

Detailed specifications for all API endpoints, including request parameters, authentication requirements, signing requirements and sample requests.

#### 3. Request and Response Formats

Structured JSON examples, field definitions and response formats to support accurate implementation.

#### 4. Authentication and Signing

Guidance for authenticating merchant requests using the Tylt API Key and generating HMAC-SHA256 signatures using the merchant’s API Secret Key.

#### 5. Code Examples

Reference implementations in Node.js, Python and other supported languages for creating transactions, retrieving transaction information and validating webhook signatures.

#### 6. Webhooks and Transaction Status

Guidance for receiving signed transaction-status notifications, validating webhook signatures and processing lifecycle events idempotently.

#### 7. Error Handling

Common error scenarios, possible causes and recommended handling strategies to support a reliable integration.

### Summary

This API enables merchants to embed an Interac e-Transfer-based on-ramp flow within their applications.

End users can initiate payments in CAD through their Canadian financial institution, following which the corresponding stablecoins are acquired and settled in USDC , USDT through Tylt’s crypto-asset infrastructure.

The integration supports real-time quotes, hosted payment flows, signed status webhooks, transaction-status retrieval and configurable internal or external settlement.


# Create a Pay-in Instance

This endpoint creates a CAD pay-in instance and returns a unique URL for the Tylt-hosted Interac e-Transfer payment flow.

Depending on the selected flow, the merchant may either redirect the customer to the hosted payment URL or provide the required customer information when creating the instance.

***

### Endpoint

```html
POST https://api.tylt.money/v2/prime-fiat/cad/instance/payin
```

***

### Authentication

All merchant-initiated API requests must include:

| Header            | Type   | Required | Description                                                                                              |
| ----------------- | ------ | -------: | -------------------------------------------------------------------------------------------------------- |
| `Content-Type`    | string |      Yes | Must be `application/json`.                                                                              |
| `X-TLP-APIKEY`    | string |      Yes | JWT-based API key issued by Tylt. The authenticated user and merchant are resolved from this credential. |
| `X-TLP-SIGNATURE` | string |      Yes | HMAC-SHA256 signature generated from the exact JSON request body using the API Secret Key.               |

The API Key and API Secret Key are provided during onboarding. The API Secret Key must remain confidential and must never be exposed in frontend or client-side code.

***

### Signing the Request

The request body must be signed using HMAC-SHA256.

#### Signing Process

1. Construct the request-body object.
2. Convert the object into a JSON string using `JSON.stringify()` or an equivalent compact JSON encoder.
3. Generate an HMAC-SHA256 digest using the API Secret Key.
4. Encode the digest as a lowercase hexadecimal string.
5. Include the generated signature in the `X-TLP-SIGNATURE` header.
6. Send the exact JSON string used to generate the signature.

```
signature = HMAC-SHA256(
    API_SECRET_KEY,
    JSON.stringify(requestBody)
)
```

> The JSON string used to generate the signature must be identical to the request body sent to Tylt. Changes to spacing, field order, encoding or serialisation after signing may cause signature validation to fail.

***

### Request Body

| Field                   | Type    |    Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ----------------------- | ------- | ----------: | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `currencySymbol`        | string  |         Yes | Fiat currency symbol. Must be `"CAD"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `cryptoCurrencySymbol`  | string  |          No | Crypto Asset Symbol that is being purchased. Must be USDT, USDC                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `amount`                | number  |         Yes | Amount the customer will pay in CAD.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `merchantOrderId`       | string  |         Yes | Unique transaction reference generated by the merchant.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `callBackUrl`           | string  |         Yes | HTTPS endpoint that will receive transaction-status webhooks.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `redirectUrl`           | string  |         Yes | URL to which the customer will be redirected after the hosted payment flow.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `merchantDetails`       | object  |         Yes | <p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. </p><p></p><p>This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.</p><p></p><p> If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided If the integrator is the end merchant, the details of its own business must be provided.</p><p></p><p>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong> The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong> The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong> A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.</p> |
| `isMerchantOnRecord`    | boolean |          No | Set to `true` when operating under an approved Merchant on Record arrangement.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `userDetails`           | object  |          No | <p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>countryOfBirth</code> </li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)</li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).<br><br>Use <em>ISO 3166-1 alpha-3</em> three-letter country codes </p><p><br><strong>If</strong> <code>autoAcceptTrade</code><br><strong>is set to 1, the Reserved Keys need to be populated.</strong></p>                                                                                                                                                            |
| `userDetails.dob`       | string  | Conditional | Customer’s date of birth in `YYYY-MM-DD` format.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `autoAcceptTrade`       | number  |          No | Set to `1` to automatically accept the instance and initiate the Interac e-Transfer request.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `transferType`          | string  |          No | Settlement destination. Supported values are `"internal"` and `"external"`. Defaults to `"internal"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |
| `walletDetails`         | object  | Conditional | Required when `transferType` is `"external"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `walletDetails.address` | string  | Conditional | External wallet address to which the USDC, USDT settlement will be delivered.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `walletDetails.network` | string  | Conditional | Blockchain network associated with the wallet address, such as `"ETH"` or `"SOL"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `settlementType`        | string  |          No | Settlement schedule. Defaults to `"instant"`. Other approved values may use the `T+N` format, such as `"T+1"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |

> In this API, `autoAcceptTrade` means that Tylt automatically accepts the pay-in instance and initiates the Interac e-Transfer request. It does not refer to the customer’s bank-level Interac AutoAcceptTrade settings.

***

### JavaScript Example

```javascript
const crypto = require("crypto");

const apiKey = process.env.TYLT_API_KEY;
const apiSecret = process.env.TYLT_API_SECRET;

const requestBody = {
  currencySymbol: "CAD",
  amount: 250.00,
  merchantOrderId: "ORD-2026-001",
  cryptoCurrencySymbol: "USDC",
  callBackUrl: "https://merchant.example/webhooks/tylt/cad",
  redirectUrl: "https://merchant.example/payments/return",
  merchantDetails: {
    merchantName: "Acme Corp",
    merchantUrl: "https://merchant.example",
    merchantInternalId: "MUID-001"
  },
  userDetails: {
    firstName: "John",
    lastName: "Doe",
    email: "john@example.com",
    country: "CAN",
    countryOfBirth: "CAN",
    dob: "1990-05-15"
  },
  autoAcceptTrade: 1,
  transferType: "internal",
  settlementType: "instant"
};

// Sign and send the exact same JSON string.
const rawBody = JSON.stringify(requestBody);

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(rawBody)
  .digest("hex");

const response = await fetch(
  "https://api.tylt.money/v2/prime-fiat/cad/instance/payin",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature
    },
    body: rawBody
  }
);

const result = await response.json();
console.log(result);
```

***

### Successful Response

{% tabs %}
{% tab title="200" %}

#### Scenario A: Standard Pay-In Request (Without Auto-Accept)

This is the standard response when initializing a payment session where the user will be redirected to the Tylt payment portal. the user will be redirected to the Tylt payment portal.

```json
{
  "status": 200,
  "msg": "Instance created successfully",
  "data": {
    "instanceId": "8f3b2cd1-49fa-11ed-bdca-0a58a9feac02",
    "url": "https://exchange.tylt.money/review/cad/8f3b2cd1-49fa-11ed-bdca-0a58a9feac02",
    "ReferenceNumber": null,
    "TransactionNumber": null,
    "interacUrl": null,
    "userDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "email": "johndoe@example.com"
    },
    "merchantDetails": {
      "customerPlatformId": "user123"
    },
    "fiatAmount": 100.0,
    "fiatCurrencySymbol": "CAD",
    "cryptoAmount": 65.5,
    "cryptoCurrencySymbol": "USDC",
    "merchantOrderId": "ORDER-999238",
    "rate": 1.4975
  }
}
```

{% endtab %}
{% endtabs %}

When `autoAcceptTrade` is not set to `1`, `ReferenceNumber` and `TransactionNumber` may initially be `null`. These values are populated after the Interac payment request is initiated.

***

### Response Fields

| **Field**                                 | **Type**       | **Description**                                                                                                          |
| ----------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `status`                                  | number         | HTTP-style response status code returned by Tylt. A value of `200` indicates that the instance was created successfully. |
| `msg`                                     | string         | Human-readable message describing the result of the API request.                                                         |
| `data`                                    | object         | Object containing the newly created pay-in instance details.                                                             |
| `data.instanceId`                         | string         | Unique identifier generated by Tylt for the pay-in instance.                                                             |
| `data.url`                                | string         | Tylt-hosted customer payment URL used to review and continue the Interac payment flow.                                   |
| `data.ReferenceNumber`                    | string or null | Interac reference number assigned after the payment request is initiated. Returns `null` before initiation.              |
| `data.TransactionNumber`                  | string or null | External payment provider transaction number. Returns `null` until assigned by the provider.                             |
| `data.interacUrl`                         | string or null | Interac-hosted payment request URL. Returns `null` until the Interac payment request has been generated.                 |
| `data.userDetails`                        | object         | Customer details associated with the transaction.                                                                        |
| `data.userDetails.firstName`              | string         | Customer's first name.                                                                                                   |
| `data.userDetails.lastName`               | string         | Customer's last name.                                                                                                    |
| `data.userDetails.email`                  | string         | Customer's email address.                                                                                                |
| `data.merchantDetails`                    | object         | Merchant-specific information associated with the transaction.                                                           |
| `data.merchantDetails.customerPlatformId` | string         | Merchant-defined identifier for the customer on the merchant's platform.                                                 |
| `data.fiatAmount`                         | number         | Amount to be paid by the customer in fiat currency.                                                                      |
| `data.fiatCurrencySymbol`                 | string         | Fiat currency symbol. For the Canada Interac flow, this is `"CAD"`.                                                      |
| `data.cryptoAmount`                       | number         | Calculated cryptocurrency amount to be settled for the transaction.                                                      |
| `data.cryptoCurrencySymbol`               | string         | Cryptocurrency used for settlement, such as `"USDC"`.                                                                    |
| `data.merchantOrderId`                    | string         | Unique transaction reference supplied by the merchant.                                                                   |
| `data.rate`                               | number         | Base exchange rate applied to the transaction.                                                                           |
| `data.effectiveRate`                      | number         | Effective exchange rate applied after incorporating applicable pricing, fees, or spread.                                 |

***


# Event Status Reference

Each Canada Interac e-Transfer on-ramp transaction progresses through two connected lifecycle stages:

1. **Payment Processing** — the end user completes the CAD payment through Interac e-Transfer.
2. **Crypto Settlement** — following successful payment, Tylt settles the corresponding USDT or USDC according to the transaction’s configured settlement method.

The `eventId` identifies the current state of the transaction.

Merchants should use the `eventId` received through webhooks or returned by the **Get Instance Information** endpoint as the primary transaction-status indicator.

***

### Event IDs

| `eventId` | Status Key            | Display Text               | Description                                                                                                                                              | Terminal State |
| --------: | --------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- | :------------: |
|       `1` | `created`             | Instance Created           | The payment instance has been created but has not yet been accepted.                                                                                     |       No       |
|       `2` | `initiated`           | Order Created              | The instance has been accepted and the Interac e-Transfer payment request has been initiated.                                                            |       No       |
|       `3` | `paymentProcessing`   | Payment Processing         | The customer has initiated the Interac e-Transfer payment, and Tylt is waiting for confirmation from the payment provider.                               |       No       |
|       `4` | `paymentFulfilled`    | Payment Fulfilled          | The customer has completed the Interac e-Transfer payment. Tylt has received confirmation and is completing final processing before settlement.          |       No       |
|       `5` | `paymentCompleted`    | Payment Completed          | The Interac e-Transfer payment has been successfully received and payment processing is complete. The transaction will now proceed to crypto settlement. |       Yes      |
|       `6` | `settlementPending`   | Settlement Pending         | The payment has been completed, but settlement to the merchant is still pending.                                                                         |       No       |
|       `7` | `settlementCompleted` | Settlement Complete        | The payment has been successfully settled according to the merchant’s configured settlement method.                                                      |       Yes      |
|       `8` | `failed`              | Payment Failed             | The payment failed because of a provider-side or processing error.                                                                                       |       Yes      |
|       `9` | `expired`             | Order Cancelled or Expired | The instance expired or was cancelled before successful completion.                                                                                      |       Yes      |
|      `10` | `refundInitiated`     | Refund Initiated           | A refund or return has been initiated with the payment provider and is awaiting completion.                                                              |       No       |
|      `11` | `refundCompleted`     | Refund Completed           | The funds have been successfully returned to the sender.                                                                                                 |       Yes      |
|      `12` | `kyc_failed`          | KYC Failed                 | The required identity verification failed, expired, or was not completed within the permitted time.                                                      |       Yes      |

***

## Transaction Lifecycle

A successful Canada Interac on-ramp consists of a **payment lifecycle followed by a settlement lifecycle**.

```
PAYMENT

Instance Created
      ↓
Order Created
      ↓
Payment Processing
      ↓
Payment Fulfilled
      ↓
Payment Completed

      ↓

SETTLEMENT

Settlement Pending
      ↓
Settlement Complete
```

Settlement is processed separately from the Interac payment regardless of whether the merchant is configured for instant settlement or another permitted settlement schedule.

For an instant-settlement configuration, the transition from `Payment Completed` through `Settlement Pending` to `Settlement Complete` may occur very quickly.

***

## Payment Lifecycle

### 1 — Instance Created

`eventId: 1`

The pay-in instance has been successfully created.

At this stage:

* The transaction exists within Tylt.
* The CAD payment amount has been defined.
* The applicable crypto quote has been calculated.
* The Interac payment has not yet been completed.
* Crypto settlement has not started.

No fulfilment should occur at this stage.

***

### 2 — Order Created

`eventId: 2`

The instance has been accepted, the end user KYC for the transaction is sufficient and the Interac e-Transfer payment request has been initiated.&#x20;

The end user can proceed with the payment through their Canadian financial institution.

The transaction remains pending.

***

### 3 — Payment Processing

`eventId: 3`

Awaitng the the end user to initiated the Interac e-Transfer payment. Tylt is waiting for confirmation from the payment provider that the payment has been successfully received.

The transaction should continue to be treated as pending.

***

### 4 — Payment Fulfilled

`eventId: 4`

The end user has completed the Interac e-Transfer payment and Tylt has received confirmation from the payment provider.

Tylt is completing the remaining payment-side processing before marking the payment as completed.

This remains an intermediate state.

***

### 5 — Payment Completed

`eventId: 5`

The CAD payment lifecycle has been successfully completed.

At this stage:

* The Interac payment has been received.
* Payment-side processing has completed.
* The applicable crypto amount has been determined.
* The transaction can proceed into the separate crypto-settlement process.

The relevant amount and conversion information is returned in the `accounts` object.

| Field             | Description                                                        |
| ----------------- | ------------------------------------------------------------------ |
| `fiatCurrency`    | Fiat currency used for the transaction. For Canada, this is `CAD`. |
| `fiatAmount`      | CAD amount paid by the end user.                                   |
| `cryptoCurrency`  | Settlement asset, such as `USDT` or `USDC`.                        |
| `cryptoAmount`    | Gross crypto amount calculated for the transaction.                |
| `toReleaseAmount` | Net crypto amount to be released during settlement.                |
| `rate`            | Base conversion rate used for the transaction.                     |
| `effectiveRate`   | Effective transaction rate after applicable commercial pricing.    |
| `fees`            | Fees applied to the transaction expressed in cryptoCrrency         |
| `MDR`             | The spread applicable on the transaction expressed in percentage.  |

> `Payment Completed` confirms completion of the **payment process**. Crypto settlement is processed separately and should be tracked through the settlement events.

***

## Settlement Lifecycle

Following `Payment Completed`, Tylt processes settlement of the corresponding USDT or USDC amount.

Settlement is a separate process regardless of whether the configured settlement timing is instant or another permitted settlement schedule.

The amount being settled is represented by:

```
accounts.toReleaseAmount
```

and the settlement asset is represented by:

```
accounts.cryptoCurrency
```

***

### 6 — Settlement Pending

`eventId: 6`

The CAD payment has been successfully completed and the crypto settlement is now pending.

This state indicates that the stablecoin settlement process has started but has not yet completed.

For an instant-settlement transaction, this state may be short-lived.

The merchant should continue waiting for `Settlement Complete` before treating the crypto settlement as final.

***

### 7 — Settlement Complete

`eventId: 7`

The crypto settlement has been successfully completed.

This represents final completion of the **full Canada Interac on-ramp transaction**.

The settlement destination depends on the transaction’s `transferType`.

#### Internal Settlement

Where:

```json
{
  "type": "internal"
}
```

the USDT or USDC is credited to the **merchant’s Tylt wallet**.

No external blockchain transfer is required, and therefore fields such as `hash` or external wallet `address` may be `null`.

#### External Settlement

Where:

```json
{
  "type": "external"
}
```

the USDT or USDC is transferred to the **end user’s external wallet address** supplied for the transaction.

The settlement details may include:

| Field     | Description                                                              |
| --------- | ------------------------------------------------------------------------ |
| `Status`  | Current crypto-settlement status.                                        |
| `hash`    | Blockchain transaction hash for the external transfer, where applicable. |
| `address` | End user’s destination wallet address.                                   |
| `Network` | Blockchain network used for settlement.                                  |
| `type`    | Settlement type: `internal` or `external`.                               |

Merchants should use `eventId: 7` as the authoritative confirmation that settlement has completed rather than relying solely on the presence of a blockchain transaction hash.

***

## Settlement Model

The settlement destination is determined by `transferType`.

| Transfer Type | Settlement Destination     |
| ------------- | -------------------------- |
| `internal`    | Merchant’s Tylt wallet     |
| `external`    | End user’s external wallet |

The settlement asset may be either **USDT or USDC**, depending on the transaction and merchant configuration.

Settlement timing may be instant or follow another settlement schedule enabled for the merchant; however, the underlying lifecycle remains:

```
Payment Completed
      ↓
Settlement Pending
      ↓
Settlement Complete
```

***

## Refund Lifecycle

Where a transaction requires the CAD payment to be returned, it enters the refund lifecycle.

```
Refund Initiated
      ↓
Refund Completed
```

A refund may be initiated after the payment has been initiated, fulfilled, or completed, depending on the reason for the return.

***

### 10 — Refund Initiated

`eventId: 10`

A refund or return has been initiated with the payment provider and is awaiting completion.

This is not a terminal state.

The merchant should suspend any pending fulfilment and continue monitoring the transaction until the refund has completed.

***

### 11 — Refund Completed

`eventId: 11`

The CAD funds have been successfully returned to the sender.

This is a terminal unsuccessful state for the original on-ramp transaction.

The transaction should not be treated as successfully settled.

***

## Other Terminal States

### 8 — Payment Failed

`eventId: 8`

The payment failed because of a provider-side or processing error.

The transaction should not be fulfilled or settled.

***

### 9 — Order Cancelled or Expired

`eventId: 9`

The pay-in instance expired or was cancelled before successful completion.

If the end user wishes to try again, a new pay-in instance should be created.

***

### 12 — KYC Failed

`eventId: 12`

The required identity verification failed, expired, or was not completed within the permitted period.

The transaction cannot proceed unless the end user subsequently completes an approved verification flow.

***

## Processing Event Updates

Tylt sends webhook notifications as the transaction progresses through its lifecycle.

The current event is returned under:

```json
{
  "eventDetails": {
    "eventId": 6,
    "description": "Settlement Pending"
  }
}
```

Merchants should identify transactions using both:

```
data.instanceId
```

and:

```
data.merchantOrderId
```

Settlement-specific information is returned separately under:

```
data.cryptoSettlementDetails
```

***

### Recommended Merchant Handling

Merchants should:

* Use `eventId` as the primary transaction-status indicator.
* Process webhook notifications idempotently.
* Maintain the latest state for each `instanceId`.
* Match both `instanceId` and `merchantOrderId` against the merchant’s records.
* Treat `Payment Fulfilled` as confirmation that the end user’s Interac payment has been confirmed but payment-side processing is still completing.
* Treat `Payment Completed` as completion of the CAD payment lifecycle.
* Treat `Settlement Pending` as confirmation that the separate crypto-settlement process is underway.
* Treat `Settlement Complete` as final completion of the full CAD → USDT/USDC transaction.
* For `internal` transactions, expect settlement to the merchant’s Tylt wallet.
* For `external` transactions, expect settlement to the end user’s external wallet.
* Use `accounts.toReleaseAmount` as the net stablecoin amount to be settled.
* Use `accounts.cryptoCurrency` to identify whether settlement is in USDT or USDC.
* Use `cryptoSettlementDetails` for additional settlement metadata.
* Use the **Get Instance Information** endpoint when the latest transaction state needs to be independently verified.

***

## Successful Transaction Summary

The complete successful lifecycle is:

```
INTERAC PAYMENT

Instance Created
      ↓
Order Created
      ↓
Payment Processing
      ↓
Payment Fulfilled
      ↓
Payment Completed

────────────────────────

CRYPTO SETTLEMENT

Settlement Pending
      ↓
Settlement Complete
```

The final settlement destination is:

```
internal → Merchant Tylt Wallet

external → End User External Wallet
```

Accordingly, for the complete on-ramp transaction:

```
CAD Payment Completed
        +
USDT / USDC Settlement Complete
        =
Canada Interac On-Ramp Complete
```


# Webhook for Tylt CrossRamp (Pay-in)

***

### Overview

Tylt sends real-time transaction-status notifications to the `callBackUrl` supplied when the CAD pay-in instance is created.

A webhook is sent whenever the payment instance moves from one lifecycle state to another.

The webhook should be used as the primary mechanism for receiving transaction updates. Merchants may use the Get Instance Information endpoint to independently confirm the latest transaction status.

***

### Setting Up the Webhook

#### 1. Create a Callback Endpoint

The merchant must provide a publicly accessible HTTPS endpoint that:

* Accepts HTTP `POST` requests.
* Accepts a JSON request body.
* Preserves the original raw request body.
* Validates the `X-TLP-SIGNATURE` header.
* Processes each status update idempotently.
* Returns HTTP status `200` with the text `ok` in the response body.

#### 2. Submit the Callback URL

Include the callback endpoint in the `callBackUrl` field when creating the pay-in instance.

```json
{
  "callBackUrl": "https://merchant.example/webhooks/tylt/cad"
}
```

#### 3. Process Status Updates

Each webhook contains an `eventId` identifying the latest transaction state.

The merchant should perform customer crediting, order fulfilment or other irreversible actions only after receiving and validating `eventId: 5`.

***

### Webhook Headers

| Header            | Description                                                                                          |
| ----------------- | ---------------------------------------------------------------------------------------------------- |
| `Content-Type`    | `application/json`                                                                                   |
| `X-TLP-SIGNATURE` | HMAC-SHA256 signature generated from the exact raw webhook body using the merchant’s API Secret Key. |
| `sign`            | Legacy signature header retained for compatibility.                                                  |

***

### Webhook Reponses ( Event Id: 1 through Event Id: 12)

{% tabs %}
{% tab title="Event Id:1" %}

#### **1. Instance Created (eventId: 1)**

Triggered when a payment instance is created. The step initiates the payment and settlement flow.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": null,
    "eventDetails": {
      "eventId": 1,
      "description": "Instance Created"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:2" %}

#### **2. Order Created / Payment Pending (eventId: 2)**

Triggered with an interac payment link is generated and the payment is pending.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 2,
      "description": "Order Created / Payment Pending"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:3" %}

#### &#x20;**Payment Processing (eventId: 3)**

Triggered when the payment is initiated by the end-user and the payment is under processing.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 3,
      "description": "Payment Processing"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:4 " %}

#### **4. Payment Fulfilled (eventId: 4)**

Triggered when the payment is initiated by the end-user and the status is fullfiled. This status is not an intermediate step and does not signify completed or finality of the fiat payment.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 4,
      "description": "Payment Fulfilled"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:5" %}

#### **5. Payment Completed (eventId: 5)**

Triggered when the fiat payment by the end-user has been completed and settled.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 5,
      "description": "Payment Completed"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:6" %}

#### **6. Settlement Pending (eventId: 6)**

Triggered when the fiat payment is completed and the on-chain settlement to the end-user wallet has been initiated. This process is triggered only at the settlement Time (T+1 etc) is elapsed.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 6,
      "description": "Settlement Pending"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "settlementPending",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

<br>
{% endtab %}

{% tab title="Event Id:7" %}

#### **7. Settlement Completed (eventId: 7)**

Triggered directly via internal withdrawal sequences dispensing crypto natively. `hash` attaches.

```json
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 7,
      "description": "Settlement Completed"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "settlementCompleted",
      "hash": "0x4fb812c3b88b7bc2d...",
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:8" %}

#### **8. Payment Failed (eventId: 8)**

Triggered if the payment process fails or the settlement process fails.&#x20;

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 8,
      "description": "Payment Failed / Declined"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "failed",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id:9" %}
**9. Order Expired (eventId: 9)**

Triggered when the Interac Payment Link expires due to non payment by the end-user. The link expires 48 hours after issuance.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 9,
      "description": "Order Expired"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "expired",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id: 10" %}

#### **10. Refund Initiated (eventId: 10)**

Triggered actively when a manual admin refund is iniated.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 10,
      "description": "Refund Initiated"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "refundInitiated",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id: 11" %}
**11. Refund Completed (eventId: 11)**

Hook triggers directly upon verifying the Interac refund securely reaching the user.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 11,
      "description": "Refund Completed"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "refunded",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}

{% tab title="Event Id 12" %}

#### **12. KYC Failed (eventId: 12)**

Strictly triggered when the KYC processor natively responds with a formal rejection on the ID tier mappings for the specific instance user trace.

```json
{
  "data": {
    "instanceId": "992a5752-89ad-4ef6-af6e-67bd858ef1d7",
    "isBuying": 1,
    "callBackUrl": "https://dev-api.tylt.money/common/postback",
    "merchantOrderId": "cadtest1786097846972",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA1XyzRef&src=email",
    "eventDetails": {
      "eventId": 12,
      "description": "KYC Failed"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 1000,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 712.25,
      "toReleaseAmount": 710.43,
      "effectiveRate": 1.4975,
      "rate": 1.4042,
      "fees": 1.82,
      "MDR": 6
    },
    "cryptoSettlementDetails": {
      "Status": "kycFailed",
      "hash": null,
      "address": "0xDestinationWallet123",
      "Network": "TPNK",
      "type": "external"
    }
  }
}
```

{% endtab %}
{% endtabs %}

***

### Webhook Fields

| Field                                  | Type           | Description                                                                                                                                |
| -------------------------------------- | -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `data.instanceId`                      | string         | Unique pay-in instance identifier generated by Tylt.                                                                                       |
| `data.isBuying`                        | number         | Indicates transaction direction. `1` represents a pay-in / on-ramp transaction.                                                            |
| `data.callBackUrl`                     | string         | Callback URL configured for receiving transaction-status webhooks.                                                                         |
| `data.merchantOrderId`                 | string         | Unique transaction reference supplied by the merchant.                                                                                     |
| `data.interacUrl`                      | string or null | Interac payment URL associated with the transaction, where applicable. May be `null` before the Interac request is generated.              |
| `data.eventDetails`                    | object         | Current transaction lifecycle information.                                                                                                 |
| `data.eventDetails.eventId`            | number         | Numeric identifier representing the current transaction state.                                                                             |
| `data.eventDetails.description`        | string         | Human-readable description of the current transaction state.                                                                               |
| `data.accounts`                        | object         | Fiat, crypto, rate, fee and settlement-amount details for the transaction.                                                                 |
| `data.accounts.fiatCurrency`           | string         | Fiat currency used for the transaction. For Canada pay-ins, this is `CAD`.                                                                 |
| `data.accounts.fiatAmount`             | number         | Amount paid or to be paid by the end user in CAD.                                                                                          |
| `data.accounts.cryptoCurrency`         | string         | Crypto-asset used for settlement, such as `USDC` or `USDT`.                                                                                |
| `data.accounts.cryptoAmount`           | number         | Gross crypto amount calculated from the fiat amount using the applicable conversion rate.                                                  |
| `data.accounts.toReleaseAmount`        | number         | Net crypto amount to be released or credited after applicable fees and transaction adjustments.                                            |
| `data.accounts.effectiveRate`          | number         | Effective conversion rate applicable after incorporating the commercial pricing or spread applied to the transaction.                      |
| `data.accounts.rate`                   | number         | Base CAD-to-crypto conversion rate used for the transaction calculation.                                                                   |
| `data.accounts.fees`                   | number         | Total transaction fees applied to the transaction, expressed in the settlement asset unless otherwise configured.                          |
| `data.accounts.MDR`                    | number         | Merchant Discount Rate applied to the transaction.                                                                                         |
| `data.cryptoSettlementDetails`         | object         | Details relating to settlement of the crypto asset.                                                                                        |
| `data.cryptoSettlementDetails.Status`  | string or null | Current crypto settlement status. May be `null` before settlement is initiated.                                                            |
| `data.cryptoSettlementDetails.hash`    | string or null | Blockchain transaction hash for external settlement. `null` for transactions not yet settled or where no on-chain transaction is required. |
| `data.cryptoSettlementDetails.address` | string or null | Destination wallet address for external settlement. May be `null` for internal settlement.                                                 |
| `data.cryptoSettlementDetails.Network` | string or null | Blockchain or internal network identifier associated with settlement.                                                                      |
| `data.cryptoSettlementDetails.type`    | string         | Settlement type. Typically `internal` or `external`.                                                                                       |

***

### Validating the Webhook Signature

Tylt signs the exact raw JSON webhook body using HMAC-SHA256 and the merchant’s API Secret Key.

```
expectedSignature = HMAC-SHA256(
    API_SECRET_KEY,
    RAW_WEBHOOK_BODY
)
```

The resulting lowercase hexadecimal digest is sent in the `X-TLP-SIGNATURE` header.

The merchant must:

1. Read the exact raw request body.
2. Generate an HMAC-SHA256 signature using the API Secret Key.
3. Compare the generated signature with `X-TLP-SIGNATURE`.
4. Use a constant-time comparison.
5. Reject the webhook when the signatures do not match.
6. Parse and process the JSON only after successful validation.

> Do not parse and re-serialise the JSON before generating the signature. Changes to spacing, field order or encoding may change the calculated signature.

***

### Node.js Webhook Example

```javascript
const crypto = require("crypto");
const express = require("express");

const app = express();
const apiSecret = process.env.TYLT_API_SECRET;

// Preserve the exact raw body.
app.use(express.raw({ type: "application/json" }));

app.post("/webhooks/tylt/cad", (req, res) => {
  const receivedSignature =
    req.headers["x-tlp-signature"] || "";

  const expectedSignature = crypto
    .createHmac("sha256", apiSecret)
    .update(req.body)
    .digest("hex");

  const receivedBuffer = Buffer.from(
    receivedSignature,
    "utf8"
  );

  const expectedBuffer = Buffer.from(
    expectedSignature,
    "utf8"
  );

  const signatureIsValid =
    receivedBuffer.length === expectedBuffer.length &&
    crypto.timingSafeEqual(
      receivedBuffer,
      expectedBuffer
    );

  if (!signatureIsValid) {
    return res
      .status(400)
      .send("Invalid HMAC signature");
  }

  const webhook = JSON.parse(
    req.body.toString("utf8")
  );

  const {
    instanceId,
    merchantOrderId,
    eventDetails
  } = webhook.data;

  // Store and process the event idempotently.
  console.log({
    instanceId,
    merchantOrderId,
    eventId: eventDetails.eventId
  });

  return res.status(200).send("ok");
});

app.listen(3000, () => {
  console.log("Webhook server running");
});
```

***

### Acknowledging the Webhook

After successfully validating and recording the webhook, return:

```http
HTTP/1.1 200 OK
Content-Type: text/plain
```

```
ok
```

The callback is acknowledged only when Tylt receives HTTP status `200` and the response body `ok`.

Webhooks are not automatically retried when an acknowledgement is not received. Missed webhooks may be manually resent through the Tylt dashboard.

***

### Webhook Processing Requirements

* Always validate `X-TLP-SIGNATURE`.
* Match the `instanceId` and `merchantOrderId` against the merchant’s records.
* Store and process webhook events idempotently.
* Do not assume that every intermediate event will always be received.
* Do not credit the customer based on an intermediate status.
* Treat `eventId: 5` (Payment Completed),`eventId: 6` (Settlement Pending), and`eventId: 7` (Settlement Completed)as successful states. `7` is the ultimate terminal success state.
* Treat event IDs`8` (Failed), `9` (Expired), `10` (Refund Initiated), and `12` (KYC Failed)as terminal unsuccessful states.
* Use the Get Instance Information endpoint to verify an uncertain or missing status.
* Store the webhook body, signature, event ID, processing result and timestamp for reconciliation.


# Get Instance Information

This endpoint retrieves the latest information for a CAD pay-in instance.

The authenticated `userId` and `merchantId` are resolved from the JWT-based API key. They must not be included in the query parameters.

The merchant may retrieve an instance using either:

* The merchant-generated `merchantOrderId`; or
* The Tylt-generated `instanceId`.

Using `merchantOrderId` is recommended because it corresponds to the unique reference generated by the merchant when the pay-in instance was created.

***

### Endpoint

#### Retrieve by Merchant Order ID

```http
GET https://api.tylt.money/v2/prime-fiat/cad/instance/details?merchantOrderId=<MERCHANT_ORDER_ID>
```

#### Retrieve by Instance ID

```http
GET https://api.tylt.money/v2/prime-fiat/cad/instance/details?instanceId=<INSTANCE_ID>
```

***

### Authentication

| Header            | Type   | Required | Description                                                                                               |
| ----------------- | ------ | -------: | --------------------------------------------------------------------------------------------------------- |
| `X-TLP-APIKEY`    | string |      Yes | JWT-based API key issued by Tylt. The authenticated user and merchant are resolved from this credential.  |
| `X-TLP-SIGNATURE` | string |      Yes | HMAC-SHA256 signature generated from the JSON-serialised query-parameter object using the API Secret Key. |

***

### Signing a GET Request

For a GET request, construct an object containing the query parameters included in the request.

#### Example Using `merchantOrderId`

```javascript
const params = {
  merchantOrderId: "ORD-2026-001"
};
```

Convert the object into a JSON string:

```javascript
const signaturePayload = JSON.stringify(params);
```

The value signed is:

```json
{"merchantOrderId":"ORD-2026-001"}
```

Generate the signature:

```
signature = HMAC-SHA256(
    API_SECRET_KEY,
    JSON.stringify(params)
)
```

The resulting lowercase hexadecimal digest must be submitted in the `X-TLP-SIGNATURE` header.

The query parameters used to generate the signature must be identical to the query parameters sent in the request URL.

***

### Query Parameters

| Field             | Type   |    Required | Description                                                                       |
| ----------------- | ------ | ----------: | --------------------------------------------------------------------------------- |
| `merchantOrderId` | string | Conditional | Unique transaction reference supplied by the merchant when creating the instance. |
| `instanceId`      | string | Conditional | Unique instance identifier generated and returned by Tylt.                        |

Submit either `merchantOrderId` or `instanceId`.

***

### JavaScript Example

```javascript
const crypto = require("crypto");

const apiKey = process.env.TYLT_API_KEY;
const apiSecret = process.env.TYLT_API_SECRET;

const params = {
  merchantOrderId: "ORD-2026-001"
};

const signaturePayload = JSON.stringify(params);

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(signaturePayload)
  .digest("hex");

const queryString = new URLSearchParams(
  params
).toString();

const response = await fetch(
  `https://api.tylt.money/v2/prime-fiat/cad/instance/details?${queryString}`,
  {
    method: "GET",
    headers: {
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature
    }
  }
);

const result = await response.json();
console.log(result);
```

### Example Request

```http
GET https://api.tylt.money/v2/prime-fiat/cad/instance/details?merchantOrderId=ORD-2026-001
X-TLP-APIKEY: <YOUR_API_KEY>
X-TLP-SIGNATURE: <GENERATED_HMAC_SHA256_SIGNATURE>
```

***

### Successful Response

#### `200 OK`

{% tabs %}
{% tab title="External" %}

```json
{
  "status": 200,
  "msg": "Instance details fetched successfully.",
  "data": {
    "instanceId": "8f3b2cd1-49fa-11ed-bdca-0a58a9feac02",
    "isBuying": 1,
    "merchantOrderId": "ORDER-999238",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA3L9X21B&src=email",
    "eventDetails": {
      "eventId": 7,
      "description": "Settlement Completed"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 100.0,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 66.7,
      "toReleaseAmount": 65.5,
      "effectiveRate": 1.4975,
      "rate": 1.4975,
      "fees": 1.2,
      "MDR": 0.01
    },
    "cryptoSettlementDetails": {
      "Status": "Settlement Completed",
      "hash": "0x349bf29...",
      "address": "0xYourConsumerWalletAddress...",
      "Network": "TPNK",
      "type": "external",
      "settlementDate": "T+1",
      "settlementTime": "2026-08-11T12:00:00Z"
    },
    "callBackUrl": "https://webhook.yourplatform.com/notify",
    "redirectUrl": "https://app.yourplatform.com/success",
    "userDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "email": "johndoe@example.com"
    },
    "merchantDetails": {
      "internalPlatformId": "acc-998"
    },
    "ReferenceNumber": "CA3L9X21B",
    "TransactionNumber": "9876543210",
    "expiresAt": "2026-08-10T12:00:00Z",
    "kycStatus": "APPROVED",
    "kycDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "DOB": "1990-01-01",
      "countryOfResidence": "CA",
      "email": "johndoe@example.com",
      "amlStatus": "approved"
    }
  }
}
```

{% endtab %}

{% tab title="Internal" %}

```json
{
  "status": 200,
  "msg": "Instance details fetched successfully.",
  "data": {
    "instanceId": "8f3b2cd1-49fa-11ed-bdca-0a58a9feac02",
    "isBuying": 1,
    "merchantOrderId": "ORDER-999238",
    "interacUrl": "https://gateway-web.fit.interac.ca/acceptPaymentRequest.do?rID=CA3L9X21B&src=email",
    "eventDetails": {
      "eventId": 2,
      "description": "Order Created / Payment Pending"
    },
    "accounts": {
      "fiatCurrency": "CAD",
      "fiatAmount": 100.0,
      "cryptoCurrency": "USDC",
      "cryptoAmount": 66.7,
      "toReleaseAmount": 65.5,
      "effectiveRate": 1.4975,
      "rate": 1.4975,
      "fees": 1.2,
      "MDR": 0.01
    },
    "cryptoSettlementDetails": {
      "Status": null,
      "hash": null,
      "address": null,
      "Network": "TPNK",
      "type": "internal",
      "settlementDate": "T+1",
      "settlementTime": null
    },
    "callBackUrl": "https://webhook.yourplatform.com/notify",
    "redirectUrl": "https://app.yourplatform.com/success",
    "userDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "email": "johndoe@example.com"
    },
    "merchantDetails": {
      "internalPlatformId": "acc-998"
    },
    "ReferenceNumber": "CA3L9X21B",
    "TransactionNumber": "9876543210",
    "expiresAt": "2026-08-10T12:00:00Z",
    "kycStatus": "APPROVED",
    "kycDetails": {
      "firstName": "John",
      "lastName": "Doe",
      "DOB": "1990-01-01",
      "countryOfResidence": "CA",
      "email": "johndoe@example.com",
      "amlStatus": "approved"
    }
  }
}
```

{% endtab %}
{% endtabs %}

***

### Response Fields

| **Field**                                     | **Type**       | **Description**                                                                                                                                            |
| --------------------------------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `status`                                      | number         | HTTP-style response status code returned by Tylt. A value of `200` indicates a successful request.                                                         |
| `msg`                                         | string         | Human-readable message describing the result of the API request.                                                                                           |
| `data`                                        | object         | Object containing the payment instance details.                                                                                                            |
| `data.instanceId`                             | string         | Unique identifier generated by Tylt for the payment instance.                                                                                              |
| `data.isBuying`                               | number         | Indicates the transaction direction. A value of `1` represents a pay-in / crypto purchase transaction.                                                     |
| `data.merchantOrderId`                        | string         | Unique transaction reference supplied by the merchant when creating the payment instance.                                                                  |
| `data.interacUrl`                             | string         | Hosted Interac e-Transfer payment request URL that the customer uses to complete the payment.                                                              |
| `data.eventDetails`                           | object         | Object containing the current lifecycle status of the transaction.                                                                                         |
| `data.eventDetails.eventId`                   | number         | Numeric code representing the current transaction lifecycle state.                                                                                         |
| `data.eventDetails.description`               | string         | Human-readable description of the current transaction status.                                                                                              |
| `data.accounts`                               | object         | Object containing the fiat, crypto, rate, and fee details for the transaction.                                                                             |
| `data.accounts.fiatCurrency`                  | string         | Fiat currency used for the transaction. For the Canada Interac flow, this is `CAD`.                                                                        |
| `data.accounts.fiatAmount`                    | number         | Amount payable or paid by the customer in fiat currency.                                                                                                   |
| `data.accounts.cryptoCurrency`                | string         | Cryptocurrency used for the purchase or settlement, such as `USDC`.                                                                                        |
| `data.accounts.cryptoAmount`                  | number         | Gross cryptocurrency amount calculated for the transaction before applicable deductions.                                                                   |
| `data.accounts.toReleaseAmount`               | number         | Net cryptocurrency amount to be released or settled after applicable fees or deductions.                                                                   |
| `data.accounts.effectiveRate`                 | number         | Effective fiat-to-crypto conversion rate after applying the transaction pricing logic.                                                                     |
| `data.accounts.rate`                          | number         | Exchange rate applied to calculate the cryptocurrency amount.                                                                                              |
| `data.accounts.fees`                          | number         | Total transaction fees recorded for the transaction.                                                                                                       |
| `data.accounts.MDR`                           | number         | Merchant Discount Rate applied to the transaction.                                                                                                         |
| `data.cryptoSettlementDetails`                | object         | Object containing details of the cryptocurrency settlement associated with the transaction.                                                                |
| `data.cryptoSettlementDetails.Status`         | string         | Current status of the cryptocurrency settlement.                                                                                                           |
| `data.cryptoSettlementDetails.hash`           | string or null | Blockchain transaction hash for an external on-chain settlement. May be `null` or unavailable until the transaction is broadcast.                          |
| `data.cryptoSettlementDetails.address`        | string or null | Destination wallet address to which the cryptocurrency is settled for an external transfer.                                                                |
| `data.cryptoSettlementDetails.Network`        | string         | Blockchain network used for the cryptocurrency settlement.                                                                                                 |
| `data.cryptoSettlementDetails.type`           | string         | Settlement type. `external` represents settlement to an external wallet address; `internal` represents settlement to an internal Tylt or merchant balance. |
| `data.cryptoSettlementDetails.settlementDate` | string         | Settlement schedule or settlement convention applicable to the transaction, for example `T+1`.                                                             |
| `data.cryptoSettlementDetails.settlementTime` | string or null | Actual or scheduled settlement timestamp in ISO 8601 format.                                                                                               |
| `data.callBackUrl`                            | string         | Merchant endpoint configured to receive webhook notifications for transaction status changes.                                                              |
| `data.redirectUrl`                            | string         | URL to which the customer is redirected after completing the hosted payment flow.                                                                          |
| `data.userDetails`                            | object         | Object containing customer information associated with the transaction.                                                                                    |
| `data.userDetails.firstName`                  | string         | Customer's first name.                                                                                                                                     |
| `data.userDetails.lastName`                   | string         | Customer's last name.                                                                                                                                      |
| `data.userDetails.email`                      | string         | Customer's email address.                                                                                                                                  |
| `data.merchantDetails`                        | object         | Object containing merchant-specific information associated with the transaction.                                                                           |
| `data.merchantDetails.internalPlatformId`     | string         | Merchant-defined internal identifier associated with the customer, account, wallet, or transaction.                                                        |
| `data.ReferenceNumber`                        | string or null | Interac reference number assigned to the payment request after it is initiated.                                                                            |
| `data.TransactionNumber`                      | string or null | External payment provider's transaction identifier.                                                                                                        |
| `data.expiresAt`                              | string         | Expiry timestamp for the payment instance in ISO 8601 format.                                                                                              |
| `data.kycStatus`                              | string         | Current KYC status of the customer associated with the transaction, for example `APPROVED`.                                                                |
| `data.kycDetails`                             | object         | Object containing KYC and AML information associated with the customer.                                                                                    |
| `data.kycDetails.firstName`                   | string         | First name recorded as part of the customer's verified KYC information.                                                                                    |
| `data.kycDetails.lastName`                    | string         | Last name recorded as part of the customer's verified KYC information.                                                                                     |
| `data.kycDetails.DOB`                         | string         | Customer's date of birth in `YYYY-MM-DD` format.                                                                                                           |
| `data.kycDetails.countryOfResidence`          | string         | Customer's country of residence, represented using the ISO 3166-1 alpha-2 country code.                                                                    |
| `data.kycDetails.email`                       | string         | Email address associated with the customer's KYC profile.                                                                                                  |
| `data.kycDetails.amlStatus`                   | string         | Current AML screening status for the customer, for example `approved`.                                                                                     |

The `eventId` should be used to determine the current transaction state.


# Open Banking Payout (USDC → EUR)

<figure><img src="https://content.gitbook.com/content/1faQQ9zk1XcGCYD5rVeI/blobs/gN5s6Efpc0RzMzugs1dt/Tylt%20Prime%20API.png" alt=""><figcaption></figcaption></figure>

This section provides a reference for integrating Tylt CrossRamp’s Open Banking off-ramp flow within merchant applications.

Through this integration, merchants can initiate transfers of stablecoins (USDC) to end users, who can subsequently convert the received crypto-assets into fiat via Open Banking rails.

{% hint style="warning" %}
Open loop Open-Banking Payouts are only available for EUR currency. Support for GBP will be available shorlty.
{% endhint %}

***

### Conversion & Settlement Model

1. Each transaction is processed using a **real-time conversion quote**.
2. At the time of initiation, a USDC → EUR quote is generated. The merchant initiates a transfer of stablecoins to the end user, who reviews and accepts the off-ramp quote and proceeds with the transaction based on the provided details.
3. The end user then completes the off-ramp flow, following which the corresponding crypto-asset conversion is executed and the resulting fiat amount is made available via SEPA Instant.
4. All transactions are reconciled through a daily settlement cycle, ensuring that balances are fully reflected no later than **2:30 AM UTC**.

***

### Settlement Summary

| Attribute               | Description                                       |
| ----------------------- | ------------------------------------------------- |
| **Quote Model**         | Real-time quote per transaction                   |
| **Debit Timing**        | USDC debited upon initiation of the off-ramp flow |
| **Settlement Finality** | Fully reconciled no later than 2:30 AM UTC daily  |
| **Settlement Currency** | USDC                                              |
| **Source**              | Merchant Tylt Wallet                              |

***

### What You’ll Find in the API Reference

**1. Off-Ramp Flow (USDC → EUR)**\
Guidance for initiating off-ramp flows, including transferring stablecoins to end users and enabling fiat conversion via Open Banking.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and sample requests.

**3. Request & Response Formats**\
Structured JSON examples, parameter definitions, and HTTP status codes for accurate implementation.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other supported languages.

**5. Error Handling**\
Common error scenarios, causes, and recommended handling strategies to ensure reliable integration.

***

### Summary

This API enables merchants to initiate Open Banking-based off-ramp flows, allowing end users to convert stablecoins into fiat via local bank transfers, with all crypto-asset conversion and settlement managed within Tylt’s infrastructure.


# Create a Pay-Out Instance

This endpoint creates a new Open Banking **off-ramp instance** and returns a widget launch URL. The merchant can use this URL to launch the Tylt CrossRamp Open Banking off-ramp widget, where the end user completes the off-ramp flow and receives fiat via Open Banking.

**Flow outcome:**

* The merchant initiates a transfer of USDC to the end user
* The end user completes the off-ramp flow via the hosted widget
* The corresponding fiat amount is made available to the end user via SEPA instant
* The merchant’s USDC balance is debited for the corresponding amount (including applicable fees, if any)

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)<br></li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).</p></td></tr><tr><td><code>payeeDetails</code></td><td><code>JSON Object</code></td><td><p>Bank Account Details (Payout Destination)</p><p>Use this object to capture the user’s payout destination bank account—i.e., the bank account where fiat funds will be paid out.</p><p></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>iban</code> (string)</li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).</p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to withdraw in EUR.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Mandatory. Supported Currency is "EUR" only</td></tr><tr><td><code>merchantDetails</code></td><td><code>JSON Object</code></td><td><p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.<br><br>If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided.<br><br>If the integrator is the end merchant, the details of its own business must be provided. <br><br>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong><br>The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong><br>The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong><br>A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.<br><br>Transactions with new <code>merchantDetails</code> go through an automated internal review process. </p></td></tr><tr><td><code>cryptoUi</code></td><td><code>number</code></td><td>Controls the visual mode of the hosted payment widget. Default is <code>1</code>. If set to <code>1</code>, the widget UI is adapted to showcase a crypto purchase flow. If set to <code>0</code>, the widget UI is adapted to showcase a fiat payment flow.</td></tr><tr><td><code>autoMerchantApproval</code></td><td><code>bool</code></td><td><strong>Default: <code>1</code></strong><br><code>1</code> =  Auto-approved; payout processed automatically after customer submission and KYC where applicable<br><code>0</code> = payout queued for merchant approval after customer submission and KYC where applicable. Requires merchant approval via approvePayout to move to processing.</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'EUR',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345"
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Poland",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg",
<strong>    },
</strong><strong>   payeeDetails: {
</strong>            iban: "FR7630006000011234567890185"
    },
    autoMerchantApproval : 0,
<strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Ivy instance created successfully",
  "data": {
    "instanceId": "467153bc-72a8-466d-8fb1-59b080250554",
    "merchantOrderId": "merchant-test-gWsQ1fiLmk",
    "url": "https://app.tylt.money/prime-eur-instance/467153bc-72a8-466d-8fb1-59b080250554",
    "userDetails": {
      "firstName": "Test",
      "lastName": "User",
      "email": "testuser@testemail.com",
      "country": "Poland",
      "dob": "1990-01-01",
      "DocumentType": "Identity Card",
      "DocumentNumber": "426349253ZY8",
      "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
    },
    "payeeDetails": {
      "iban": "FR7630006000011234567890185"
    },
    "merchantDetils":{ 
      "merchantName": "Example Merchant Ltd",
      "merchantUrl": "https://www.examplemerchant.com",
      "merchantInternalId": "merchant-12345"
    },
    "fiatAmount": 4000,
    "fiatCurrencySymbol": "EUR",
    "cryptoAmount": 4686.58,
    "cryptoCurrencySymbol": "USDC",
    "rate": 0.8535
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type   | Description                                                                                    |
| ---------------------- | ------ | ---------------------------------------------------------------------------------------------- |
| `instanceId`           | String | Unique identifier for the  Open Banking payment instance.                                      |
| `merchantOrderId`      | String | Merchant-provided order reference used for internal tracking and reconciliation.               |
| `url`                  | String | Hosted checkout URL where the customer is redirected to complete the EUR Open Banking payment. |
| `userDetails`          | Object | Merchant-supplied customer metadata returned exactly as provided in the request.               |
| `merchantDetails`      | Object | Object containing merchant identification information associated with the transaction.         |
| `payeeDetails`         | Object | Object containing users bank account details where the payment will be made.                   |
| `fiatAmount`           | Number | Amount to be paid by the customer.                                                             |
| `fiatCurrencySymbol`   | String | Fiat currency used in the transaction — always `EUR`.                                          |
| `cryptoAmount`         | Number | Amount of USDC to be debited from the merchant upon successful initiation of the payout.       |
| `cryptoCurrencySymbol` | String | Crypto currency used for settlement — always `USDC`.                                           |
| `rate`                 | Number | EUR → USDC conversion rate applied at the time the quote was generated.                        |
| {% endtab %}           |        |                                                                                                |
| {% endtabs %}          |        |                                                                                                |


# Approve Payout

The Approve Payout endpoint is used by the Merchant to explicitly approve a payout request before it is sent for processing. This step is required only when `autoMerchantApproval = 0`. Once approved, the payout transitions from a pending / queued state to processing, triggering the downstream fiat disbursement.

***

#### When to Use

Call this endpoint when:

* `autoMerchantApproval = 0`
* A payout has been created and is in a **pending / awaiting approval** state
* All required user inputs, KYC (where applicable), and validations are complete

***

#### Flow Context

1. Merchant creates a payout request
2. End user submits required details and completes KYC (if applicable)
3. Payout enters pending approval state
4. Merchant calls `approvePayout` (this endpoint)
5. Payout moves to processing
6. EUR is disbursed to beneficiary via Open Banking rails
7. Merchant’s USDC balance is debited accordingly

#### **Flow outcome:**

* The merchant initiates a transfer of USDC to the end user
* The end user completes the off-ramp flow via the hosted widget
* The corresponding fiat amount is made available to the end user via SEPA instant
* The merchant’s USDC balance is debited for the corresponding amount (including applicable fees, if any)

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout/approve`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>merchantOrderId</code></td><td><code>String</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3' // please use a unique order id per request
}
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout/approve', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Payout instance accepted successfully",
  "data": {}
}
```

{% endtab %}

{% tab title="Response Fields" %}

{% endtab %}
{% endtabs %}


# Disapprove Payout

The Disapprove Payout endpoint is used by the Merchant to explicitly disapprove a payout request before it is sent for processing. This step is required only when `autoMerchantApproval = 0`. Once disapproved, the payout transitions from a pending / queued state to expired state.

***

#### When to Use

Call this endpoint when:

* `autoMerchantApproval = 0`
* A payout has been created and is in a **pending / awaiting approval** state
* All required user inputs, KYC (where applicable), and validations are complete

***

#### Flow Context

1. Merchant creates a payout request
2. End user submits required details and completes KYC (if applicable)
3. Payout enters pending approval state
4. Merchant calls `disapprovePayout` (this endpoint)
5. Payout moves to Expired state

#### **Flow outcome:**

* The merchant disapproves the payout request
* The payout moves to **Expired** state
* The fiat disbursement does not start
* The merchant’s USDC balance remains unchanged

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/payout/disapprove`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>merchantOrderId</code></td><td><code>String</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3' // please use a unique order id per request
}
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": 'application/json',
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/instance/payout/disapprove', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Payout instance disapproved successfully",
  "data": {}
}
```

{% endtab %}

{% tab title="Response Fields" %}

{% endtab %}
{% endtabs %}


# Webhook for Tylt CrossRamp (Pay-Out)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:

<table><thead><tr><th width="124.421875">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>Instance Created</td></tr><tr><td><strong><code>2</code></strong></td><td>Order Created</td></tr><tr><td><strong><code>3</code></strong></td><td>Order Processing</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment Processing</td></tr><tr><td><strong><code>5</code></strong></td><td>Payment Completed</td></tr><tr><td><strong><code>8</code></strong></td><td>Payment Failed</td></tr><tr><td><strong><code>9</code></strong></td><td>Order Cancelled or Expired</td></tr><tr><td><strong><code>10</code></strong></td><td>KYC Failed</td></tr><tr><td><strong><code>11</code></strong></td><td>Pending Merchant Final Approval</td></tr></tbody></table>

1. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
2. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend web-hooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.isBuying == 1) {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 1, "description": "Instance Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 2, "description": "Order Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 3, "description": "Order Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 4, "description": "Payment Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 5" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 5, "description": "Payment Completed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId8" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 8, "description": "Order Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 9" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 9, "description": "Order Cancelled or Expired" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 10" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 10, "description": "KYC Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId:11" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 1.3,
      "fiatAmount": 30,
      "cryptoAmount": 23.08,
      "fiatCurrency": "EUR",
      "cryptoCurrency": "USDC"
    },
    "isBuying": 0,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "autoMerchantApproval": 1,
    "eventDetails": { "eventId": 11, "description": "Awaiting Approval" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

[<mark style="color:green;">**`GET`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  merchantOrderId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/v2/prime-fiat/instance/details??merchantOrderId?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
    "msg": "Instance details fetched successfully.",
    "data": {
        "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
        "isBuying": 0,
        "eventId": 4,
        "eventDescription": "Payment Completed",
        "fiatAmount": 30,
        "fiatCurrencySymbol": "EUR",
        "rate": 1.3,
        "cryptoAmount": 39,
        "cryptoCurrencySymbol": "USDC",
        "fees": 0.78,
        "bankStatementReference": "irf482bca625d9a9d",
        "callBackUrl": "https://www.callback.com",
        "redirectUrl": "https://www.google.com",
        "userDetails": {
          "firstName": "Test",
          "lastName": "User",
          "email": "testuser@testemail.com",
          "country": "Poland",
          "dob": "1990-01-01",
          "DocumentType": "Identity Card",
          "DocumentNumber": "426349253ZY8",
          "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
        },
        "payeeDetails": {
          "iban": "FR7630006000011234567890185"
        },
        "merchantDetils":{ 
            "merchantName": "Example Merchant Ltd",
            "merchantUrl": "https://www.examplemerchant.com",
            "merchantInternalId": "merchant-12345"
            },
        "autoMerchantApproval": 1,
        "MDR": 2
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                    | Type   | Description                                                                  |
| ------------------------ | ------ | ---------------------------------------------------------------------------- |
| `instanceId`             | String | Unique identifier for the payment instance.                                  |
| `isBuying`               | Number | Indicates whether the transaction is a Pay-In (`1`) or Pay-Out (`0`).        |
| `eventId`                | Number | Numeric code representing the current transaction lifecycle state.           |
| `eventDescription`       | String | Human-readable description of the transaction status.                        |
| `fiatAmount`             | Number | Amount paid by the customer in fiat currency.                                |
| `fiatCurrencySymbol`     | String | Fiat currency symbol used in the transaction — always `"EUR"`.               |
| `rate`                   | Number | EUR → USDC conversion rate applied for the transaction.                      |
| `cryptoAmount`           | Number | Amount of USDC credited to the merchant after conversion.                    |
| `cryptoCurrencySymbol`   | String | Crypto currency used for settlement — always `"USDC"`.                       |
| `fees`                   | Number | Total fees charged for processing the transaction.                           |
| `bankStatementReference` | String | Unique reference shown in the customer’s bank statement.                     |
| `callBackUrl`            | String | Merchant-configured URL to receive payment or settlement callbacks.          |
| `redirectUrl`            | String | URL used to redirect the customer to complete or authorize the payment.      |
| `userDetails`            | Object | Merchant-defined metadata associated with the customer.                      |
| `merchantDetails`        | Object | Merchant-defined metadata associated with the merchant being paid.           |
| `payeeDetails`           | Object | Object containing users bank account details where the payment will be made. |
| `MDR`                    | Number | Merchant Discount Rate applied to the transaction (percentage).              |
| {% endtab %}             |        |                                                                              |
| {% endtabs %}            |        |                                                                              |


# Philippines (PHP)

Tylt CrossRamp enables merchants to embed on-ramp functionality using qrPH rails in the Philippines, with settlement in USDT. CrossRamp operates as an embedded crypto exchange and transfer layer, allowing end users to acquire stablecoins via local payment methods, while merchants receive and manage balances in USDT.

***

#### Low-Code Integration

Tylt CrossRamp provides a low-code integration for embedding qrPH-based on-ramp flows within merchant applications.

This approach enables:

* Rapid integration with minimal development effort
* Pre-built interface for end-user transaction initiation
* Standardised flows across supported regions
* Integrated compliance stack (AML, KYC, Travel Rule)
* Reduced integration and operational complexity

***

#### Settlement Model

CrossRamp enables end users to initiate PHP transfers via qrPH, which are used to facilitate crypto-asset acquisition flows.

Under the daily settlement model:

* Fiat transactions are completed in PHP via qrPH through regulated partners
* Corresponding crypto-asset conversions are executed within Tylt
* Resulting USDT balances are aggregated and settled to the merchant

Settlement is processed once daily at 2:00 AM UTC, with the merchant’s USDT balance updated accordingly.

Merchants may subsequently use their USDT balance for transfers, payouts, or treasury operations.

***

### Settlement Summary

| Feature                     | qrPH (Philippines)                                |
| --------------------------- | ------------------------------------------------- |
| **Settlement Frequency**    | Daily (2:00 AM UTC)                               |
| **Settlement Currency**     | USDT                                              |
| **Fiat Currency (On-Ramp)** | PHP                                               |
| **Payment Method**          | qrPH (account-to-account via banks and e-wallets) |
| **Integration Type**        | Low-code widget                                   |
| **Conversion Model**        | PHP → USDT (per transaction)                      |
| **Settlement Model**        | Aggregated daily settlement                       |
| **Liquidity Availability**  | Post 2:00 AM UTC settlement                       |
| **Merchant Wallet Credit**  | USDT wallet                                       |
| **Supported Region**        | Philippines                                       |


# qrPH Payin (PHP → USDT)

This section provides a reference for integrating Tylt CrossRamp’s qrPH on-ramp flow within merchant applications. Through this integration, end users can initiate PHP transfers via qrPH, which are used to facilitate the acquisition of stablecoins. The resulting USDT is transferred to the merchant’s Tylt wallet.

***

#### Conversion & Settlement Model

1. Each transaction is processed using a real-time conversion quote.
2. At the time of initiation, a PHP → USDT quote is generated. The end user reviews and accepts the quote and proceeds with the on-ramp flow based on the provided transaction details.
3. The end user then completes the fiat transfer via qrPH through a regulated partner. Upon successful completion of the fiat leg, the corresponding crypto-asset conversion is executed and the resulting USDT is credited to the merchant’s Tylt wallet.
4. Settlement is not batch-dependent. All transactions are reconciled through a daily settlement cycle, ensuring that balances are fully reflected no later than 02:30 AM UTC

***

#### Settlement Overview

| Attribute               | Description                                                 |
| ----------------------- | ----------------------------------------------------------- |
| **Quote Model**         | Real-time FX quote per transaction (PHP → USDT)             |
| **Credit Timing**       | USDT credited upon successful completion of the transaction |
| **Settlement Finality** | Fully reconciled by 02:30 AM UTC daily                      |
| **Settlement Currency** | USDT                                                        |
| **Payment Method**      | qrPH (Philippines National QR Standard)                     |
| **Destination**         | Merchant Tylt Wallet                                        |

***

### What You’ll Find in the API Reference

**1. qrPH On-Ramp Flow**\
Guidance for enabling end users to initiate PHP transfers via qrPH and complete on-ramp transactions, including transaction lifecycle tracking and settlement visibility.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, webhook structure, and lifecycle states.

**3. Request & Response Formats**\
Structured JSON examples covering pay-in creation, status retrieval, webhook payloads, and error handling.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other common stacks.

***

### Summary

This API enables merchants to embed qrPH-based on-ramp functionality, allowing end users to acquire stablecoins via local payment methods, with settlement managed in USDT through Tylt’s crypto-asset infrastructure.


# Create a Pay-in Instance

This endpoint allows you to create a new payment instance and receive a URL that can be used to launch the Tylt CrossRamp qrPH Pay-In widget. Through the widget, the merchant's end customer can make a deposit or payment to the merchant using qrPH in PHP. The payment is settled in USDT into the merchants wallet.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/php/instance/payin`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)<br></li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).</p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to deposit in PHP.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Mandatory. Supported Currency is "PHP" only</td></tr><tr><td><code>merchantDetails</code></td><td><code>JSON Object</code></td><td><p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.<br><br>If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided<br><br>If the integrator is the end merchant, the details of its own business must be provided. <br><br>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong><br>The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong><br>The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong><br>A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.<br><br>Transactions with new <code>merchantDetails</code> go through an automated internal review process. </p></td></tr><tr><td><code>cryptoUi</code></td><td><code>number</code></td><td>Controls the visual mode of the hosted payment widget. Default is <code>1</code>. If set to <code>1</code>, the widget UI is adapted to showcase a crypto purchase flow. If set to <code>0</code>, the widget UI is adapted to showcase a fiat payment flow.</td></tr><tr><td><code>provider</code></td><td><code>string</code></td><td>Optional. Defaults to <code>PSMD</code>. Allowed values: <code>PSMD</code>, <code>CONNECX</code>.</td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'PHP',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345" 
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Poland",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg"          
<strong>    }
</strong><strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/php/instance/payin', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Ivy instance created successfully",
  "data": {
    "instanceId": "467153bc-72a8-466d-8fb1-59b080250554",
    "merchantOrderId": "merchant-test-gWsQ1fiLmk",
    "url": "https://app.tylt.money/prime-php-instance/467153bc-72a8-466d-8fb1-59b080250554",
    "userDetails": {
      "firstName": "Test",
      "lastName": "User",
      "email": "testuser@testemail.com",
      "country": "Poland",
      "dob": "1990-01-01",
      "DocumentType": "Identity Card",
      "DocumentNumber": "426349253ZY8",
      "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
    },
    "merchantDetils":{ 
            "merchantName": "Example Merchant Ltd",
            "merchantUrl": "https://www.examplemerchant.com",
            "merchantInternalId": "merchant-12345"
    },
    "fiatAmount": 4000,
    "fiatCurrencySymbol": "PHP",
    "cryptoAmount": 69.00,
    "cryptoCurrencySymbol": "USDT",
    "rate": 57.97
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type   | Description                                                                              |
| ---------------------- | ------ | ---------------------------------------------------------------------------------------- |
| `instanceId`           | String | Unique identifier for the  Open Banking payment instance.                                |
| `merchantOrderId`      | String | Merchant-provided order reference used for internal tracking and reconciliation.         |
| `url`                  | String | Hosted checkout URL where the customer is redirected to complete the PHP qrPH payment.   |
| `userDetails`          | Object | Merchant-supplied customer metadata returned exactly as provided in the request.         |
| `merchantDetails`      | Object | Object containing merchant identification information associated with the transaction.   |
| `fiatAmount`           | Number | Amount to be paid by the customer.                                                       |
| `fiatCurrencySymbol`   | String | Fiat currency used in the transaction — always `PHP`.                                    |
| `cryptoAmount`         | Number | Amount of USDT to be credited to the merchant upon successful completion of the payment. |
| `cryptoCurrencySymbol` | String | Crypto currency used for settlement — always `USDT`.                                     |
| `rate`                 | Number | PHP → USDT conversion rate applied at the time the quote was generated.                  |
| {% endtab %}           |        |                                                                                          |
| {% endtabs %}          |        |                                                                                          |


# Webhook for Tylt CrossRamp (Pay-in)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:

<table><thead><tr><th width="124.421875">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>Instance Created</td></tr><tr><td><strong><code>2</code></strong></td><td>Order Created</td></tr><tr><td><strong><code>3</code></strong></td><td>Payment Processing</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment Completed</td></tr><tr><td><strong><code>6</code></strong></td><td>Refund Processing</td></tr><tr><td><strong><code>7</code></strong></td><td>Payment Refunded</td></tr><tr><td><strong><code>8</code></strong></td><td>Payment Failed</td></tr><tr><td><strong><code>9</code></strong></td><td>Order Cancelled or Expired</td></tr><tr><td><strong><code>10</code></strong></td><td>KYC Failed</td></tr></tbody></table>

1. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
2. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend web-hooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.isBuying == 1) {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 1, "description": "Instance Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 2, "description": "Order Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
     "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 3, "description": "Payment Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 4, "description": "Payment Completed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 9" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 9, "description": "Order Cancelled or Expired" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 10" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 10, "description": "KYC Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

[<mark style="color:green;">**`GET`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/php/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/php/instance/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  merchantOrderId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/v2/prime-fiat/php/instance/details??merchantOrderId?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
    "msg": "Instance details fetched successfully.",
    "data": {
        "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
        "isBuying": 1,
        "eventId": 4,
        "eventDescription": "Payment Completed",
        "fiatAmount": 580,
        "fiatCurrencySymbol": "PHP",
        "rate": 58,
        "cryptoAmount": 10,
        "cryptoCurrencySymbol": "USDT",
        "fees": 0.78,
        "callBackUrl": "https://www.callback.com",
        "redirectUrl": "https://www.google.com",
        "userDetails": {
            "Full Name": "Ana Carolina Barros Freitas",
            "DOB": "1950-01-01",
            "Country": "Portugal",
            "DocumentType": "Identity Card",
            "DocumentNumber": "426349253ZY8",
            "DocumentURL" : "https://kyc.gaming.com/b1278191.jpeg"
            },
        "merchantDetils":{ 
            "merchantName": "Example Merchant Ltd",
            "merchantUrl": "https://www.examplemerchant.com",
            "merchantInternalId": "merchant-12345"
            },
        "MDR": 2
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type   | Description                                                             |
| ---------------------- | ------ | ----------------------------------------------------------------------- |
| `instanceId`           | String | Unique identifier for the payment instance.                             |
| `isBuying`             | Number | Indicates whether the transaction is a Pay-In (`1`) or Pay-Out (`0`).   |
| `eventId`              | Number | Numeric code representing the current transaction lifecycle state.      |
| `eventDescription`     | String | Human-readable description of the transaction status.                   |
| `fiatAmount`           | Number | Amount paid by the customer in fiat currency.                           |
| `fiatCurrencySymbol`   | String | Fiat currency symbol used in the transaction — always `"PHP"`.          |
| `rate`                 | Number | PHP → USDT conversion rate applied for the transaction.                 |
| `cryptoAmount`         | Number | Amount of USDT credited to the merchant after conversion.               |
| `cryptoCurrencySymbol` | String | Crypto currency used for settlement — always `"USDT"`.                  |
| `fees`                 | Number | Total fees charged for processing the transaction.                      |
| `callBackUrl`          | String | Merchant-configured URL to receive payment or settlement callbacks.     |
| `redirectUrl`          | String | URL used to redirect the customer to complete or authorize the payment. |
| `userDetails`          | Object | Merchant-defined metadata associated with the customer.                 |
| `merchantDetails`      | Object | Merchant-defined metadata associated with the merchant being paid.      |
| `MDR`                  | Number | Merchant Discount Rate applied to the transaction (percentage).         |
| {% endtab %}           |        |                                                                         |
| {% endtabs %}          |        |                                                                         |


# InstaPay Payout (PHP → USDT)

This section provides a reference for integrating Tylt CrossRamp’s off-ramp flow in the Philippines using InstaPay / PESONet rails.

Through this integration, merchants can initiate transfers of stablecoins (USDT) to end users, who can subsequently convert the received crypto-assets into fiat (PHP) via local payment rails.

Tylt does not process or hold fiat funds. All fiat transactions are executed via regulated payment partners.

***

#### Conversion & Settlement Model

1. Each transaction is processed using a real-time conversion quote.
2. At the time of initiation, a USDT → PHP quote is generated. The merchant initiates a transfer of stablecoins to the end user, who reviews and accepts the quote and proceeds with the off-ramp flow based on the provided transaction details.
3. Upon completion of the off-ramp flow, the corresponding crypto-asset conversion is executed, and the resulting fiat amount is made available to the end user via InstaPay or PESONet through a regulated payment partner.
4. Processing is continuous and not batch-dependent. All transactions are reconciled through a daily settlement cycle to ensure balance consistency.

***

#### Settlement Overview

| Attribute               | Description                                      |
| ----------------------- | ------------------------------------------------ |
| **Quote Model**         | Real-time FX quote per transaction (USDT → PHP)  |
| **Debit Timing**        | USDC debited upon execution of the off-ramp flow |
| **Settlement Currency** | USDT (merchant side)                             |
| **Fiat Currency**       | PHP                                              |
| **Payment Method**      | InstaPay / PESONet (Philippines local rails)     |
| **Source**              | Merchant Tylt Wallet                             |

***

#### What You’ll Find in the API Reference

**1. Off-Ramp Flow (USDT → PHP)**\
Guidance for initiating off-ramp flows, including transferring stablecoins to end users and enabling fiat conversion via local rails.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, webhook structure, and lifecycle states.

**3. Request & Response Formats**\
Structured JSON examples covering off-ramp creation, status tracking, webhook payloads, and error handling.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other common stacks.

***

#### Summary

This API enables merchants to initiate off-ramp flows, allowing end users to convert stablecoins into fiat via local bank transfer mechanisms, with all crypto-asset conversion and settlement managed within Tylt’s infrastructure.


# Create a Pay-Out Instance

This endpoint creates a new Open Banking Pay-Out payment instance and returns a widget launch URL. The merchant can use this URL to launch the Tylt CrossRamp Open Banking Pay-Out widget, where the merchant’s end customer submits a payout request.

**Flow outcome:**

* The end customer receives a PHP bank transfer into their provided bank account via istaPay or Pesonet
* The merchant’s USDT balance is debited for the corresponding amount (plus applicable fees, if any).
* Settlement is executed in PHP, while funding is taken in USDT from the merchant wallet.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/php/instance/payout`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Custom fields associated with the end user making a payment to the merchant. These fields are echoed back in webhook notifications and other API responses for tracking and reconciliation.You may send an empty object (<code>{}</code>).<br></p><p><strong>Reserved keys (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>firstName</code> (string)</li><li><code>lastName</code> (string)</li><li><code>email</code> (string)</li><li><code>country</code> (string)</li><li><code>dob</code> (string, format: <code>YYYY-MM-DD</code>)<br></li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).</p></td></tr><tr><td><code>payeeDetails</code></td><td><code>JSON Object</code></td><td><p>Bank Account Details (Payout Destination)</p><p>Use this object to capture the user’s payout destination bank account—i.e., the bank account where fiat funds will be paid out.</p><p></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:</p><ul><li><code>accountNumber</code> (string)</li><li><code>bic</code>(string)</li><li><code>bankName</code>(string)</li></ul><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget (if required by the flow).<br><br>The list of supported banks, wallets, financial institutions that are active can be found here</p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>Mandatory. A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>Mandatory. The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to withdraw in PHP.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Mandatory. Supported Currency is "PHP" only</td></tr><tr><td><code>merchantDetails</code></td><td><code>JSON Object</code></td><td><p>The <code>merchantDetails</code> object identifies the merchant on whose behalf the transaction is being processed. This information is required for transaction attribution, reconciliation, risk screening, and regulatory reporting.<br><br>If the integrator is acting as a Merchant of Record, the details of the underlying end merchant must be provided.<br><br>If the integrator is the end merchant, the details of its own business must be provided. <br><br>The following fields must be provided inside the <code>merchantDetails</code> object:</p><ul><li><strong>merchantName</strong><br>The legal or DBA name of the merchant.</li><li><strong>merchantUrl</strong><br>The official website URL of the merchant. This must be a valid HTTPS URL representing the merchant’s active operating website.</li><li><strong>merchantInternalId</strong><br>A unique internal identifier assigned by the merchant. This identifier is used for reconciliation, reporting, and ongoing transaction tracking and must remain consistent across transactions.</li></ul><p>All fields within <code>merchantDetails</code> are mandatory. Transactions submitted without this object, or with incomplete merchant details, will be rejected.<br><br>Transactions with new <code>merchantDetails</code> go through an automated internal review process. </p></td></tr><tr><td><code>autoPayout</code></td><td><code>number</code></td><td><p>Set to <code>1</code> if you want the payout to be processed automatically, without requiring the user to interact with the Pay-Out widget. </p><p></p><p>When set to <code>0</code>, the user must manually confirm the payout through the widget interface.<br><br>For auto-payout to work, payeeDetails need to complete and accurate.</p></td></tr><tr><td><code>cryptoUi</code></td><td><code>number</code></td><td>Controls the visual mode of the hosted payment widget. Default is <code>1</code>. If set to <code>1</code>, the widget UI is adapted to showcase a crypto purchase flow. If set to <code>0</code>, the widget UI is adapted to showcase a fiat payment flow.</td></tr><tr><td><code>provider</code></td><td><code>string</code></td><td>Optional. Defaults to <code>PSMD</code>. Allowed values: <code>PSMD</code>, <code>CONNECX</code>.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3', // please use a unique order id per request
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'PHP',
    merchantDetails: {
        merchantName: "Example Merchant Ltd",
        merchantUrl: "https://www.examplemerchant.com",
        merchantInternalId: "merchant-12345"
    },
    userDetails: {
            firstName: "Test",
            lastName: "User",
            email: `testuser@testemail.com`,
            country: "Philippines",
            dob: "1990-01-01",
            DocumentType: "Identity Card",
            DocumentNumber: "426349253ZY8",
            DocumentURL : "https://kyc.gaming.com/b1278191.jpeg"          
<strong>    },
</strong><strong>   payeeDetails: {
</strong><strong>           accountNumber: "1212987267494" 
</strong><strong>           bic: "APHIPHM2XXX"
</strong><strong>           bankName: "Alipay Philippines"
</strong><strong>    }
</strong><strong>};
</strong>
// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime-fiat/php/instance/payin', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Instance created successfully",
  "data": {
    "instanceId": "467153bc-72a8-466d-8fb1-59b080250554",
    "merchantOrderId": "merchant-test-gWsQ1fiLmk",
    "url": "https://app.tylt.money/prime-php-instance/467153bc-72a8-466d-8fb1-59b080250554",
    "userDetails": {
      "firstName": "Test",
      "lastName": "User",
      "email": "testuser@testemail.com",
      "country": "Philippines",
      "dob": "1990-01-01",
      "DocumentType": "Identity Card",
      "DocumentNumber": "426349253ZY8",
      "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
    },
   "payeeDetails": {
       "accountNumber": "1212987267494",
       "bic": "APHIPHM2XXX",
       "bankName": "Alipay Philippines"
    },
    "merchantDetils":{ 
      "merchantName": "Example Merchant Ltd",
      "merchantUrl": "https://www.examplemerchant.com",
      "merchantInternalId": "merchant-12345"
    },
    "fiatAmount": 5800,
    "fiatCurrencySymbol": "PHP",
    "cryptoAmount": 100,
    "cryptoCurrencySymbol": "USDT",
    "rate": 58.00
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type   | Description                                                                                                         |
| ---------------------- | ------ | ------------------------------------------------------------------------------------------------------------------- |
| `instanceId`           | String | Unique identifier for the  Open Banking payment instance.                                                           |
| `merchantOrderId`      | String | Merchant-provided order reference used for internal tracking and reconciliation.                                    |
| `url`                  | String | Hosted checkout URL where the customer is redirected to complete the PHP payout using instaPay or Pesonet channels. |
| `userDetails`          | Object | Merchant-supplied customer metadata returned exactly as provided in the request.                                    |
| `merchantDetails`      | Object | Object containing merchant identification information associated with the transaction.                              |
| `payeeDetails`         | Object | Object containing users bank account details where the payment will be made.                                        |
| `fiatAmount`           | Number | Amount to be paid by the customer.                                                                                  |
| `fiatCurrencySymbol`   | String | Fiat currency used in the transaction — always `EUR`.                                                               |
| `cryptoAmount`         | Number | Amount of USDT to be debited from the merchant upon successful initiation of the payout.                            |
| `cryptoCurrencySymbol` | String | Crypto currency used for settlement — always `USDT`.                                                                |
| `rate`                 | Number | PHP → USDT conversion rate applied at the time the quote was generated.                                             |
| {% endtab %}           |        |                                                                                                                     |
| {% endtabs %}          |        |                                                                                                                     |


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

[<mark style="color:green;">**`GET`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/instance/php/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/instance/php/details?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  merchantOrderId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/v2/prime-fiat/instance/details??merchantOrderId?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
    "msg": "Instance details fetched successfully.",
    "data": {
        "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
        "isBuying": 0,
        "eventId": 4,
        "eventDescription": "Payment Completed",
        "fiatAmount": 580,
        "fiatCurrencySymbol": "PHP",
        "rate": 58,
        "cryptoAmount": 10,
        "cryptoCurrencySymbol": "USDT",
        "fees": 0.78,
        "callBackUrl": "https://www.callback.com",
        "redirectUrl": "https://www.google.com",
        "userDetails": {
          "firstName": "Test",
          "lastName": "User",
          "email": "testuser@testemail.com",
          "country": "Poland",
          "dob": "1990-01-01",
          "DocumentType": "Identity Card",
          "DocumentNumber": "426349253ZY8",
          "DocumentURL": "https://kyc.gaming.com/b1278191.jpeg" 
        },
          "payeeDetails": {
               "accountNumber": "1212987267494",
               "bic": "APHIPHM2XXX",
               "bankName": "Alipay Philippines"
        },
        "merchantDetils":{ 
            "merchantName": "Example Merchant Ltd",
            "merchantUrl": "https://www.examplemerchant.com",
            "merchantInternalId": "merchant-12345"
            },
        "MDR": 2
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                    | Type   | Description                                                                  |
| ------------------------ | ------ | ---------------------------------------------------------------------------- |
| `instanceId`             | String | Unique identifier for the payment instance.                                  |
| `isBuying`               | Number | Indicates whether the transaction is a Pay-In (`1`) or Pay-Out (`0`).        |
| `eventId`                | Number | Numeric code representing the current transaction lifecycle state.           |
| `eventDescription`       | String | Human-readable description of the transaction status.                        |
| `fiatAmount`             | Number | Amount paid by the customer in fiat currency.                                |
| `fiatCurrencySymbol`     | String | Fiat currency symbol used in the transaction — always `"EUR"`.               |
| `rate`                   | Number | PHP → USDT conversion rate applied for the transaction.                      |
| `cryptoAmount`           | Number | Amount of USDT debited to the merchant after conversion.                     |
| `cryptoCurrencySymbol`   | String | Crypto currency used for settlement — always `"USDT"`.                       |
| `fees`                   | Number | Total fees charged for processing the transaction.                           |
| `bankStatementReference` | String | Unique reference shown in the customer’s bank statement.                     |
| `callBackUrl`            | String | Merchant-configured URL to receive payment or settlement callbacks.          |
| `redirectUrl`            | String | URL used to redirect the customer to complete or authorize the payment.      |
| `userDetails`            | Object | Merchant-defined metadata associated with the customer.                      |
| `merchantDetails`        | Object | Merchant-defined metadata associated with the merchant being paid.           |
| `payeeDetails`           | Object | Object containing users bank account details where the payment will be made. |
| `MDR`                    | Number | Merchant Discount Rate applied to the transaction (percentage).              |
| {% endtab %}             |        |                                                                              |
| {% endtabs %}            |        |                                                                              |


# Webhook for Tylt CrossRamp (Pay-Out)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:

<table><thead><tr><th width="124.421875">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>Instance Created</td></tr><tr><td><strong><code>2</code></strong></td><td>Order Created</td></tr><tr><td><strong><code>3</code></strong></td><td>Payment Processing</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment Completed</td></tr><tr><td><strong><code>8</code></strong></td><td>Payment Failed</td></tr><tr><td><strong><code>9</code></strong></td><td>Order Cancelled or Expired</td></tr><tr><td><strong><code>10</code></strong></td><td>KYC Failed</td></tr></tbody></table>

1. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
2. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend web-hooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.isBuying == 1) {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 1, "description": "Instance Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 2, "description": "Order Created" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
     "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 3, "description": "Payment Processing" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 4, "description": "Payment Completed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 9" %}

```jsonl
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 9, "description": "Order Cancelled or Expired" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}

{% tab title="eventId: 10" %}

```json
{
  "data": {
    "accounts": {
      "MDR": 2,
      "fees": 0.46,
      "rate": 58,
      "fiatAmount": 580,
      "cryptoAmount": 10,
      "fiatCurrency": "PHP",
      "cryptoCurrency": "USDT"
    },
    "isBuying": 1,
    "instanceId": "443bd1a8-944b-4595-8dcf-21e274e6386c",
    "callBackUrl": "",
    "eventDetails": { "eventId": 10, "description": "KYC Failed" },
    "merchantOrderId": "merchant-test-ANHOGoRiG3"
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Get Supported Institutions

This endpoint retrieves the list of supported receiving banks or institutions for a specific provider and channel.

***

**End Point**

<mark style="color:green;">**`GET`**</mark>` ``https://api.tylt.money/v2/prime-fiat/php/institutions/v2/list?provider={}&channel={}`

**Example Request**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-fiat/php/institutions/v2/list?provider=Pisomind&channel=pesonet`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Query Parameters**

| Parameter  | Required | Description                                                                      |
| ---------- | -------- | -------------------------------------------------------------------------------- |
| `provider` | Yes      | The provider to fetch institutions from. Accepted values: `Pisomind`, `Connecx`. |
| `channel`  | Yes      | The payment rail or channel for the selected provider.                           |

**Notes**

* Both `provider` and `channel` are mandatory.
* `provider` is case-insensitive.
* For `Pisomind`, only `instapay` and `pesonet` are valid channel values.
* For `Connecx`, pass the exact Connecx bank code identifier as the `channel`.
* The response format remains the same for both providers.

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request params
const params = {
  provider: 'Pisomind',
  channel: 'pesonet'
};

// Create HMAC SHA-256 signature using the request params
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(JSON.stringify(params))
  .digest('hex');

// Define headers
const headers = {
  'x-api-key': apiKey,
  'X-TLP-SIGNATURE': signature,
  'Content-Type': 'application/json'
};

// Send the GET request
axios.get('https://api.tylt.money/v2/prime-fiat/php/institutions/v2/list', {
  headers,
  params
})
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error.response ? error.response.data : error.message);
  });
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Institutions retrieved",
  "data": {
    "institutions": [
      {
        "code": "CSPA001PH",
        "name": "PayMaya",
        "rail": "PHPCIS-1001"
      },
      {
        "code": "CSMK001PH",
        "name": "Maya Bank",
        "rail": "PHPCIS-1001"
      }
    ]
  }
}
```

{% endtab %}

{% tab title="400" %}

```json
{
  "msg": "Invalid channel for Pisomind! Allowed values are instapay, pesonet.",
  "data": {}
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field         | Description                                                       |
| ------------- | ----------------------------------------------------------------- |
| `code`        | Institution code to be used when creating a payout.               |
| `name`        | Name of the receiving bank, wallet, or institution.               |
| `rail`        | Payment rail or provider channel associated with the institution. |
| {% endtab %}  |                                                                   |
| {% endtabs %} |                                                                   |


# Administration

The Administration section is intended for approved PSPs, VASPs, and local infrastructure partners that support the operation of Tylt’s Philippines PHP rail.

These partners provide the underlying local payment, disbursement, conversion, settlement, or liquidity infrastructure required to process PHP pay-ins and pay-outs. Tylt uses this infrastructure to make the Philippines PHP rail available to approved merchants through the Tylt platform, API, dashboard, and ledger systems.

Access to the administration APIs is restricted. Only authorized partner-side actors may use these endpoints.

***

### Partner Role

The Philippines PHP rail is operated through a partner-enabled model.

Depending on the agreed configuration, the PSP / VASP partner may support one or more of the following functions:

| Function                  | Description                                                                                    |
| ------------------------- | ---------------------------------------------------------------------------------------------- |
| PHP pay-in collection     | Receiving or processing PHP payments through supported local payment methods.                  |
| PHP pay-out disbursement  | Processing PHP disbursements to end recipients through supported local payment rails.          |
| Fiat-to-crypto conversion | Converting PHP value into USDT or another supported settlement asset, where applicable.        |
| Crypto-to-fiat conversion | Converting USDT or another supported settlement asset into PHP for pay-outs, where applicable. |
| Rate administration       | Setting or updating the PHP/USDT conversion rate used for transaction creation.                |
| Settlement support        | Supporting settlement, reconciliation, and balance confirmation between the partner and Tylt.  |
| Status reporting          | Providing transaction status updates required for merchant-facing reconciliation.              |

The exact responsibilities of each partner depend on the commercial, operational, and regulatory arrangement agreed with Tylt.

***

### Administration APIs

Approved administration actors may be provided access to the following APIs:

| API                   | Description                                                                          |
| --------------------- | ------------------------------------------------------------------------------------ |
| Set PSMD Rate         | Allows the authorized rate actor to set or update the PHP/USDT conversion rate.      |
| Get PSMD Rate History | Allows the authorized rate actor to retrieve historical rate insertions and updates. |

These APIs are restricted and require partner-level authorization. Unauthorized API requests will be rejected.

***

### Authentication

Administration API requests must be authenticated using Tylt-issued API credentials.

Each request must include:

| Header            | Description                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------- |
| `X-TLP-APIKEY`    | API key issued by Tylt to the authorized partner or rate actor.                           |
| `X-TLP-SIGNATURE` | HMAC SHA-256 signature generated using the API secret and the applicable request payload. |

API secrets must be stored securely and must not be exposed in frontend applications, public repositories, shared documents, or unsecured communication channels.

Tylt may revoke or rotate API credentials where required for operational, security, compliance, or contractual reasons.


# Get Rate History

This endpoint returns the rate history for the authorized PSMD rate actor. Each history record represents a rate insert or update made for the applicable fiat currency.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime-fiat/php/rate/history`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Query Parameters**

{% tabs %}
{% tab title="Parameters" %}

| Parameter        | Type     | Default | Description                                                  |
| ---------------- | -------- | ------: | ------------------------------------------------------------ |
| `currencySymbol` | `string` |       — | Filter rate history by fiat currency symbol. Example: `PHP`. |
| `limit`          | `number` |    `50` | Number of history records to return. Maximum value: `200`.   |
| `offset`         | `number` |     `0` | Pagination offset.                                           |
| {% endtab %}     |          |         |                                                              |
| {% endtabs %}    |          |         |                                                              |

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require("axios");
const crypto = require("crypto");

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const query = {
  currencySymbol: "PHP",
  limit: "50",
  offset: "0"
};

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(JSON.stringify(query))
  .digest("hex");

axios.get(
  "https://api.tylt.money/v2/prime-fiat/php/rate/history",
  {
    params: query,
    headers: {
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature
    }
  }
)
  .then((response) => console.log(response.data))
  .catch((error) => console.error(error.response?.data || error));
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Rate history fetched successfully.",
  "data": [
    {
      "id": 10,
      "rateId": 1,
      "fiatCurrencySymbol": "PHP",
      "cryptoCurrencySymbol": "USDT",
      "usdtToFiatRate": 58,
      "fiatToUsdtRate": 0.017241379310344827,
      "action": "update",
      "createdAt": "2026-05-14T10:15:30Z"
    }
  ]
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type     | Description                                                                                                         |
| ---------------------- | -------- | ------------------------------------------------------------------------------------------------------------------- |
| `id`                   | `number` | Unique ID of the history record.                                                                                    |
| `rateId`               | `number` | ID of the active rate record associated with the history entry.                                                     |
| `fiatCurrencySymbol`   | `string` | Fiat currency symbol for which the rate was set.                                                                    |
| `cryptoCurrencySymbol` | `string` | Crypto currency symbol used for conversion. Currently `USDT`.                                                       |
| `usdtToFiatRate`       | `number` | Rate in `1 USDT = x fiatCurrency` format.                                                                           |
| `fiatToUsdtRate`       | `number` | Derived rate in `1 fiatCurrency = x USDT` format.                                                                   |
| `action`               | `string` | Indicates whether the history entry was created by an insert or update action. Possible values: `insert`, `update`. |
| `createdAt`            | `string` | Timestamp when the history record was created.                                                                      |
| {% endtab %}           |          |                                                                                                                     |
| {% endtabs %}          |          |                                                                                                                     |


# Set Rate

This endpoint allows the authorized PSMD rate actor to set the fiat conversion rate used for PSMD pay-in and pay-out creation. The submitted rate must be provided in the following format:

```
1 USDT = x fiatCurrency
```

For example, if `1 USDT = 58 PHP`, the value of `usdtToFiatRate` should be `58`.

When a pay-in or pay-out is created, Tylt uses this rate to calculate the equivalent fiat-to-USDT conversion rate internally.

#### Endpoint

[<mark style="color:green;">**`POST`**</mark>](https://dev-api.tylt.money/v2/prime-fiat/instance/details)`https://api.tylt.money/v2/prime-fiat/php/rate`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Parameters" %}

| Field            | Type     | Required | Description                                                           |
| ---------------- | -------- | -------: | --------------------------------------------------------------------- |
| `currencySymbol` | `string` |      Yes | Fiat currency symbol for which the rate is being set. Example: `PHP`. |
| `usdtToFiatRate` | `number` |      Yes | Actor-set rate in `1 USDT = x fiatCurrency` format. Example: `58`.    |
| {% endtab %}     |          |          |                                                                       |
| {% endtabs %}    |          |          |                                                                       |

**Code Snippet**

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const axios = require("axios");
const crypto = require("crypto");

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const body = {
  currencySymbol: "PHP",
  usdtToFiatRate: 58
};

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(JSON.stringify(body))
  .digest("hex");

axios.post(
  "https://api.tylt.money/v2/prime-fiat/php/rate",
  body,
  {
    headers: {
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature
    }
  }
)
  .then((response) => console.log(response.data))
  .catch((error) => console.error(error.response?.data || error));
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}

```json
{
  "msg": "Rate set successfully.",
  "data": {
    "rateId": 1,
    "currencySymbol": "PHP",
    "cryptoCurrencySymbol": "USDT",
    "usdtToFiatRate": 58,
    "fiatToUsdtRate": 0.017241379310344827,
    "action": "insert"
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                  | Type     | Description                                                                                    |
| ---------------------- | -------- | ---------------------------------------------------------------------------------------------- |
| `rateId`               | `number` | Unique ID of the active rate record.                                                           |
| `currencySymbol`       | `string` | Fiat currency symbol for which the rate was set.                                               |
| `cryptoCurrencySymbol` | `string` | Crypto currency symbol used for conversion. Currently `USDT`.                                  |
| `usdtToFiatRate`       | `number` | Submitted rate in `1 USDT = x fiatCurrency` format.                                            |
| `fiatToUsdtRate`       | `number` | Derived rate in `1 fiatCurrency = x USDT` format.                                              |
| `action`               | `string` | Indicates whether the rate was newly inserted or updated. Possible values: `insert`, `update`. |
| {% endtab %}           |          |                                                                                                |
| {% endtabs %}          |          |                                                                                                |


# Webhook for Administrators

Tylt provides a webhook mechanism for approved rail partners to receive real-time updates on the status of payment instances for both pay-ins and pay-outs. For the Philippines PHP rail, this webhook page applies to:

| Flow                       | Description                                                                                            |
| -------------------------- | ------------------------------------------------------------------------------------------------------ |
| QRPH Pay-In                | PHP pay-in transaction where the end user pays in PHP and the merchant receives USDT settlement value. |
| InstaPay / PESONet Pay-Out | PHP pay-out transaction where USDT value is used to initiate a PHP disbursement.                       |

Tylt sends webhook notifications whenever there is a status change in the transaction lifecycle. The lifecycle is tracked using `eventId`, which identifies the current state of the payment instance. The existing Tylt webhook page states that callbacks are sent on transaction status changes and that the lifecycle is tracked through `eventId`.&#x20;

***

### Setting Up the Webhook

The partner must provide Tylt with an HTTP POST endpoint that can receive JSON webhook payloads.

The webhook endpoint should be capable of:

1. Receiving JSON payloads from Tylt.
2. Verifying the authenticity of the webhook using HMAC-SHA256 signature validation.
3. Processing the transaction status update based on the `eventId`.
4. Returning an HTTP `200` response with `ok` in the response body.

Tylt signs each webhook payload using HMAC-SHA256 and sends the signature in the `X-TLP-SIGNATURE` header. The existing webhook page also specifies that the callback endpoint must validate the signature and acknowledge the webhook with HTTP 200 and body `"ok"`.&#x20;

***

### Webhook Header

| Header            | Description                                                                               |
| ----------------- | ----------------------------------------------------------------------------------------- |
| `X-TLP-SIGNATURE` | HMAC-SHA256 signature generated using the raw POST data and the partner’s API secret key. |

***

### Pay-In Lifecycle

For QRPH pay-ins, Tylt sends webhook updates as the pay-in instance moves through the payment lifecycle.

```
eventId 1 → Instance Created
eventId 2 → Order Created
eventId 3 → Payment Processing
eventId 4 → Payment Completed
```

Exception or unsuccessful states may include:

```
eventId 8  → Payment Failed
eventId 9  → Order Cancelled or Expired
eventId 10 → KYC Failed
```

The partner should use the `instanceId`, `merchantOrderId`, and `eventDetails.eventId` to identify and process the pay-in update.

***

### Pay-Out Lifecycle

For InstaPay / PESONet pay-outs, Tylt sends webhook updates as the pay-out instance moves through the payment lifecycle.

```
eventId 1 → Instance Created
eventId 2 → Order Created
eventId 3 → Payment Processing
eventId 4 → Payment Completed
```

Exception or unsuccessful states may include:

```
eventId 8  → Payment Failed
eventId 9  → Order Cancelled or Expired
eventId 10 → KYC Failed
```

The partner should use the `instanceId`, `merchantOrderId`, and `eventDetails.eventId` to identify and process the pay-out update.

***

### Validating Webhooks

Partners should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to confirm that the webhook was sent by Tylt and that the payload has not been modified.

The HMAC signature is generated using:

```
HMAC-SHA256(raw POST data, API_SECRET)
```

The generated signature should be compared with the value received in the `X-TLP-SIGNATURE` header.

***

### Example Webhook Handling Code

```javascript
const express = require("express");
const crypto = require("crypto");

const app = express();
const PORT = 3000;
const apiSecretKey = "YOUR_TLP_API_SECRET_KEY";

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post("/callback", (req, res) => {
  const data = req.body;

  const tlpSignature = req.headers["x-tlp-signature"];

  const calculatedHmac = crypto
    .createHmac("sha256", apiSecretKey)
    .update(JSON.stringify(data))
    .digest("hex");

  if (calculatedHmac === tlpSignature) {
    console.log("Received Tylt webhook:", data);

    const eventId = data?.data?.eventDetails?.eventId;
    const instanceId = data?.data?.instanceId;
    const merchantOrderId = data?.data?.merchantOrderId;

    console.log("Event ID:", eventId);
    console.log("Instance ID:", instanceId);
    console.log("Merchant Order ID:", merchantOrderId);

    // Process the webhook based on eventId
    // 1  = Instance Created
    // 2  = Order Created
    // 3  = Payment Processing
    // 4  = Payment Completed
    // 8  = Payment Failed
    // 9  = Order Cancelled or Expired
    // 10 = KYC Failed

    return res.status(200).send("ok");
  }

  return res.status(400).send("Invalid HMAC signature");
});

app.listen(PORT, () => {
  console.log(`Server listening on port ${PORT}`);
});
```

### Webhook Acknowledgement

After receiving and validating the webhook, the partner must return:

```
HTTP 200
```

with the response body:

```
ok
```

If Tylt does not receive this acknowledgement, the webhook will not be retried automatically. Missed callbacks can be resent manually from the Tylt dashboard. ([Tylt Documentation](https://docs.tylt.money/introduction/tylt-crossramp-fiat-less-than-greater-than-crypto-solutions/philippines-php-english/instapay-pesonet-pay-out-widget/webhook-for-tylt-crossramp-pay-out))

***

### Important Considerations

| Area                 | Requirement                                                                                                           |
| -------------------- | --------------------------------------------------------------------------------------------------------------------- |
| Signature validation | Always verify the `X-TLP-SIGNATURE` header before processing the webhook.                                             |
| Response             | Always return HTTP `200` with `ok` in the response body after successful receipt.                                     |
| Manual retry         | If a callback is missed, the webhook can be manually resent from the Tylt dashboard.                                  |
| Lifecycle handling   | Use `eventDetails.eventId` to determine the current transaction state.                                                |
| Reconciliation       | Store `instanceId`, `merchantOrderId`, `eventId`, fiat amount, crypto amount, rate, and timestamp for reconciliation. |

***


# India (INR)

Tylt CrossRamp enables merchants to embed on-ramp and off-ramp functionality using UPI rails in India, with settlement in USDT. CrossRamp operates as an embedded crypto exchange and transfer layer, allowing end users to acquire and dispose of stablecoins via local payment methods, while merchants receive and manage balances in USDT. In the India (UPI) flow, fiat transactions are facilitated through a peer-to-peer (P2P) network of buyers and sellers, rather than direct integration with payment partners.

***

#### Supported Flows

1. End users initiate UPI transfers through the P2P network to acquire stablecoins, which are transferred to the merchant
2. Merchants transfer stablecoins to end users, who subsequently convert the received crypto-assets into INR via the P2P network.

***

#### Integration Methods

Tylt CrossRamp provides two integration approaches:

#### 1. Hosted Widget

* Low-code integration with minimal development effort
* Pre-built interface for end-user transaction initiation
* Integrated P2P matching and execution within the flow
* Suitable for rapid deployment with limited customisation

***

#### 2. Host-to-Host Integration

* Direct API-based integration
* Full control over application flow and user experience
* Enables custom handling of P2P flows and liquidity interaction
* Suitable for advanced implementations

***


# UPI Payin (INR → USDT)

This section provides a reference for integrating Tylt CrossRamp’s UPI on-ramp flow within merchant applications. Through this integration, end users initiate INR transfers via UPI, which are facilitated through a peer-to-peer (P2P) network of liquidity providers. These flows are used to enable the acquisition of stablecoins, which are subsequently transferred to the merchant.

***

#### Flow Overview

* End users initiate UPI transfers through the embedded widget
* Fiat leg is executed via P2P matching with liquidity providers
* Upon confirmation, the corresponding crypto-asset conversion is executed
* Resulting USDT is transferred to the merchant

***

#### What You’ll Find in the API Reference

**1. UPI On-Ramp Flow (INR → USDT)**\
Guidance for enabling end users to initiate UPI transfers via the P2P network and complete on-ramp transactions, including lifecycle tracking and reconciliation.

**2. Supporting APIs**\
Documentation for auxiliary endpoints, including supported currencies, networks, and system capabilities.

**3. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and usage patterns.

**4. Request & Response Formats**\
Structured JSON examples covering on-ramp creation, status tracking, webhook payloads, and error handling.

**5. Code Examples**\
Reference implementations in Node.js, Python, and other commonly used stacks.

**6. Error Handling**\
Common error scenarios, causes, and recommended handling strategies.

***

#### Summary

This API enables merchants to embed UPI-based on-ramp functionality, allowing end users to acquire stablecoins via P2P-facilitated fiat flows, with settlement managed in USDT through Tylt’s crypto-asset infrastructure.


# Create a Pay-in Instance

This endpoint allows you to create a new payment instance and receive a URL that can be used to launch the **Tylt CrossRamp Pay-In widget.** Through the widget, the merchant's end customer can make a deposit or payment to the merchant using UPI. The payment is settled in USDT into the merchants wallet.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/p2pRampsMerchant/createInstance`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>isBuyTrade</code></td><td><code>number</code></td><td>Must be set to 1 for a Pay-In transaction.</td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td>Custom fields associated with the user, supplied by the merchant. These fields are included in webhook notifications and other API responses for easy reference and tracking. An empty object can be sent.</td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Non-mandatory. This is the amount the user wants to deposit in USDT or INR equivalent. If this field is empty user can enter the value in the payment flow. </td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>To be used if using <code>amount</code>. Supported Currency is "USDT" or "INR" only.</td></tr><tr><td><code>userEmail</code></td><td><code>string</code></td><td>Non-mandatory. If the merchant wants to share the user email id they can use this field. If this field is empty, the user will have to provide the email or SSO login during the payment flow.</td></tr><tr><td><code>isKYCNeeded</code></td><td><code>number</code></td><td>1 or 0. If set to 0 the user will not be required to complete KYC or provide KYC. If field is in passed, default behaviour is KYC is required. This bypass needs to be approved by the admin for the Merchant.</td></tr><tr><td><code>isUTRNeeded</code></td><td>number</td><td>To be set <mark style="color:green;"><code>Mandatorily</code></mark> as 1.  The user will be required to provide the UTR (Unique Transaction Reference) number after making the payment. This is a <mark style="color:green;"><code>compliance</code></mark> step as it significantly reduces payment failures, disputes, and chargebacks while also enabling seamless processing through our automated Lightning Bridge.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Flow Modularity**

Merchants have the flexibility to enable or disable the following modules within the customer flow:

1. **User Email Sign-in**:
   * The system requires an email for user identification.
   * Merchants can provide the email by passing it in the `userEmail` field within the request body.
   * Alternatively, if the merchant prefers the user to enter their email during the payment process, this field can be left empty.
2. **KYC Bypass**:
   * In certain use cases, KYC verification may not be required for the end user.
   * To bypass KYC, set `isKYCNeeded` to 0.
   * When enabled, the user will not be required to complete KYC, and any existing KYC records will not be checked.
   * **Important:** Merchants must have admin pre-authorisation to use the KYC bypass feature.
     {% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    isBuyTrade: 1,
    userDetails: {},
    merchantOrderId: crypto.randomUUID(),
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    isUTRNeeded: 1,
    currencySymbol: "USDT",
    amount: "10",
    isKYCNeeded: 1,
    //userEmail: abc@email.com (required if isKYCNeeded is 0)
};

// Print request body for reference
console.log("requestBody", requestBody);

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/p2pRampsMerchant/createInstance', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests
import uuid

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a POST request
def send_post_request(url, body):
    raw = json.dumps(body, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, raw)

    headers = {
        'Content-Type': 'application/json',
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }

    response = requests.post(url, headers=headers, data=raw)
    return response.json()

# Request body
request_body = {
    "isBuyTrade": 1,
    "userDetails": {},
    "merchantOrderId": str(uuid.uuid4()),
    "callBackUrl": 'https://www.test.com/callback',
    "redirectUrl": 'https://www.test.com/callback',
    "isUTRNeeded": 1,
    "currencySymbol": "USDT",
    "amount": "10",
    "isKYCNeeded": 1,
    ##userEmail: abc@email.com (required if isKYCNeeded is 0)
}

# Print request body for reference
print('request_body',request_body)

# Send the request
response = send_post_request('https://api.tylt.money/p2pRampsMerchant/createInstance', request_body)
print("Response:", response)


```

{% endtab %}

{% tab title="JavaScript (Fetch)" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    isBuyTrade: 1,
    userDetails: {},
    merchantOrderId: crypto.randomUUID(),
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    isUTRNeeded: 1,
    currencySymbol: "USDT",
    amount: "10",
    isKYCNeeded: 1,
    //userEmail: abc@email.com (required if isKYCNeeded is 0)
};

// Print request body for reference
console.log("requestBody", requestBody);

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: body,
    });
    return response.json();
};

// Send the request
sendRequest('https://api.tylt.money/p2pRampsMerchant/createInstance', headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "Instance created successfully",
    "data": {
        "url": "https://app.tylt.money/prime/d0f6cc25-e8f8-11ef-830e-02d8461243e9",
        "instanceId": "d0f6cc25-e8f8-11ef-830e-02d8461243e9"     
        }    
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>url</td><td>string</td><td>The unique link to the Tylt Prime Payment widget. You can display this url either on iframe or a browser.</td></tr><tr><td>instanceId</td><td>string</td><td>The instance ID generated by Tylt, used as a global identifier. </td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Web-hook: UPI Pay-In

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:<br>

   <table data-header-hidden><thead><tr><th width="100"></th><th></th></tr></thead><tbody><tr><td><strong><code>eventId</code></strong></td><td><strong>Description</strong></td></tr><tr><td><strong><code>0</code></strong></td><td>The instance is created. User is yet to interact with the instance.</td></tr><tr><td><strong><code>1</code></strong></td><td>Trade initiated.</td></tr><tr><td><strong><code>2</code></strong></td><td>Waiting for the buyer to make and confirm payment via UPI.</td></tr><tr><td><strong><code>3</code></strong></td><td>Buyer confirms making payment. Seller is verifying the payment.</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment acknowledged and trade completed.</td></tr><tr><td><strong><code>5</code></strong></td><td>Payment disputed. Trade moved to dispute.</td></tr><tr><td><strong><code>6</code></strong></td><td>Payment acknowledged and trade completed by the system.</td></tr><tr><td><strong><code>9</code></strong></td><td>Trade expired as action or payment was not completed prior to the deadline or disputed payment was expired due to non payment. </td></tr></tbody></table>

{% hint style="info" %}

### Instance Information

The response related to an instance information contains two primary objects:

#### 1. Trade Object

This object contains all the information about the customer buying or selling USDT from the counterparty. It includes fields like:

* Trade lifecycle details (`eventId`, deadlines, description).
* Fiat and cryptocurrency details (currency name, symbol, amount, etc.).
* Payment method information (e.g., UPI).

#### 2. Transaction Object

This object contains all the information about the financial debit or credit carried out on the merchant's account. It is relevant to merchants for crediting or debiting a consumer for the transaction. The `transaction` object is updated **only when the `eventId` is 4**, representing the completion of the trade
{% endhint %}

4. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
5. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.accounts.transactionType === 'pay-in') {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)

# Your TL Pay API Secret Key
TLP_API_SECRET_KEY = 'YOUR_TLP_API_SECRET_KEY'  # Replace with your actual API secret key

@app.route('/callback', methods=['POST'])
def callback():
    # Get the raw request data for HMAC calculation
    raw_data = request.data

    # Parse JSON data from the request
    data = request.get_json()

    # Retrieve the signature from the request headers
    tlp_signature = request.headers.get('X-TLP-SIGNATURE')

    # Calculate the HMAC SHA-256 signature
    calculated_hmac = hmac.new(
        key=TLP_API_SECRET_KEY.encode(),
        msg=raw_data,
        digestmod=hashlib.sha256
    ).hexdigest()

    # Compare the calculated HMAC signature with the one in the request header
    if hmac.compare_digest(calculated_hmac, tlp_signature):
        # Signature is valid
        if data['accounts']['transactionType'] == 'pay-in':
            print('Received pay-in callback:', data)
            # Process pay-in data here
            
        # Return HTTP Response 200 with content "ok"
        return jsonify({"message": "ok"}), 200
    else:
        # Invalid HMAC signature
        return jsonify({"error": "Invalid HMAC signature"}), 400

if __name__ == '__main__':
    app.run(port=3000, debug=True)

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: null" %}

```json
{
    "data": {
        "trade": {
            "isBuyTrade":1,
            "event": {
                "id": null,
                "deadline": null,
                "description": null
            },
            "createdAt": null,
            "updatedAt": null,
            "fiatCurrency": {
                "name": null,
                "symbol": null
            },
            "priceDetails": {
                "price": null,
                "amount": null,
                "paymentAmount": null
            },
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": null,
                "symbol": null
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
"accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 196.35,
            "localCurrency": "INR",
            "conversionRate": 93.5,
            "amountPaidInCryptoCurrency": 2.1,
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 4,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 1" %}

```json
{
  "data": {
    "user": {},

    "trade": {
      "utr": "",
      "cashierUTR": "",
      "tradeId": 987654,
      "isBuyTrade": 1,
      "isUTRNeeded": 1,
      "event": {
        "id": 1,
        "deadline": "2026-04-17T12:00:00Z",
        "description": "Trade Initiated. Finding Seller."
      },
      "createdAt": "2026-04-17T11:55:25Z",
      "updatedAt": "2026-04-17T11:55:25Z",
      "fiatCurrency": {
        "name": "Indian Rupee",
        "symbol": "INR"
      },
      "priceDetails": {
        "price": 97.0,
        "amount": 5.15,
        "paymentAmount": 500.0
      },
      "paymentMethod": {
        "details": null
      },
      "cryptoCurrency": {
        "name": "Tether",
        "symbol": "USDT"
      }
    },
    "accounts": {
      "transactionType": "pay-in",
      "localCurrency": "INR",
      "cryptoCurrencySymbol": "USDT",
      "conversionRate": 97.0,
      "MDR_Rate": 6.5,
      "amountPaidInLocalCurrency": 500.0,
      "amountPaidInCryptoCurrency": 5.154639175257732,
      "merchantAccountCredited": 4.82,
      "merchantAccountDebited": null,
      "network": null,
      "transactionHash": null
    },
    "transaction": {
      "amount": null,
      "status": null,
      "isFinal": null,
      "orderId": null,
      "createdAt": null,
      "updatedAt": null,
      "isDebited": null,
      "merchantOrderId": "c1c1793a-cff9-4a4c-933f-3bbc218ec1c2"
    },
    "callBackUrl": "https://example.com/api/callback",
    "instanceExpired": 0,
    "manualSettlement": 0,
    "insufficientBalance": 0
  }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
  "data": {
    "user": {},
    "trade": {
      "utr": "",
      "cashierUTR": "",
      "tradeId": 987654,
      "isBuyTrade": 1,
      "isUTRNeeded": 1,
      "event": {
        "id": 2,
        "deadline": "2026-04-17T12:30:00Z",
        "description": "Seller Found, waiting for Buyer to make and confirm payment."
      },
      "createdAt": "2026-04-17T11:55:25Z",
      "updatedAt": "2026-04-17T11:55:54Z",
      "fiatCurrency": {
        "name": "Indian Rupee",
        "symbol": "INR"
      },
      "priceDetails": {
        "price": 97.0,
        "amount": 5.15,
        "paymentAmount": 500.0
      },
      "paymentMethod": {
        "details": {
          "qrString": "upi://pay?pa=merchant@upi&pn=Merchant%20Name&am=500&tn=TID987654%20AMT500&cu=INR",
          "upiAddress": "merchant@upi"
        }
      },
      "cryptoCurrency": {
        "name": "Tether",
        "symbol": "USDT"
      }
    },
    "accounts": {
      "transactionType": "pay-in",
      "localCurrency": "INR",
      "cryptoCurrencySymbol": "USDT",
      "conversionRate": 97.0,
      "MDR_Rate": 6.5,
      "amountPaidInLocalCurrency": 500.0,
      "amountPaidInCryptoCurrency": 5.154639175257732,
      "merchantAccountCredited": 4.82,
      "merchantAccountDebited": null,
      "network": null,
      "transactionHash": null
    },
    "transaction": {
      "amount": null,
      "status": null,
      "isFinal": null,
      "orderId": null,
      "createdAt": null,
      "updatedAt": null,
      "isDebited": null,
      "merchantOrderId": "c1c1793a-cff9-4a4c-933f-3bbc218ec1c2"
    },
    "callBackUrl": "https://example.com/api/callback",
    "instanceExpired": 0,
    "manualSettlement": 0,
    "insufficientBalance": 0
  }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
  "data": {
    "user": {},
    "trade": {
      "utr": "123456789012",
      "cashierUTR": "CASH123456", //Optional
      "tradeId": 987654,
      "isBuyTrade": 1,
      "isUTRNeeded": 1,
      "event": {
        "id": 3,
        "deadline": "2026-04-17T12:30:00Z",
        "description": "Payment Confirmed by Buyer. Seller Verifying Payment."
      },
      "createdAt": "2026-04-17T11:55:25Z",
      "updatedAt": "2026-04-17T11:56:02Z",
      "fiatCurrency": {
        "name": "Indian Rupee",
        "symbol": "INR"
      },
      "priceDetails": {
        "price": 97.0,
        "amount": 5.15,
        "paymentAmount": 500.0
      },
      "paymentMethod": {
        "details": {
          "qrString": "upi://pay?pa=merchant@upi&pn=Merchant%20Name&am=500&tn=TID987654%20AMT500&cu=INR",
          "upiAddress": "merchant@upi"
        }
      },
      "cryptoCurrency": {
        "name": "Tether",
        "symbol": "USDT"
      }
    },
    "accounts": {
      "transactionType": "pay-in",
      "localCurrency": "INR",
      "cryptoCurrencySymbol": "USDT",

      "conversionRate": 97.0,
      "MDR_Rate": 6.5,

      "amountPaidInLocalCurrency": 500.0,
      "amountPaidInCryptoCurrency": 5.154639175257732,

      "merchantAccountCredited": 4.82,
      "merchantAccountDebited": null,

      "network": "TRC20",
      "transactionHash": "0xabc123def456ghi789"
    },
    "transaction": {
      "amount": 500.0,
      "status": "pending",
      "isFinal": false,
      "orderId": "ORD123456",
      "merchantOrderId": "c1c1793a-cff9-4a4c-933f-3bbc218ec1c2",
      "createdAt": "2026-04-17T11:55:30Z",
      "updatedAt": "2026-04-17T11:56:10Z",
      "isDebited": false
    },
    "callBackUrl": "https://example.com/api/callback",
    "instanceExpired": 0,
    "manualSettlement": 0,
    "insufficientBalance": 0
  }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
  "data": {
    "user": {},
    "trade": {
      "utr": "123456789012",
      "cashierUTR": "CASH123456", //Optional
      "tradeId": 987654,
      "isBuyTrade": 1,
      "isUTRNeeded": 1,
      "event": {
        "id": 4,
        "deadline": "2026-04-17T12:30:00Z",
        "description": "Seller Acknowledges Payment Receipt. Trade Completed."
      },
      "createdAt": "2026-04-17T11:55:25Z",
      "updatedAt": "2026-04-17T11:56:15Z",
      "fiatCurrency": {
        "name": "Indian Rupee",
        "symbol": "INR"
      },
      "priceDetails": {
        "price": 97.0,
        "amount": 5.15,
        "paymentAmount": 500.0
      },
      "paymentMethod": {
        "details": {
          "qrString": "upi://pay?pa=merchant@upi&pn=Merchant%20Name&am=500&tn=TID987654%20AMT500&cu=INR",
          "upiAddress": "merchant@upi"
        }
      },
      "cryptoCurrency": {
        "name": "Tether",
        "symbol": "USDT"
      }
    },
    "accounts": {
      "transactionType": "pay-in",
      "localCurrency": "INR",
      "cryptoCurrencySymbol": "USDT",
      "conversionRate": 97.0,
      "MDR_Rate": 6.5,
      "amountPaidInLocalCurrency": 500.0,
      "amountPaidInCryptoCurrency": 5.154639175257732,
      "merchantAccountCredited": 4.82,
      "merchantAccountDebited": null,
      "network": "TRC20",
      "transactionHash": "0xabc123def456ghi789"
    },
    "transaction": {
      "amount": 4.82,
      "status": "Completed",
      "isFinal": 1,
      "orderId": "560b27c5-2474-40f9-bedd-a7962a60dfa1",
      "createdAt": "2026-04-17T11:56:15Z",
      "updatedAt": "2026-04-17T11:56:15Z",
      "isCredited": 1,
      "merchantOrderId": "c1c1793a-cff9-4a4c-933f-3bbc218ec1c2"
    },
    "callBackUrl": "https://example.com/api/callback",
    "instanceExpired": 0,
    "manualSettlement": 0,
    "insufficientBalance": 0
  }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the webhook.
* **Manual Retry:** In case of missed callbacks, use the tylt.monry dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?merchantOrderId={merchantOrderId}`

You may alternatively query using:

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?instanceId={instanceId}`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?merchantOrderId=dOf6cc25-e9f9-11ef-830e-02d8461243e9`

You may alternatively query using:

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?instanceId=X889Of6cc25-e9f9-11ef-830e-02d81243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-secret-key'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a GET request
def send_get_request(url, params):
    raw = '&'.join([f"{key}={value}" for key, value in params.items()])
    body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, body_string)

    headers = {
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }

    response = requests.get(f"{url}?{raw}", headers=headers)
    return response.json()

# Request parameters for GET request
get_params = {
    'instanceId': 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
}

# Send the GET request
get_response = send_get_request("https://api.tylt.money/p2pRampsMerchant/getInstanceDetails", get_params)
print(get_response)

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  instanceId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};
// This endpoint can be queried using either `merchantOrderId` or `instanceId` based on your preference.
const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}
{% hint style="info" %}
To better understand the payment process lifecycle and effectively utilize the data provided by the **Get Instance Information** API, refer to the detailed explanation of the event lifecycle [here](/tylt-crossramp-fiat-crypto-solutions/india-inr/upi-payin-inr-usdt/web-hook-upi-pay-in)
{% endhint %}

```json
{
    "msg": "",
    "data": {
        "trade": {
            "isBuyTrade":1,
            "event": {
                "id": null,
                "deadline": null,
                "description": null
            },
            "createdAt": null,
            "updatedAt": null,
            "fiatCurrency": {
                "name": null,
                "symbol": null
            },
            "priceDetails": {
                "price": null,
                "amount": null,
                "paymentAmount": null
            },
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": null,
                "symbol": null
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                                 | Type    | Description                                                                                                                                                                               |
| ------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| msg                                   | string  | Message providing additional context about the response.                                                                                                                                  |
| data                                  | object  | Container for the response data.                                                                                                                                                          |
| data.trade                            | object  | Details about the trade.                                                                                                                                                                  |
| data.trade.isBuyTrade                 | number  | Indicates if the trade is a buy trade (1 for buy, 0 for sell).                                                                                                                            |
| data.trade.event                      | object  | Contains event details related to the trade lifecycle.                                                                                                                                    |
| data.trade.event.id                   | number  | The event ID representing the current state of the trade. Read more about widget lifecycle [here](/tylt-crossramp-fiat-crypto-solutions/india-inr/upi-payin-inr-usdt/web-hook-upi-pay-in) |
| data.trade.event.deadline             | string  | Deadline for completing the trade, in ISO 8601 format.                                                                                                                                    |
| data.trade.event.description          | string  | A description of the eventId or its state.                                                                                                                                                |
| data.trade.createdAt                  | string  | Timestamp when the trade was created, in ISO 8601 format.                                                                                                                                 |
| data.trade.updatedAt                  | string  | Timestamp when the trade was last updated, in ISO 8601 format.                                                                                                                            |
| data.trade.fiatCurrency               | object  | Details about the fiat currency used in the trade.                                                                                                                                        |
| data.trade.fiatCurrency.name          | string  | Name of the fiat currency (e.g., Indian Rupee).                                                                                                                                           |
| data.trade.fiatCurrency.symbol        | string  | Symbol of the fiat currency (e.g., INR).                                                                                                                                                  |
| data.trade.priceDetails               | object  | Price-related details for the trade.                                                                                                                                                      |
| data.trade.priceDetails.price         | number  | The price per unit of the cryptocurrency in fiat currency.                                                                                                                                |
| data.trade.priceDetails.amount        | number  | The amount of cryptocurrency involved in the trade.                                                                                                                                       |
| data.trade.priceDetails.paymentAmount | number  | Total fiat payment amount for the trade.                                                                                                                                                  |
| data.trade.paymentMethod              | object  | Information about the payment method used.                                                                                                                                                |
| data.trade.paymentMethod.details      | string  | Details of the payment method (e.g., UPI).                                                                                                                                                |
| data.trade.cryptoCurrency             | object  | Details about the cryptocurrency used in the trade.                                                                                                                                       |
| data.trade.cryptoCurrency.name        | string  | Name of the cryptocurrency (e.g., US Theather).                                                                                                                                           |
| data.trade.cryptoCurrency.symbol      | string  | Symbol of the cryptocurrency (e.g., USDT).                                                                                                                                                |
| data.transaction                      | object  | Details about the associated transaction.                                                                                                                                                 |
| data.transaction.amount               | number  | The amount of fiat involved in the transaction.                                                                                                                                           |
| data.transaction.status               | string  | Current status of the transaction (e.g., Pending, Completed).                                                                                                                             |
| data.transaction.isFinal              | boolean | Indicates whether the transaction is in its final state.                                                                                                                                  |
| data.transaction.orderId              | string  | Unique identifier for the transaction.                                                                                                                                                    |
| data.transaction.createdAt            | string  | Timestamp when the transaction was created, in ISO 8601 format.                                                                                                                           |
| data.transaction.updatedAt            | string  | Timestamp when the transaction was last updated, in ISO 8601 format.                                                                                                                      |
| data.transaction.isCredited           | boolean | Indicates if the amount has been credited to the merchant.                                                                                                                                |
| data.transaction.merchantOrderId      | string  | Merchant-provided unique identifier for the transaction.                                                                                                                                  |
| data.user                             | object  | User-related information provided by the Merchant.                                                                                                                                        |

{% endtab %}
{% endtabs %}


# Get Pay-In Transaction Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `orderId` is required, and it corresponds to the unique identifier generated by Tylt for the transaction.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?`orderId={orderId}

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?orderId=a49579dd-7711-11ef-8277-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="182">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);

const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-secret-key'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a GET request
def send_get_request(url, params):
    raw = '&'.join([f"{key}={value}" for key, value in params.items()])
    body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, body_string)

    headers = {
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }

    response = requests.get(f"{url}?{raw}", headers=headers)
    return response.json()

# Function to send a POST request
def send_post_request(url, params):
    body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, body_string)

    headers = {
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature,
        'Content-Type': 'application/json'
    }

    response = requests.post(url, headers=headers, data=body_string)
    return response.json()

# Request parameters for GET request
get_params = {
    'orderId': 'a49579dd-7711-11ef-8277-02d8461243e9'
}

# Request parameters for POST request
post_params = {
    'orderId': '38054005-fb53-11ef-bcfd-42010a280107'
}

# Send the GET request
get_response = send_get_request("https://api.tylt.money/transactions/merchant/getPayinTransactionInformation", get_params)
print(get_response)

# Send the POST request
post_response = send_post_request("https://api.tylt.money/transactions/merchant/getPayinTransactionInformation", post_params)
print(post_response)




```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);

const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": {
        "orderId": "a49579dd-7711-11ef-8277-02d8461243e9",
        "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
        "baseAmount": 1,
        "baseCurrency": "USDT",
        "settledCurrency": "USDT",
        "settledAmountRequested": 1,
        "settledAmountReceived": 0,
        "settledAmountCredited": 0,
        "commission": 0.01,
        "network": "BSC",
        "depositAddress": "0xdbfc3d80de367906ccb456fe2eed57c39f05f63c",
        "status": "Expired",
        "paymentURL": "https://app.tylt.money/pscreen/a49579dd-7711-11ef-8277-02d8461243e9",
        "callBackURL": "",
        "transactions": [],
        "createdAt": "2024-09-20T05:31:53Z",
        "expiresAt": "2024-09-20T06:31:53Z",
        "updatedAt": "2024-09-20T06:31:56Z",
        "isFinal": 1,
        "isCredited": 0,
        "customerName": "TradingLeagues",
        "comments": "Description testing 234"
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                     |
| ------------------------ | -------- | ----------------------------------------------------------------------------------- |
| `orderId`                | string   | The order ID generated by TL Pay, used as a global identifier for the transaction.  |
| `merchantOrderId`        | string   | The order ID provided by the Merchant, used for local reference (optional).         |
| `baseAmount`             | number   | The base value of the good/service being supplied.                                  |
| `baseCurrency`           | string   | The base currency of the good/service being supplied.                               |
| `settledCurrency`        | string   | The cryptocurrency/token in which the payment is to be made by the customer.        |
| `settledAmountRequested` | number   | The amount of cryptocurrency/token requested from the customer.                     |
| `settledAmountReceived`  | number   | The amount of cryptocurrency/token received from the customer.                      |
| `settledAmountCredited`  | number   | The amount of cryptocurrency/token credited to the merchant's balance (net).        |
| `commission`             | number   | The commission deducted for the transaction.                                        |
| `network`                | string   | The cryptocurrency network over which the payment is made.                          |
| `depositAddress`         | string   | The address for receiving the payment.                                              |
| `status`                 | string   | The status of the transaction (e.g., Expired, Pending, Completed).                  |
| `paymentURL`             | string   | The payment link that needs to be used by the customer to make the payment.         |
| `callBackURL`            | string   | The callback URL for post-payment notifications (if applicable).                    |
| `transactions`           | array    | Details of the transactions resulting in the payment (if any).                      |
| `createdAt`              | string   | The timestamp when the transaction was created.                                     |
| `expiresAt`              | string   | The timestamp when the transaction expires.                                         |
| `updatedAt`              | string   | The timestamp when the transaction was last updated.                                |
| `isFinal`                | number   | Indicates if the transaction is complete (1) or still processing (0).               |
| `isCredited`             | number   | Indicates if the payment has been credited to the merchant account (1: Yes, 0: No). |
| `customerName`           | string   | The name of the customer provided by the merchant (optional).                       |
| `comments`               | string   | Comments provided by the merchant about the transaction (optional).                 |
| {% endtab %}             |          |                                                                                     |
| {% endtabs %}            |          |                                                                                     |


# UPI Payin (INR → USDT) | H2H

This section provides a reference for integrating Tylt CrossRamp’s UPI on-ramp flow via a host-to-host (H2H) integration. Through this integration, merchants can directly orchestrate on-ramp flows using API calls, without relying on the hosted widget. End-user INR transfers are facilitated through a peer-to-peer (P2P) network of liquidity providers, enabling the acquisition of stablecoins which are subsequently transferred to the merchant.

***

#### Flow Overview

* Merchant initiates on-ramp instances via API
* End users complete UPI transfers through P2P-matched counterparties
* Fiat leg is executed via the P2P network of liquidity providers
* Upon confirmation, crypto-asset conversion is executed
* Resulting USDT is transferred to the merchant

***

#### What You’ll Find in the API Reference

**1. UPI On-Ramp Flow (INR → USDT)**\
Guidance for initiating and managing on-ramp flows via API, including lifecycle tracking and reconciliation.

**2. Supporting APIs**\
Documentation for auxiliary endpoints, including supported currencies, networks, and system capabilities.

**3. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and integration patterns.

**4. Request & Response Formats**\
Structured JSON examples covering on-ramp creation, status tracking, webhook payloads, and error handling.

**5. Code Examples**\
Reference implementations in Node.js, Python, and other commonly used stacks.

**6. Error Handling**\
Common error scenarios, causes, and recommended handling strategies.

***

#### Summary

This API enables merchants to integrate UPI-based on-ramp functionality via direct API communication, allowing end users to acquire stablecoins through P2P-facilitated fiat flows, with settlement managed in USDT through Tylt’s crypto-asset infrastructure


# Create a Pay-in Instance

This endpoint allows you to create a new payment instance and receive a in the response an `instanceId.`The instanceId can be used further along with the other exposed API's to create a completely customisable host to host integration.&#x20;

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/h2h/in/upi/createPayinInstance`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="201"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td>Custom fields associated with the user, supplied by the merchant. These fields are included in webhook notifications and other API responses for easy reference and tracking. An empty object can be sent.</td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td><strong>Mandatory</strong>.A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td><strong>Mandatory</strong>.The URL to which payment status updates are sent.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td><strong>Mandatory</strong>. This is the amount the user wants to deposit in USDT or INR equivalent. If this field is empty user can enter the value in the payment flow. </td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td><strong>Mandatory</strong>. Supported Currency is "USDT" or "INR" only.</td></tr><tr><td><code>userEmail</code></td><td><code>string</code></td><td><strong>Mandatory</strong>. The emailId of the end user.</td></tr><tr><td><code>isKYCNeeded</code></td><td><code>number</code></td><td>1 or 0. If set to 0 the user will not be required to complete KYC or provide KYC. If field is in passed, default behaviour is KYC is required. This bypass needs to be approved by the admin for the Merchant.</td></tr><tr><td><code>isUTRNeeded</code></td><td>number</td><td>To be set <mark style="color:green;"><code>Mandatorily</code></mark> as 1.  The user will be required to provide the UTR (Unique Transaction Reference) number after making the payment. This is a <mark style="color:green;"><code>recommended</code></mark> setting as it significantly reduces payment failures, disputes, and chargebacks while also enabling seamless processing through our automated Lightning Bridge.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Flow Modularity**

1. **KYC Bypass**:
   * In certain use cases, KYC verification may not be required for the end user.
   * To bypass KYC, set `isKYCNeeded` to 0.
   * When enabled, the user will not be required to complete KYC, and any existing KYC records will not be checked.
   * **Important:** Merchants must have admin pre-authorisation to use the KYC bypass feature.
     {% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    userDetails: {},
    amount: 500,
    currencySymbol: 'INR',
    merchantOrderId: crypto.randomUUID(),
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    userEmail: 'test@test.com',
    isKYCNeeded: 0,
    isUTRNeeded:1,
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
<strong>    "Content-Type": "application/json",
</strong>    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/h2h/in/upi/createPayinInstance', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json
import uuid

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body
request_body = {
    "userDetails": {},
    "amount": 500,
    "currencySymbol": 'INR',
    "merchantOrderId": str(uuid.uuid4()),
    "callBackUrl": 'https://www.test.com/callback',
    "redirectUrl": 'https://www.test.com/callback',
    "userEmail": 'test@test.com',
    "isKYCNeeded": 0,
    "isUTRNeeded": 1,
}

# Convert request body to JSON
raw = json.dumps(request_body, separators=(',', ':'), ensure_ascii=False)

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Generate signature
signature = create_signature(api_secret, raw)

# Define headers
headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the request
response = requests.post('https://api.tylt.money/h2h/in/upi/createPayinInstance', headers=headers, data=raw)
print("Response:", response.json())

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "Trade created successfully.",
    "data": {
        "instanceId": "51138bbb-fe4e-11ef-bcfd-42010a280107",
        "tradeId": 2081,
        "accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 215.04999999999998,
            "localCurrency": "INR",
            "conversionRate": 93.5,
            "amountPaidInCryptoCurrency": 2.3,
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 4,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        }
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>instanceId</td><td>string</td><td>The instance ID generated by Tylt, used as a global identifier. </td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Buyer Confirms Payment

This endpoint is to be called by the end user of the Merchant after the user has made the payment to the cashier using the provided payment instructions. The payment instructions are received over the callBackUrl when the Cashier has accepted the order request.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/h2h/in/upi/buyerConfirmsPayment`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="201"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>instanceId</code></td><td><code>string</code></td><td><strong>Mandatory</strong>. This is the instanceId of the trade and it is returned as a respnse to the createPayinInstance API.</td></tr><tr><td><code>utr</code></td><td>number</td><td>Mandatory if <code>isUTRNeeded</code> flag is set to 1 at the time of calling <code>createPayinInstance</code></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    "instanceId":'51138bbb-fe4e-11ef-bcfd-42010a280107',
    "utr":'123456789012'
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/h2h/in/upi/buyerConfirmsPayment', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body
request_body = {
    "instanceId":'51138bbb-fe4e-11ef-bcfd-42010a280107',
    "utr":'123456789012'
};

# Convert request body to JSON
raw = json.dumps(request_body, separators=(',', ':'), ensure_ascii=False)

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Generate signature
signature = create_signature(api_secret, raw)

# Define headers
headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the request
response = requests.post('https://api.tylt.money/h2h/in/upi/buyerConfirmsPayment', headers=headers, data=raw)
print("Response:", response.json())

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "success",
    "data": {
        "tradeId": 2081
    },
    "msg": "Payment confirmed successfully."
}
```

{% endtab %}
{% endtabs %}


# Web-hook: UPI Pay-In

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:<br>

   <table data-header-hidden><thead><tr><th width="100"></th><th></th></tr></thead><tbody><tr><td><strong><code>eventId</code></strong></td><td><strong>Description</strong></td></tr><tr><td><strong><code>0</code></strong></td><td>The instance is created. User is yet to interact with the instance.</td></tr><tr><td><strong><code>1</code></strong></td><td>Trade initiated.</td></tr><tr><td><strong><code>2</code></strong></td><td>Waiting for the buyer to make and confirm payment via UPI.</td></tr><tr><td><strong><code>3</code></strong></td><td>Buyer confirms making payment. Seller is verifying the payment.</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment acknowledged and trade completed.</td></tr><tr><td><strong><code>5</code></strong></td><td>Payment disputed. Trade moved to dispute.</td></tr><tr><td><strong><code>6</code></strong></td><td>Payment acknowledged and trade completed by the system.</td></tr><tr><td><strong><code>9</code></strong></td><td>Trade expired as action or payment was not completed prior to the deadline.</td></tr></tbody></table>

{% hint style="info" %}

### Instance Information

The response related to an instance information contains two primary objects:

#### 1. Trade Object

This object contains all the information about the customer buying or selling USDT from the counterparty. It includes fields like:

* Trade lifecycle details (`eventId`, deadlines, description).
* Fiat and cryptocurrency details (currency name, symbol, amount, etc.).
* Payment method information (e.g., UPI).

#### 2. Transaction Object

This object contains all the information about the financial debit or credit carried out on the merchant's account. It is relevant to merchants for crediting or debiting a consumer for the transaction. The `transaction` object is updated **only when the `eventId` is 4**, representing the completion of the trade
{% endhint %}

4. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
5. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.accounts.transactionType === 'pay-in') {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import hmac
import hashlib
import json


app = Flask(__name__)

# Your TL Pay API Secret Key
TLP_API_SECRET_KEY = 'YOUR_TLP_API_SECRET_KEY'  # Replace with your actual API secret key

@app.route('/callback', methods=['POST'])
def callback():
    # Get the raw request data for HMAC calculation
    raw_data = json.dumps(request.get_json(), separators=(',', ':'), ensure_ascii=False)

    # Parse JSON data from the request
    data = request.get_json()

    # Retrieve the signature from the request headers
    tlp_signature = request.headers.get('X-TLP-SIGNATURE')

    # Calculate the HMAC SHA-256 signature
    calculated_hmac = hmac.new(
        key=TLP_API_SECRET_KEY.encode(),
        msg=raw_data,
        digestmod=hashlib.sha256
    ).hexdigest()

    # Compare the calculated HMAC signature with the one in the request header
    if hmac.compare_digest(calculated_hmac, tlp_signature):
        # Signature is valid
        if data['accounts']['transactionType'] == 'pay-in':
            print('Received pay-in callback:', data)
            # Process pay-in data here
            
        # Return HTTP Response 200 with content "ok"
        return jsonify({"message": "ok"}), 200
    else:
        # Invalid HMAC signature
        return jsonify({"error": "Invalid HMAC signature"}), 400

if __name__ == '__main__':
    app.run(port=3000, debug=True)

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: null" %}

```json
{
    "data": {
        "trade": {
            "isBuyTrade":1,
            "event": {
                "id": null,
                "deadline": null,
                "description": null
            },
            "createdAt": null,
            "updatedAt": null,
            "fiatCurrency": {
                "name": null,
                "symbol": null
            },
            "priceDetails": {
                "price": null,
                "amount": null,
                "paymentAmount": null
            },
            "paymentMethod": {
                "details": null
            },           },
            "cryptoCurrency": {
                "name": null,
                "symbol": null
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
         "accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 196.35,
            "localCurrency": "INR",
            "conversionRate": 93.5,
            "amountPaidInCryptoCurrency": 2.1,
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 4,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        }
        "user": {}
    }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 1" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 1,
                "deadline": "2025-02-12T05:27:37Z",
                "description": "Trade Initiated. Finding Seller."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:24:37Z",
            "fiatCurrency": {
                "name": "Indian Rupee",
                "symbol": "INR"
            },
            "priceDetails": {
                "price": 93.5,
                "amount": 1,
                "paymentAmount": 93.5
            },
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 2,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Seller Found, waiting for Buyer to make and confirm payment."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Indian Rupee",
                "symbol": "INR"
            },
            "priceDetails": {
                "price": 93.5,
                "amount": 1,
                "paymentAmount": 93.5
            },
            "paymentMethod": {
                "details": {
                    "upiAddress": "p2ptrade@upi",
                    "qrString": "upi://pay?pa=p2ptrade@upi&pn=&am=215.04999999999998&cu=INR"
                }
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isDebited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
        "user": {}
    }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 3,
                "deadline": "2025-02-12T05:30:25Z",
                "description": "Payment Confirmed by Buyer. Seller Verifying Payment."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:25Z",
            "fiatCurrency": {
                "name": "Indian Rupee",
                "symbol": "INR"
            },
            "priceDetails": {
                "price": 93.5,
                "amount": 1,
                "paymentAmount": 93.5
            },
            "paymentMethod": {
                "details": {
                    "upiAddress": "p2ptrade@upi",
                    "qrString": "upi://pay?pa=p2ptrade@upi&pn=&am=215.04999999999998&cu=INR"
                }
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isDebited": null,
            "updatedAt": null,
            "merchantOrderId": null
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 4,
                "deadline": "2025-02-12T05:25:45Z",
                "description": "Seller Acknowledges Payment Receipt. Trade Completed."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:45Z",
            "fiatCurrency": {
                "name": "Indian Rupee",
                "symbol": "INR"
            },
            "priceDetails": {
                "price": 93.5,
                "amount": 1,
                "paymentAmount": 93.5
            },
            "paymentMethod": {
                "details": {
                    "upiAddress": "p2ptrade@upi",
                    "qrString": "upi://pay?pa=p2ptrade@upi&pn=&am=215.04999999999998&cu=INR"
                }
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": 0.998,
            "status": "Completed",
            "isFinal": 1,
            "orderId": "b61fedfd-e901-11ef-830e-02d8461243e9",
            "createdAt": "2025-02-12T05:25:45Z",
            "updatedAt": "2025-02-12T05:25:45Z",
            "isCredited": 1,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
        },
        "user": {}
    }
}
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the webhook.
* **Manual Retry:** In case of missed callbacks, use the tylt.monry dashboard to manually resend the webhook.
  {% endhint %}


# Get Instance Details

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction instance. The `merchantOrderId` is required, and it corresponds to the unique identifier generated by merchant at the time of creating a payment instance.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?{instanceId}`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?dOf6cc25-e9f9-11ef-830e-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

const params = {
  instanceId: 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
<strong>const url = `https://api.tylt.money/p2pRampsMerchant/getInstanceDetails?${queryString}`;
</strong>const apiKey = 'your-api-key';
const apiSecret = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', apiSecret)
  .update(signaturePayload)
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

</code></pre>

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hashlib
import hmac
import json

url = "https://api.tylt.money/p2pRampsMerchant/getInstanceDetails"

params = {
  "instanceId": 'dOf6cc25-e9f9-11ef-830e-02d8461243e9'
};

api_key = 'your-api-key'
secret_key = 'your-secret-key'

query_string = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)

signature = hmac.new(secret_key.encode(), body_string.encode(), hashlib.sha256).hexdigest()

headers = {
    'Content-Type': 'application/json',
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature
}

response = requests.get(url, headers=headers, params=params)
print(response.text)

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="Response Example" %}
{% hint style="info" %}
To better understand the payment process lifecycle and effectively utilize the data provided by the **Get Instance Information** API, refer to the detailed explanation of the event lifecycle [here](/tylt-crossramp-fiat-crypto-solutions/india-inr/upi-payin-inr-usdt/web-hook-upi-pay-in)
{% endhint %}

```json
{
    "msg": "",
    "data": {
        "trade": {
            "event": {
                "id": 4,
                "deadline": "2025-03-11T07:57:20Z",
                "description": "Seller Acknowledges Payment Receipt. Trade Completed."
            },
            "createdAt": "2025-03-11T07:56:19Z",
            "updatedAt": "2025-03-11T07:57:20Z",
            "isBuyTrade": 1,
            "fiatCurrency": {
                "name": "Indian Rupee",
                "symbol": "INR"
            },
            "priceDetails": {
                "price": 93.5,
                "amount": 2.3,
                "paymentAmount": 215.04999999999998
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            },
            "paymentMethod": {
                 "details": {
                    "upiAddress": "p2ptrade@upi",
                    "qrString": "upi://pay?pa=p2ptrade@upi&pn=&am=215.04999999999998&cu=INR"
                }
            }
        },
        "transaction": {
            "amount": 2.2079999999999997,
            "status": "Completed",
            "isFinal": 1,
            "orderId": "538ffd9a-fe4e-11ef-bcfd-42010a280107",
            "createdAt": "2025-03-11T07:57:20Z",
            "updatedAt": "2025-03-11T07:57:22Z",
            "isCredited": 1,
            "merchantOrderId": "merchant-test-111"
        },
        "accounts": {
            "MDR_Rate": 4,
            "localCurrency": "INR",
            "transactionType": "pay-in",
            "merchantAccountDebited": null,
            "merchantAccountCredited": 2.2079999999999997,
            "amountPaidInLocalCurrency": 215.04999999999998,
            "cryptoCurrencySymbol": "USDT",
            "amountPaidInCryptoCurrency": 2.3,
            "conversionRate": 93.5
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field                                 | Type    | Description                                                                                                                                                                               |
| ------------------------------------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| msg                                   | string  | Message providing additional context about the response.                                                                                                                                  |
| data                                  | object  | Container for the response data.                                                                                                                                                          |
| data.trade                            | object  | Details about the trade.                                                                                                                                                                  |
| data.trade.isBuyTrade                 | number  | Indicates if the trade is a buy trade (1 for buy, 0 for sell).                                                                                                                            |
| data.trade.event                      | object  | Contains event details related to the trade lifecycle.                                                                                                                                    |
| data.trade.event.id                   | number  | The event ID representing the current state of the trade. Read more about widget lifecycle [here](/tylt-crossramp-fiat-crypto-solutions/india-inr/upi-payin-inr-usdt/web-hook-upi-pay-in) |
| data.trade.event.deadline             | string  | Deadline for completing the trade, in ISO 8601 format.                                                                                                                                    |
| data.trade.event.description          | string  | A description of the eventId or its state.                                                                                                                                                |
| data.trade.createdAt                  | string  | Timestamp when the trade was created, in ISO 8601 format.                                                                                                                                 |
| data.trade.updatedAt                  | string  | Timestamp when the trade was last updated, in ISO 8601 format.                                                                                                                            |
| data.trade.fiatCurrency               | object  | Details about the fiat currency used in the trade.                                                                                                                                        |
| data.trade.fiatCurrency.name          | string  | Name of the fiat currency (e.g., Indian Rupee).                                                                                                                                           |
| data.trade.fiatCurrency.symbol        | string  | Symbol of the fiat currency (e.g., INR).                                                                                                                                                  |
| data.trade.priceDetails               | object  | Price-related details for the trade.                                                                                                                                                      |
| data.trade.priceDetails.price         | number  | The price per unit of the cryptocurrency in fiat currency.                                                                                                                                |
| data.trade.priceDetails.amount        | number  | The amount of cryptocurrency involved in the trade.                                                                                                                                       |
| data.trade.priceDetails.paymentAmount | number  | Total fiat payment amount for the trade.                                                                                                                                                  |
| data.trade.paymentMethod              | object  | Information about the payment method used.                                                                                                                                                |
| data.trade.paymentMethod.details      | string  | Details of the payment method (e.g., UPI).                                                                                                                                                |
| data.trade.cryptoCurrency             | object  | Details about the cryptocurrency used in the trade.                                                                                                                                       |
| data.trade.cryptoCurrency.name        | string  | Name of the cryptocurrency (e.g., US Theather).                                                                                                                                           |
| data.trade.cryptoCurrency.symbol      | string  | Symbol of the cryptocurrency (e.g., USDT).                                                                                                                                                |
| data.transaction                      | object  | Details about the associated transaction.                                                                                                                                                 |
| data.transaction.amount               | number  | The amount of fiat involved in the transaction.                                                                                                                                           |
| data.transaction.status               | string  | Current status of the transaction (e.g., Pending, Completed).                                                                                                                             |
| data.transaction.isFinal              | boolean | Indicates whether the transaction is in its final state.                                                                                                                                  |
| data.transaction.orderId              | string  | Unique identifier for the transaction.                                                                                                                                                    |
| data.transaction.createdAt            | string  | Timestamp when the transaction was created, in ISO 8601 format.                                                                                                                           |
| data.transaction.updatedAt            | string  | Timestamp when the transaction was last updated, in ISO 8601 format.                                                                                                                      |
| data.transaction.isCredited           | boolean | Indicates if the amount has been credited to the merchant.                                                                                                                                |
| data.transaction.merchantOrderId      | string  | Merchant-provided unique identifier for the transaction.                                                                                                                                  |
| data.user                             | object  | User-related information provided by the Merchant.                                                                                                                                        |

{% endtab %}
{% endtabs %}


# Get Pay-In Transaction Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `orderId` passed as params in the request can be either:

1. The `orderId` generated and returned by the **getInstanceDetails** API.
2. The `merchantOrderId` provided by the merchant when calling the **createPayinInstance** API.

{% hint style="warning" %}
For Pay-In transactions, this endpoint should only be called after the transaction has been completed.
{% endhint %}

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?`orderId={orderId}

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?orderId=a49579dd-7711-11ef-8277-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const apiSecret = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', apiSecret)
  .update(signaturePayload)
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'Content-Type': "application/json",
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hashlib
import hmac
import json

url = "https://api.tylt.money/transactions/merchant/getPayinTransactionInformation"

params = {
    "orderId": 'a49579dd-7711-11ef-8277-02d8461243e9'
}

api_key = 'your-api-key'
secret_key = 'your-secret-key'

query_string = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)

signature = hmac.new(secret_key.encode(), body_string.encode(), hashlib.sha256).hexdigest()

headers = {
    'Content-Type': 'application/json'
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature
}

response = requests.get(url, headers=headers, params=params)
print(response.text)


```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": {
        "orderId": "538ffd9a-fe4e-11ef-bcfd-42010a280107",
        "merchantOrderId": "merchant-test-111",
        "baseAmount": 2.208,
        "baseCurrency": "USDT",
        "settledCurrency": "USDT",
        "settledAmountRequested": 2.208,
        "settledAmountReceived": 2.208,
        "settledAmountCredited": 2.208,
        "commission": 0,
        "network": "TPNK",
        "depositAddress": "",
        "status": "Completed",
        "paymentURL": "",
        "redirectURL": "",
        "callBackURL": "",
        "transactions": [],
        "createdAt": "2025-03-11T07:57:20Z",
        "expiresAt": "2025-03-11T07:57:20Z",
        "updatedAt": "2025-03-11T07:57:22Z",
        "isFinal": 1,
        "isCredited": 1,
        "customerName": "",
        "comments": "",
        "accounts": {
            "MDR_Rate": 4,
            "localCurrency": "INR",
            "transactionType": "pay-in",
            "merchantAccountDebited": null,
            "merchantAccountCredited": 2.2079999999999997,
            "amountPaidInLocalCurrency": 215.04999999999998,
            "cryptoCurrencySymbol": "USDT",
            "amountPaidInCryptoCurrency": 2.3,
            "conversionRate": 93.5
        }
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                     |
| ------------------------ | -------- | ----------------------------------------------------------------------------------- |
| `orderId`                | string   | The order ID generated by TL Pay, used as a global identifier for the transaction.  |
| `merchantOrderId`        | string   | The order ID provided by the Merchant, used for local reference (optional).         |
| `baseAmount`             | number   | The base value of the good/service being supplied.                                  |
| `baseCurrency`           | string   | The base currency of the good/service being supplied.                               |
| `settledCurrency`        | string   | The cryptocurrency/token in which the payment is to be made by the customer.        |
| `settledAmountRequested` | number   | The amount of cryptocurrency/token requested from the customer.                     |
| `settledAmountReceived`  | number   | The amount of cryptocurrency/token received from the customer.                      |
| `settledAmountCredited`  | number   | The amount of cryptocurrency/token credited to the merchant's balance (net).        |
| `commission`             | number   | The commission deducted for the transaction.                                        |
| `network`                | string   | The cryptocurrency network over which the payment is made.                          |
| `depositAddress`         | string   | The address for receiving the payment.                                              |
| `status`                 | string   | The status of the transaction (e.g., Expired, Pending, Completed).                  |
| `paymentURL`             | string   | The payment link that needs to be used by the customer to make the payment.         |
| `callBackURL`            | string   | The callback URL for post-payment notifications (if applicable).                    |
| `transactions`           | array    | Details of the transactions resulting in the payment (if any).                      |
| `createdAt`              | string   | The timestamp when the transaction was created.                                     |
| `expiresAt`              | string   | The timestamp when the transaction expires.                                         |
| `updatedAt`              | string   | The timestamp when the transaction was last updated.                                |
| `isFinal`                | number   | Indicates if the transaction is complete (1) or still processing (0).               |
| `isCredited`             | number   | Indicates if the payment has been credited to the merchant account (1: Yes, 0: No). |
| `customerName`           | string   | The name of the customer provided by the merchant (optional).                       |
| `comments`               | string   | Comments provided by the merchant about the transaction (optional).                 |
| {% endtab %}             |          |                                                                                     |
| {% endtabs %}            |          |                                                                                     |


# Get List of Fiat Currency and Supported Payment Methods

This endpoint allows you to retrieve detailed information the list of supported Fiat Currency and the relevent payment methods that can be used on Tylt CrossRamp.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/h2h/in/upi/getPaymentMethods_p2pOnRamp`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');


const url = `https://api.tylt.money/h2h/in/upi/getPaymentMethods_p2pOnRamp`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

// Create HMAC SHA-256 signature (no params for this request)
const signature = crypto
  .createHmac('sha256', secretKey)
  .update('{}') // No parameters to sign
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'Content-Type': "application/json",
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# API Keys
api_key = "your-api-key"
api_secret = "your-secret-key"

# API Endpoint
url = "https://api.tylt.money/h2h/in/upi/getPaymentMethods_p2pOnRamp"

# Request Payload (Params)
params = {}

# Create the signature based on JSON body
def create_signature(api_secret, params_string):
    return hmac.new(
        api_secret.encode('utf-8'),
        params_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

# Convert payload to JSON string in a consistent format
params_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
signature = create_signature(api_secret, params_string)

# Headers
headers = {
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature,
    'Content-Type': 'application/json'
}

# Make the request (assuming it should be POST)
response = requests.post(url, headers=headers, data=params_string)

response = requests.get(url, headers=headers, params=params)
print(response.text)


```

{% endtab %}
{% endtabs %}

**Response**

```json
{
    "status": "success",
    "msg": "P2P OnRamp payment methods retrieved successfully.",
    "data": [
        {
            "currencySymbol": "INR",
            "currencyName": "Indian rupee",
            "precisionDecimal": 2,
            "paymentGroups": [
                {
                    "paymentGroup": "UPI Transfer"
                }
            ]
        }
    ]
}
```

{% tabs %}
{% tab title="Response Fields" %}

| **Field Name**               | **Type** | **Description**                                                                                   |
| ---------------------------- | -------- | ------------------------------------------------------------------------------------------------- |
| `currencySymbol`             | string   | The symbol of the Fiat Currency. This is to be used in other API's such as createInstance.        |
| `currencyName`               | string   | The name of the fiat currency. This is used for display purpose.                                  |
| `precisionDecimal`           | string   | The input precisionDecimal concerning the fiat currency.                                          |
| `paymentGroups`              | string   | Contains the list of the supported payment methods for the said fiat currency. This is an object. |
| `paymentGroups.paymentGroup` | string   | The name of the payment method                                                                    |
| {% endtab %}                 |          |                                                                                                   |
| {% endtabs %}                |          |                                                                                                   |


# Get List of Supported Crypto Currency for Settlement

This endpoint allows you to retrieve detailed information the list of supported Crypto Currency in which the payment transaction will be finally settled to the Merchant Account.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/h2h/in/upi/getCryptoCurrencyListForPrime`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');


const url = `https://api.tylt.money/h2h/in/upi/getCryptoCurrencyListForPrime`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

// Create HMAC SHA-256 signature (no params for this request)
const signature = crypto
  .createHmac('sha256', secretKey)
  .update('{}') // No parameters to sign
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'Content-Type': "application/json",
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# API Keys
api_key = "your-api-key"
api_secret = "your-secret-key"

# API Endpoint
url = "https://api.tylt.money/h2h/in/upi/getCryptoCurrencyListForPrime"

# Request Payload (Params)
params = {}

# Create the signature based on JSON body
def create_signature(api_secret, params_string):
    return hmac.new(
        api_secret.encode('utf-8'),
        params_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

# Convert payload to JSON string in a consistent format
params_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
signature = create_signature(api_secret, params_string)

# Headers
headers = {
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature,
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers, params=params)
print(response.text)
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": [
        {
            "cryptoCurrencySymbol": "USDT",
            "cryptoCurrencyName": "Tether",
            "minAmount": 1,
            "maxAmount": 1000000,
            "precisionDecimal": 2
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Get Conversion Rates

This endpoint allows you to retrieve detailed information the list of supported Crypto Currency in which the payment transaction will be finally settled to the Merchant Account.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/h2h/in/upi/getMerchantRampSpecialRates`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');


const url = `https://api.tylt.money/h2h/in/upi/getMerchantRampSpecialRates`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

// Create HMAC SHA-256 signature (no params for this request)
const signature = crypto
  .createHmac('sha256', secretKey)
  .update('{}') // No parameters to sign
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'Content-Type': "application/json",
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# API Keys
api_key = "your-api-key"
api_secret = "your-secret-key"

# API Endpoint
url = "https://api.tylt.money/h2h/in/upi/getMerchantRampSpecialRates"

# Request Payload (Params)
params = {}

# Create the signature based on JSON body
def create_signature(api_secret, params_string):
    return hmac.new(
        api_secret.encode('utf-8'),
        params_string.encode('utf-8'),
        hashlib.sha256
    ).hexdigest()

# Convert payload to JSON string in a consistent format
params_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)
signature = create_signature(api_secret, params_string)

# Headers
headers = {
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature,
    'Content-Type': 'application/json'
}

response = requests.get(url, headers=headers, params=params)
print(response.text)

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "status": "success",
    "data": [
        {
            "fiatCurrencySymbol": "INR", 
            "cryptoCurrencySymbol": "USDT", 
            "buyRate": 93.5,  // deposit and pay-in
            "sellRate": 90.5 // withdrawal and pay-out
        }
    ]
}
```

{% endtab %}
{% endtabs %}


# Brazil (BRL)

Tylt CrossRamp enables merchants to embed on-ramp and off-ramp functionality using PIX rails in Brazil, with settlement in USDT. CrossRamp operates as an embedded crypto exchange and transfer layer, allowing end users to acquire and dispose of stablecoins via local payment methods, while merchants receive and manage balances in USDT.

#### Supported Flows

CrossRamp supports two primary interaction flows:&#x20;

1. End users initiate PIX transfers to acquire stablecoins, which are transferred to the merchant
2. Merchants transfer stablecoins to end users, who subsequently convert the received crypto-assets into BRL via PIX.

***

#### Settlement Modes

Tylt CrossRamp supports two settlement configurations for PIX-based flows:

**1. Daily Settlement**

* Stablecoin balances are updated following successful transaction completion
* Balances are aggregated and reconciled through a daily settlement cycle
* Merchants can utilise their USDT balance for transfers, off-ramp flows, or treasury operations

***

**2. Instant Settlement**

* Stablecoins are transferred directly to the merchant’s external wallet on a per-transaction basis
* No balance is maintained within Tylt for these transactions
* Network fees may apply due to on-chain transfers
* For subsequent off-ramp flows, merchants must maintain or transfer USDT back into the Tylt system

***

#### Low-Code Integration (PIX – Brazil)

Tylt CrossRamp provides a **low-code integration** for embedding PIX-based on-ramp and off-ramp flows within merchant applications.

This approach enables:

* Rapid integration with minimal development effort
* Pre-built interface for end-user transaction initiation
* Standardised flows across supported regions
* Integrated compliance stack (AML, KYC, Travel Rule)
* Reduced integration and operational complexity


# PIX Payin (BRL→ USDT)

#### API Reference — PIX (BRL → USDT)

This section provides a reference for integrating Tylt CrossRamp’s PIX on-ramp flow within merchant applications. Through this integration, end users can initiate BRL transfers via PIX, which are used to facilitate the acquisition of stablecoins. The resulting USDT is transferred to the merchant’s Tylt wallet.

***

#### Settlement Models

This service supports two settlement configurations:

**Daily Settlement**

* Stablecoin balances are updated following successful transaction completion
* Balances are aggregated and reconciled through a daily settlement cycle
* Funds are reflected in the merchant’s Tylt wallet balance

***

### What You’ll Find in the API Reference

**1. PIX On-Ramp Flow**\
Guidance for enabling end users to initiate BRL transfers via PIX and complete cross-ramp transactions, including transaction lifecycle tracking and settlement visibility.

**2. Endpoint Descriptions**\
Detailed specifications for all API endpoints, including parameters, authentication requirements, and sample requests.

**3. Request & Response Formats**\
Structured JSON examples covering cross-ramp creation, status retrieval, webhook payloads, and error handling.

**4. Code Examples**\
Reference implementations in Node.js, Python, and other commonly used stacks.

**5. Error Handling**\
Common error scenarios, causes, and recommended handling strategies to ensure reliable integration.

***

#### Summary

This API enables merchants to embed PIX-based on-ramp functionality, allowing end users to acquire stablecoins via local payment methods, with settlement managed in USDT through Tylt’s crypto-asset infrastructure.


# Create a Pay-in Instance

This endpoint allows you to create a new payment instance and receive a URL that can be used to launch the Tylt CrossRamp Pay-In widget. Through the widget, the merchant's end customer can make a deposit or payment to the merchant using PIX. The payment is settled in USDT into the merchants wallet.\
\
The endpoint also delivers the qrString and PIX code which can be consumed by the merchant to create a fully hosted solution / frontend integration.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime/BR/PIX/instance`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>isBuyTrade</code></td><td><code>number</code></td><td>Must be set to 1 for a Pay-In transaction.</td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td><p>Free-form object containing merchant-defined user metadata. This object may include any fields for tracking and reconciliation and is returned in webhooks and API responses.</p><p><br><strong>Reserved Keys  (for Auto-KYC)</strong></p><p>Certain keys (e.g., <code>kyc</code>) are reserved for system-level processing. If provided, they must follow the defined schema and will be used for workflows such as reusable KYC (e.g., Didit session reuse).<br></p><p>The reserved key <code>kyc</code> (object) enables reusable KYC with the following structure:<br><code>{ source: "Didit", sessionId: string }</code></p><p>Provide the <code>sessionId</code> of a completed Didit verification. The system will attempt to import and validate the session; if successful, the user may skip KYC, otherwise the standard KYC flow applies.<br></p><p>For more details on setting up Didit reusable KYC, refer to the official documentation.</p></td></tr><tr><td><code>pixDetails</code></td><td><code>JSON Object</code></td><td><p><strong>Reserved keys  (auto-populate payment widget)</strong><br></p><p>The following keys are reserved. If you include any of them, they will be used to pre-fill the corresponding fields in the hosted payment widget:<br></p><ul><li><code>fullName</code> (string)</li><li><code>cpfKey</code> (string)</li></ul><p></p><p>If a reserved field is not provided, the end user will be prompted to enter that field in the widget.</p></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to deposit in USDT or BRL equivalent.</td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Supported Currency is "BRL" only.</td></tr><tr><td><code>settledCurrency</code></td><td><code>string</code></td><td>Supported settlement currency is "USDT", "USDC" only. "USDT" is default.</td></tr><tr><td><code>channel</code></td><td><code>number</code></td><td><strong>Optional. Default 1.</strong> Special channel provision, speak with your account manager.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

.

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

<pre class="language-javascript"><code class="lang-javascript">const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    isBuyTrade: 1,
    userDetails: {},
    pixDetails: {
            fullName: "Joao Pedro Barbosa",
            cpfKey: "03475666006"
        },
    merchantOrderId: crypto.randomUUID(),
    callBackUrl: "https://www.test.com/callback",
    redirectUrl: "https://www.test.com/callback",
    amount: 10.00,
    currencySymbol: "BRL",
    settledCurrency: "USDT"
<strong>};
</strong>
// Print request body for reference
console.log("requestBody", requestBody);

// Convert request body to JSON
const raw = JSON.stringify(requestBody);
// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);
// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};
// Send the request
axios.post('https://api.tylt.money/v2/prime/BR/PIX/instance', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

</code></pre>

{% endtab %}

{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests
import uuid

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a POST request
def send_post_request(url, body):
    raw = json.dumps(body, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, raw)

    headers = {
        'Content-Type': 'application/json',
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }

    response = requests.post(url, headers=headers, data=raw)
    return response.json()

# Request body
request_body = {
    "isBuyTrade": 1,
    "userDetails": {},
    "pixDetails": {
            "fullName": "Joao Pedro Barbosa",
            "cpfKey": "03475666006"
        },
    "merchantOrderId": str(uuid.uuid4()),
    "callBackUrl": 'https://www.test.com/callback',
    "redirectUrl": 'https://www.test.com/callback',
    "amount": 10,
    "currencySymbol" : 'BRL',
     # Required only for PIX Instant Payin Channel:
    "walletAddress": '0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c', # Public address of self-hosted wallet for crypto settlement
    "network":'ETH' # Network of the self-hosted wallet — accepted values: "ETH", "TRX", "AVAX", "TON", "SOL"
}

# Print request body for reference
print('request_body',request_body)

# Send the request
response = send_post_request('https://api.tylt.money/v2/prime/BR/PIX/instance', request_body)
print("Response:", response)


```

{% endtab %}

{% tab title="JavaScript (Fetch)" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    isBuyTrade: 1,
    userDetails: {},
    pixDetails: {
            fullName: "Joao Pedro Barbosa",
            cpfKey: "03475666006"
        },
    merchantOrderId: crypto.randomUUID(),
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'https://www.test.com/callback',
    amount: 10.00,
    currencySymbol: 'BRL',
    
// Required only for Instant (INSTI) Channel:
    walletAddress: "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c", // Public address of self-hosted wallet for crypto settlement
    network:"ETH" // Network of the self-hosted wallet — accepted values: "ETH", "TRX", "AVAX", "TON", "SOL"
};

//Print request body for reference
console.log("requestBody", requestBody)

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: body,
    });
    return response.json();
};

// Send the request
sendRequest('https://api.tylt.money/v2/prime/BR/PIX/instance', headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));
re
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "Instance and trade created successfully",
    "data": {
        "qrString": "data:image/png;base64,iVBORw0KfGgoAAAANSUhEUgAAASwAAAEsCAYAAAB5fY51AAAAAklEQVR4AewaftIAAAzWSURBVO3BQY4cy5IEQdNA3//KOtx+wGsRROar9qGJ4B+pqlrgpKpqiZOqqiVOqqqWOKmqWuKkqmqJk6qqJU6qqpY4qapa4qSqaomTqqolTqqqljipqlriJ38ByBZqJkAmam4AmaiZAJmo+QTIE9TcADJRcwvIDTVPADJRcwvIE9TcADJRMwGyhZobJ1VVS5xUVS1xUlW1xElV1RInVVVL/ORBar4ByNuAPEHNBMgnam4AmQC5oeYGkFtq3qTmBpBP1EyAPAHIRM1T1HwDkCecVFUtcVJVtcRJVdUSJ1VVS5xUVS3xk/8AkCeoeYqaJ6h5gppbQG6oeZOatwG5oeaGmltqtgPyBDVvOqmqWuKkqmqJk6qqJU6qqpY4qapa4if/KCBvArIFkG9Rc0PNBMgNILfUTIDcUHMDyETNv+akqmqJk6qqJU6qqpY4qapa4qSqaomf/KPUPAHIRM0EyETNJ0Amam4AmaiZAHkbkO3UTIBMgNTfOamqWuKkqmqJk6qqJU6qqpY4qapa4if/ATXbAbkBZKJmAuQTNW8CckPNU4BM1EyA/DZAJmq2ULPBSVXVEidVVUucVFUtcVJVtcRJVdUSP3kQkC2ATNTcUDMB8jYgEzU31EyA3ADyiZo3qZkAmaiZAHkbkImaCZCJmltANjupqlripKpqiZOqqiVOqqqWOKmqWuKkqmoJ/CP/ICA31EyAPEHNJ0CeoGYC5IaapwCZqJkA+RY1bwJyQ82/5qSqaomTqqolTqqqljipqlripKpqCfwjl4BM1EyA3FAzAfIUNRMgT1BzA8gtNU8A8tuo+QYgt9T8JkA+UXMDyETNBMgNNTdOqqqWOKmqWuKkqmqJk6qqJU6qqpbAP/IQIN+g5ilAnqDmbUAmaiZAJmomQCZqtgNyS80NIBM1WwC5oeZNJ1VVS5xUVS1xUlW1xElV1RInVVVL/OSL1EyA3AByS81EzQTIRM0EyETNLSATNRMgT1DzFCATNRMgN9TcUPMUIE8AMlEzAfIUNRM1EyA3gEzU3DipqlripKpqiZOqqiVOqqqWOKmqWuInD1JzA8gT1DwFyBPUfIuaG0BuqJkA+UTNBkA+UfMmNRMgN9TcAjJRM1EzATJR84STqqolTqqqljipqlripKpqiZOqqiXwj1wCckPNDSATNRMgn6iZAHmCmgmQp6iZAJmomQDZQs0EyETNBMhEzVOA3FAzATJRcwPIJ2puAJmo+YaTqqolTqqqljipqlripKpqiZOqqiXwj9TXAXmKmgmQG2reBmSi5k1AJmo+ATJRcwPIE9TcAnJDzW9yUlW1xElV1RInVVVLnFRVLXFSVbXET/4CkImaG0Amam4AuaVmAuSGmhtAbqmZAHkTkImaCZC3AXkTkE/U3AByQ80TgHyi5glAJmomQCZqbpxUVS1xUlW1xElV1RInVVVLnFRVLXFSVbUE/pGHAJmomQCZqJkAmaj5BMgT1NwAsp2abwEyUTMBMlEzAfLbqJkAuaHmFpCJmt/kpKpqiZOqqiVOqqqWOKmqWuKkqmqJnzxIzQ01N9RMgDxFzQTIRM0NNRMgn6iZALmhZgLkbUAmaiZqJkCeoGYC5BM1EyATNW9SMwHyiZonALmh5gknVVVLnFRVLXFSVbXESVXVEidVVUv85EFAJmrepOYTIG8CMlEzATJR8wmQiZobQG4Amah5CpAbam4Amaj5FiA31EyATNS8Tc0NIBM1N06qqpY4qapa4qSqaomTqqolTqqqlsA/8jIgEzU3gDxFzQ0gEzVPAHJLzZuATNQ8BcgNNU8AMlHzCZCJmgmQG2omQN6mZgLkhpo3nVRVLXFSVbXESVXVEidVVUucVFUt8ZP/gJo3qdkCyNuATNTcUPMtaiZAJmomQCZqbqmZAJmomQCZAJmouQHkFpAbar7hpKpqiZOqqiVOqqqWOKmqWuKkqmqJnzwIyA01EyA3gDxFzb8GyG8DZKLmhpoJkLcBeQKQLYBM1DzhpKpqiZOqqiVOqqqWOKmqWuKkqmqJn/wH1EyA3FDzFCBPAPIENbeATNRMgDxBzVOATNRMgDxBzVOAfIOapwCZqJkA+YaTqqolTqqqljipqlripKpqiZOqqiV+8heATNR8A5BP1NwAMlFzA8hEzQTIJ2repGYC5AaQT9R8g5obQD5RM1EzATJRMwHyBCCfqHmTmgmQiZobJ1VVS5xUVS1xUlW1xElV1RInVVVLnFRVLfGTv6DmCWomQG6o+RYgEzVPAfImIE9Q8zY1EyA3gNwCMlHzBDUTIDfUvE3NBMhEzRNOqqqWOKmqWuKkqmqJk6qqJU6qqpb4yV8AMlEzATJRcwPI29RMgEzU3AByS80NIBM1EyA3gLwNyDeoeRuQJwDZAshEzY2TqqolTqqqljipqlripKpqiZOqqiV+8hfUTIBM1EyA3FDzFCATIN+g5haQJ6iZALmh5hMgN9RMgDxBzQTIJ2puqHkCkImapwB5gpoJkCecVFUtcVJVtcRJVdUSJ1VVS5xUVS3xk78AZKLmTUBuqflN1EyA3FIzAXIDyETNBMgEyLeomQCZqLkFZKJmAmSiZgJkomYC5ClqbgC5oeYJJ1VVS5xUVS1xUlW1xElV1RInVVVL/OQvqJkAuaHmBpCJmrepeQKQpwCZqHmTmt8GyETNDTWfALmh5glAJmpuAXmCmgmQN51UVS1xUlW1xElV1RInVVVLnFRVLfGTXwjIDSCfqLmhZgJkouZtaiZAJkB+GyATNRMgbwJyS80NIDfUPAHILSATNRMgN4BM1Nw4qapa4qSqaomTqqolTqqqljipqlriJ38ByETNN6j5BMhEzQTIRM0NIBM1t4BM1DwByATIRM23qJkAeYKaW0AmaiZAbgC5oeYWkBtqbgB5wklV1RInVVVLnFRVLXFSVbXESVXVEj95EJCJmjcB2QLIRM0tIG9ScwPIJ2omQCZqJkBuAHkKkImaJwCZqLkB5ClAbqh500lV1RInVVVLnFRVLXFSVbXESVXVEidVVUvgH7kEZKJmAmSi5luATNTcAHJDzS0gN9RMgEzUvA3IRM0EyA01N4B8i5rfBsg3qLlxUlW1xElV1RInVVVLnFRVLXFSVbXETx4EZKLmCUCeouYGkDcB+UTNBMgNNd+iZgLkhprfRs0EyG8D5AlqJkAmap5wUlW1xElV1RInVVVLnFRVLXFSVbXET/4DQCZqnqDmFpCJmieo+W2A3FDzFCATNU8AMlEzUTMB8tsAeZuaG0AmaiZAJmpunFRVLXFSVbXESVXVEidVVUucVFUtgX/klwEyUTMB8omaCZCJmicAmah5CpCJmjcBmaj5BMhEzQTIRM0NIBM1/18BeYqaCZCJmjedVFUtcVJVtcRJVdUSJ1VVS5xUVS2Bf+QhQN6k5haQiZobQG6omQD5FjUTIBM1N4B8omYC5Alq3gZkouYGkImaCZCJmgmQT9TcADJR8w0nVVVLnFRVLXFSVbXESVXVEidVVUvgH7kEZKLmBpAbaiZAvkXNDSATNZ8AuaHmCUC+Rc0EyLeouQFkouYGkG9RcwPIRM0TTqqqljipqlripKpqiZOqqiVOqqqWwD/yDwIyUbMFkImaJwCZqHkKkBtqJkCeoOYWkG9Q8xQgEzU3gEzUPOGkqmqJk6qqJU6qqpY4qapa4qSqaomf/AUgW6i5AWSiZgJkouYGkE/UTNTcADJR8wQgn6h5ApBvATJR8wQgTwDyiZpvADJRc+OkqmqJk6qqJU6qqpY4qapa4qSqaomTqqolfvIgNd8AZAsgTwEyUfMNap6iZgJkomYC5G1Abqh5k5q3AZmoedNJVdUSJ1VVS5xUVS1xUlW1xElV1RI/+Q8AeYKap6i5AWSi5glqPgEyUTMBMlHzBCBbqHmKmgmQbwDyNiATNRMgN9TcOKmqWuKkqmqJk6qqJU6qqpY4qapa4if/KCA31EyATNT8NkAmaiZqJkAmam4BmQCZqJkAmaiZAJmo+QTIRM0NIBM1EyATNVuoecJJVdUSJ1VVS5xUVS1xUlW1xElV1RI/qf+hZgJkouYJQH4bIDeAfKJmomYCZAJkouaGmgmQbwEyUXMDyC01N4BM1LzppKpqiZOqqiVOqqqWOKmqWuKkqmqJn/wH1Pw2am6oeYKaW0BuqLkB5IaaCZBbQG6o2QLIRM2b1HwCZALkCUBuqLlxUlW1xElV1RInVVVLnFRVLXFSVbXETx4EZAsgEzU3gEzUvA3IDTVvUvMUNRMgEzUTIBM1EzWfAJkAmaiZALmh5ilqbgB5gponnFRVLXFSVbXESVXVEidVVUucVFUtgX+kqmqBk6qqJU6qqpY4qapa4qSqaomTqqolTqqqljipqlripKpqiZOqqiVOqqqWOKmqWuL/ALuZhppf+0NFAAAAAElFTkSuQmCC",
        "pixCode": "00020101021226640014br.gov.bcb.pix2542pix.magenpay.io/cob/MZur_vmJREOrKDmc6Ahm9Q5204000053039865802BR5924NXP GAMING SOLUTION LTDA6005CUITE62070503***63044740",
        "instanceId": "fdea232e-173a-43cc-b190-3574b9884e31",
        "url": "https://app.cashier.network/prime-brl-instance/fdea232e-173a-43cc-b190-3574b9884e31",
        "tradeId": 1817228
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>url</td><td>string</td><td>The unique link to the Tylt Prime Payment widget. You can display this url either on iframe or a browser.</td></tr><tr><td>instanceId</td><td>string</td><td>The instance ID generated by Tylt, used as a UUID global identifier. </td></tr><tr><td>tradeId</td><td>number</td><td>The trade ID generated by Tylt, used as a numerical unique global identifier</td></tr><tr><td>qrString</td><td>string</td><td>The QR string</td></tr><tr><td>pixCode</td><td>string</td><td>The PIX code that the user can copy and paste in their bank app</td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Webhook for Tylt CrossRamp (Pay-in)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:<br>

   <table data-header-hidden><thead><tr><th width="100"></th><th></th></tr></thead><tbody><tr><td><strong><code>eventId</code></strong></td><td><strong>Description</strong></td></tr><tr><td><strong><code>1</code></strong></td><td>The instance and trade is created. Waiting for the user to accept the quote.</td></tr><tr><td><strong><code>2</code></strong></td><td>Quote accepted. Waiting for user to enter CPF number.</td></tr><tr><td><strong><code>3</code></strong></td><td>PIX QR generated. Waiting for the user to make the payment.</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment acknowledged and trade settled.</td></tr><tr><td><strong><code>9</code></strong></td><td>Trade expired as action or payment was not completed prior to the deadline or disputed payment was expired due to non payment. </td></tr></tbody></table>

{% hint style="info" %}

### Instance Information

The response related to an instance information contains two primary objects:

#### 1. Trade Object

This object contains all the information about the customer buying or selling USDT from the counterparty. It includes fields like:

* Trade lifecycle details (`eventId`, deadlines, description).
* Fiat and cryptocurrency details (currency name, symbol, amount, etc.).
* Payment method information (e.g., PIX).

#### 2. Transaction Object

This object contains all the information about the financial debit or credit carried out on the merchant's account. It is relevant to merchants for crediting or debiting a consumer for the transaction. The `transaction` object is updated **only when the `eventId` is 4**, representing the completion of the trade
{% endhint %}

4. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
5. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.accounts.transactionType === 'pay-in') {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)

# Your TL Pay API Secret Key
TLP_API_SECRET_KEY = 'YOUR_TLP_API_SECRET_KEY'  # Replace with your actual API secret key

@app.route('/callback', methods=['POST'])
def callback():
    # Get the raw request data for HMAC calculation
    raw_data = request.data

    # Parse JSON data from the request
    data = request.get_json()

    # Retrieve the signature from the request headers
    tlp_signature = request.headers.get('X-TLP-SIGNATURE')

    # Calculate the HMAC SHA-256 signature
    calculated_hmac = hmac.new(
        key=TLP_API_SECRET_KEY.encode(),
        msg=raw_data,
        digestmod=hashlib.sha256
    ).hexdigest()

    # Compare the calculated HMAC signature with the one in the request header
    if hmac.compare_digest(calculated_hmac, tlp_signature):
        # Signature is valid
        if data['accounts']['transactionType'] == 'pay-in':
            print('Received pay-in callback:', data)
            # Process pay-in data here
            
        # Return HTTP Response 200 with content "ok"
        return jsonify({"message": "ok"}), 200
    else:
        # Invalid HMAC signature
        return jsonify({"error": "Invalid HMAC signature"}), 400

if __name__ == '__main__':
    app.run(port=3000, debug=True)

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 1,
                "deadline": "2025-02-12T05:27:37Z",
                "description": "Trade Initiated. Payment Link Generated. Quote displayed."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:24:37Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
            },
            "priceDetails": {
                "price": null,
                "amount": null,
                "paymentAmount": 500
            },
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
        },
        "accounts": {
                    "transactionType": "pay-in",
                    "amountPaidInLocalCurrency": 500,
                    "localCurrency": "BRL",
                    "conversionRate": null,
                    "amountPaidInCryptoCurrency": null,
                    "cryptoCurrencySymbol": "USDT",
                    "MDR_Rate": 1.1,
                    "merchantAccountCredited": null,
                    "merchantAccountDebited": null,
                },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 2,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Quote Accepted. Waiting for CPF input."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
        },
        "accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 3,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Awaiting Payment"
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
        },
        "accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 4,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Payment acknowledged and trade settled."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": 5.00,
            "status": "Completed",
            "isFinal": 1,
            "orderId": "nbdfd-73b73b-8oidtbc-oi8rfh-331n3ull",
            "createdAt": "2025-02-12T05:25:03Z",
            "isCredited": 1,
            "updatedAt": "2025-02-12T05:25:03Z",,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3"
        },
        "accounts": {
            "transactionType": "pay-in",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}

```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# PIX Payout (USDT → BRL)

This section provides a reference for integrating Tylt CrossRamp’s PIX off-ramp flow within merchant applications. Through this integration, merchants can initiate transfers of BRL to end users using their USDT/C balances maintained in their Tylt wallets.

***

#### Overview

* Merchants initiate cross-ramp instances using their available USDT balance
* End users recieve pauouts in BRL via PIX

***

#### What You’ll Find in the API Reference

**1. PIX Off-Ramp Flow**\
Guidance for initiating cross-ramp flows

**2. Supporting APIs**\
Documentation for additional functionalities such as listing supported currencies, networks, and fiat rails.

**3. Endpoint Descriptions**\
Detailed specifications for each API endpoint, including parameters, authentication requirements, and usage patterns.

**4. Request & Response Formats**\
Structured JSON examples covering off-ramp creation, status tracking, and webhook payloads.

**5. Code Examples**\
Reference implementations in Node.js, Python, and other commonly used stacks.

**6. Error Handling**\
Common error scenarios, causes, and recommended handling strategies.

***

#### Summary

This API enables merchants to initiate PIX-based cross-ramp flows, allowing merchants to users to convert stablecoins into BRL via local payment rails, with crypto-asset conversion and settlement managed within Tylt’s infrastructure.


# Create a Pay-out Instance

This endpoint allows you to create a new payout instance and receive a URL that can be used to launch the Tylt CrossRamp Pay-Out widget. Through the widget, the merchant's end customer can input / review the beneficiary details and initaite a payout. USDT/C balances on the Merchants wallet will be consumed to settle the transaction.\
\
Merchants can also bypass the widget interaction and specify the beneficiary details and make auto payouts to their endusers.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/v2/prime/BR/PIX/instance`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>isBuyTrade</code></td><td><code>number</code></td><td>Must be set to 0 for a Pay-out transaction.</td></tr><tr><td><code>userDetails</code></td><td><code>JSON Object</code></td><td>Custom fields associated with the user, supplied by the merchant. These fields are included in web-hook notifications and other API responses for easy reference and tracking. An empty object can be sent.</td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>A UUID used by the merchant to reference this instance or any transaction related to it.</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>The URL to which payment status updates are sent.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>The URL to redirect the user after completing the payment.</td></tr><tr><td><code>amount</code></td><td><code>number</code></td><td>Mandatory. This is the amount the user wants to withdraw in USDT or BRL equivalent. </td></tr><tr><td><code>currencySymbol</code></td><td><code>string</code></td><td>Supported Currency is "BRL" only.</td></tr><tr><td><code>settledCurrency</code></td><td><code>string</code></td><td>Settled Crypto Currency is "USDT" or "USDC" only. Default "USDT".</td></tr><tr><td><code>autoPayout</code></td><td><code>number</code></td><td><p>Set to <code>1</code> if you want the payout to be processed automatically, without requiring the user to interact with the Pay-Out widget. </p><p></p><p>When set to <code>0</code>, the user must manually confirm the payout through the widget interface.<br><br>For autoPayout to work, pixDetails need to be complete.</p></td></tr><tr><td><code>pixDetails</code></td><td><code>JSON Object</code></td><td><p>Mandatory if <code>autoPayout = 1</code>.<br><br>Object containing PIX payout beneficiary details, including: <br>(a) recipient’s full name,<br>(b) PIX key type (CPF, EMAIL, MOBILE),<br>(c) corresponding PIX key value, and <br>(d) CPF. <br><br>If <code>autoPayout = 0</code>, the user will be required to enter these details within the Payment widget.</p><p></p><p>If <code>pixDetails</code> are provided in this case, the Payment widget will be pre-populated with the supplied information.<br><br>This information is used to identify and correctly route the PIX transaction to the intended beneficiary.</p></td></tr><tr><td><code>channel</code></td><td><code>number</code></td><td><strong>Optional. Default 1.</strong> Special channel provision, speak with your account manager.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="warning" %}
**Important Note on `autoPayout` Usage**

If using `autoPayout = 1`, please make note of the following:

**Widget URL Omission**\
When `autoPayout` is set to `1`, the **payout widget URL will not be included** in the API response, since no user interaction is required.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
  isBuyTrade: 0, // 0 = Sell (Off-Ramp), 1 = Buy (On-Ramp)
  userDetails: {}, // Optional user metadata (e.g., email, phone, userId)
  merchantOrderId: crypto.randomUUID(),
  callBackUrl: 'https://www.test.com/callback',
  redirectUrl: 'https://www.test.com/callback',
  amount: 10,
  currencySymbol: 'BRL',
  settledCurrency: "USDT",
  autoPayout: 1, // 1 = Auto process payout, 0 = Manual via widget ( Default)
  pixDetails: { // Required if autoPayout is set to 1
    fullName: 'João Pereira',
    cpfKey: '12345678910',
    pixKeyType: 'CPF', // Accepted values: 'CPF', 'EMAIL', 'MOBILE'
    pixKey: '12345678910'
  }
};

// Print request body for reference
console.log('requestBody',requestBody);

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/v2/prime/BR/PIX/instance', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import json
import hashlib
import hmac
import requests
import uuid

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Function to send a POST request
def send_post_request(url, body):
    raw = json.dumps(body, separators=(',', ':'), ensure_ascii=False)
    signature = create_signature(api_secret, raw)

    headers = {
        'Content-Type': 'application/json',
        'X-TLP-APIKEY': api_key,
        'X-TLP-SIGNATURE': signature
    }

    response = requests.post(url, headers=headers, data=raw)
    return response.json()

# Request body
request_body = {
  "isBuyTrade": 0,
  "userDetails": {},
  "merchantOrderId": str(uuid.uuid4()),
  "callBackUrl": "https://www.test.com/callback",
  "redirectUrl": "https://www.test.com/callback",
  "amount": 10,
  "currencySymbol": "BRL",
  "autoPayout": 1,
  "pixDetails": {
    "fullName": "João Pereira",
    "cpfKey": "12345678910",
    "pixKeyType": "CPF",
    "pixKey": "12345678910"
  }
}

# Print request body for reference
print('requst_body',request_body)


# Send the request
response = send_post_request('https://api.tylt.money/v2/prime/BR/PIX/instance', request_body)
print("Response:", response)


```

{% endtab %}

{% tab title="JavaScript (Fetch)" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
  isBuyTrade: 0, // 0 = Sell (Off-Ramp), 1 = Buy (On-Ramp)
  userDetails: {}, // Optional user metadata (e.g., email, phone, userId)
  merchantOrderId: crypto.randomUUID(),
  callBackUrl: 'https://www.test.com/callback',
  redirectUrl: 'https://www.test.com/callback',
  amount: 10.00,
  currencySymbol: 'BRL',
  autoPayout: 1, // 1 = Auto process payout, 0 = Manual via widget
  pixDetails: {
    fullName: 'João Pereira',
    cpfKey: '12345678910',
    pixKeyType: 'CPF', // Accepted values: 'CPF', 'EMAIL', 'MOBILE'
    pixKey: '12345678910'
  }
};

// Print request body for reference
console.log("requestBody", requestBody);

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: body,
    });
    return response.json();
};

// Send the request
sendRequest('https://api.tylt.money/v2/prime/BR/PIX/instance', headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "Instance created successfully",
    "data": {
        "url": "https://app.tylt.money/prime-brl/d0f6cc25-e8f8-11ef-830e-02d8461243e9", // will not be sent if autoPayout is set to 1
        "instanceId": "d0f6cc25-e8f8-11ef-830e-02d8461243e9",
        "tradeId": 10432

        }    
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>url</td><td>string</td><td>The unique link to the Tylt Prime Payment widget. You can display this url either on iframe or a browser.</td></tr><tr><td>instanceId</td><td>string</td><td>The instance ID generated by Tylt, used as a UUID global identifier. </td></tr><tr><td>tradeId</td><td>number</td><td>The trade ID generated by Tylt, used as a numerical unique global identifier</td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Webhook for Tylt CrossRamp ( Pay-out)

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their payment instance, whether for pay-ins or for pay-outs. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** While calling the Create Pay-in or Create Pay-out instance API's  , insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:**  The life cycle of a payment instance is tracked via `eventId`. Below is the list of possible `eventId` values and their meanings:<br>

**Payout using balance in Tylt Wallet**&#x20;

{% hint style="warning" %}
If you are using the Tylt Wallet balance to process a payout, please use the API keys generated for the account configured for Daily Settlement (T0). While payouts are executed and settled instantly, they are routed through the Daily Settlement channel for technical and compliance purposes.
{% endhint %}

<table data-header-hidden><thead><tr><th width="100">eventId</th><th>Description</th></tr></thead><tbody><tr><td><strong><code>1</code></strong></td><td>The instance and trade is created. Waiting for the user to accept the quote.</td></tr><tr><td><strong><code>2</code></strong></td><td>Quote accepted. The merchant wallet has been debited and we are now awaiting the user to enter their CPF number and payment details.</td></tr><tr><td><strong><code>3</code></strong></td><td>Payment via PIX in BRL is under process</td></tr><tr><td><strong><code>4</code></strong></td><td>Payment completed and trade settled.</td></tr><tr><td><strong><code>9</code></strong></td><td>Trade expired as action or payment was not completed prior to the deadline or disputed payment was expired due to non payment. </td></tr></tbody></table>

{% hint style="info" %}

### Instance Information

The response related to an instance information contains two primary objects:

#### 1. Trade Object

This object contains all the information about the customer buying or selling USDT from the counterparty. It includes fields like:

* Trade lifecycle details (`eventId`, deadlines, description).
* Fiat and cryptocurrency details (currency name, symbol, amount, etc.).
* Payment method information (e.g., PIX).

#### 2. Transaction Object

This object contains all the information about the financial debit or credit carried out on the merchant's account. It is relevant to merchants for crediting or debiting a consumer for the transaction. The `transaction` object is updated **only when the `eventId` is 4**, representing the completion of the trade
{% endhint %}

4. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
5. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.accounts.transactionType === 'pay-out') {
            console.log('Received pay-out callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import hmac
import hashlib

app = Flask(__name__)

# Your TL Pay API Secret Key
TLP_API_SECRET_KEY = 'YOUR_TLP_API_SECRET_KEY'  # Replace with your actual API secret key

@app.route('/callback', methods=['POST'])
def callback():
    # Get the raw request data for HMAC calculation
    raw_data = request.data

    # Parse JSON data from the request
    data = request.get_json()

    # Retrieve the signature from the request headers
    tlp_signature = request.headers.get('X-TLP-SIGNATURE')

    # Calculate the HMAC SHA-256 signature
    calculated_hmac = hmac.new(
        key=TLP_API_SECRET_KEY.encode(),
        msg=raw_data,
        digestmod=hashlib.sha256
    ).hexdigest()

    # Compare the calculated HMAC signature with the one in the request header
    if hmac.compare_digest(calculated_hmac, tlp_signature):
        # Signature is valid
        if data['accounts']['transactionType'] == 'pay-in':
            print('Received pay-in callback:', data)
            # Process pay-in data here
            
        # Return HTTP Response 200 with content "ok"
        return jsonify({"message": "ok"}), 200
    else:
        # Invalid HMAC signature
        return jsonify({"error": "Invalid HMAC signature"}), 400

if __name__ == '__main__':
    app.run(port=3000, debug=True)

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="eventId: 1" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 1,
                "deadline": "2025-02-12T05:27:37Z",
                "description": "Trade Initiated. Payment Link Generated. Quote displayed."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:24:37Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
            },
            "priceDetails": {
                "price": null,
                "amount": null,
                "paymentAmount": 500
            },
            "paymentMethod": {
                 "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
            "end2end": "NOX1234567890"
        },
        "accounts": {
                    "transactionType": "pay-out",
                    "amountPaidInLocalCurrency": 500,
                    "localCurrency": "BRL",
                    "conversionRate": null,
                    "amountPaidInCryptoCurrency": null,
                    "cryptoCurrencySymbol": "USDT",
                    "MDR_Rate": 1.1,
                    "merchantAccountCredited": null,
                    "merchantAccountDebited": null
                },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 2" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 2,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Quote Accepted. Waiting for CPF input."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
            "paymentMethod": {
                "details": null
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
            "end2end": "NOX1234567890"
        },
        "accounts": {
            "transactionType": "pay-out",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="eventId: 3" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 3,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Awaiting Payment"
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
             "paymentMethod": {
                 "details": {
                     "recipientPixCode": "01101101100"
                     }
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": null,
            "status": null,
            "isFinal": null,
            "orderId": null,
            "createdAt": null,
            "isCredited": null,
            "updatedAt": null,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
            "end2end": "NOX1234567890"
        },
        "accounts": {
            "transactionType": "pay-out",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}
```

{% endtab %}

{% tab title="eventId: 4" %}

```json
{
    "data": {
        "trade": {
            "event": {
                "id": 4,
                "deadline": "2025-02-12T05:30:03Z",
                "description": "Payout completed and trade settled."
            },
            "createdAt": "2025-02-12T05:24:37Z",
            "updatedAt": "2025-02-12T05:25:03Z",
            "fiatCurrency": {
                "name": "Brazilian Real",
                "symbol": "BRL"
                },
            "priceDetails": {
                "price": 5.00,
                "amount": 100,  // Amount of USDT
                "paymentAmount": 500  // Amount to be paid by user in BRL
            }, 
            "paymentMethod": {
                 "details": {
                     "recipientPixCode": "01101101100"
                     }
            },
            "cryptoCurrency": {
                "name": "Tether",
                "symbol": "USDT"
            }
        },
        "transaction": {
            "amount": 5.00,
            "status": "Completed",
            "isFinal": 1,
            "orderId": "nbdfd-73b73b-8oidtbc-oi8rfh-331n3ull",
            "createdAt": "2025-02-12T05:25:03Z",
            "isCredited": 1,
            "updatedAt": "2025-02-12T05:25:03Z",,
            "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
            "end2end": "NOX1234567890"
        },
        "accounts": {
            "transactionType": "pay-out",
            "amountPaidInLocalCurrency": 500.00, // Amount to be paid by user in BRL
            "localCurrency": "BRL",
            "conversionRate": 5.00,
            "amountPaidInCryptoCurrency": 100,  // Amount of USDT
            "cryptoCurrencySymbol": "USDT",
            "MDR_Rate": 1.1,
            "merchantAccountCredited": null,
            "merchantAccountDebited": null
        },
        "user": {}
    }
}

```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
**Important Considerations**

* **Security:** Always verify the `X-TLP-SIGNATURE` header to ensure the callback originates from Tylt.
* **Response:** Always return an HTTP 200 response with `"ok"` in the body to acknowledge successful receipt of the web-hook.
* **Manual Retry:** In case of missed callbacks, use the tylt.money dashboard to manually resend the webhook.
  {% endhint %}


# Trade Details

This API allows merchants to manually fetch the exact callback / webhook payload for a specific instance. The response contains the current trade, transaction, account, user, and settlement-related details for the selected instance.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/instance/{identifier}/trade-details`

| Parameter  |             Type | Required | Description                                                                                  |
| ---------- | ---------------: | -------: | -------------------------------------------------------------------------------------------- |
| identifier | string / integer |      Yes | The instance identifier. You may pass either the UUID `instanceId` or the numeric `tradeId`. |

**Example Request**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/instance/1563365/trade-details`

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/instance/e12a29be-5725-41b5-9913-d783174f631b/trade-details`

{% hint style="warning" %}
We recommend using `instanceId` as the primary identifier. In some cases, an instance may not result in a trade, meaning a `tradeId` may not exist.
{% endhint %}

**Request Parameters**

<table><thead><tr><th>Parameter</th><th align="right">Type</th><th width="154" align="right">Required</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td align="right">string</td><td align="right">Yes</td><td>Calendar date for which the report is required. Format: YYYY-MM-DD. The backend maps this date from 00:00:00Z to 23:59:59Z.</td></tr><tr><td>page</td><td align="right">integer</td><td align="right">No</td><td>Pagination page number. Defaults to 1.</td></tr><tr><td>limit</td><td align="right">integer</td><td align="right">No</td><td>Number of records to return per page. Defaults to 20. Maximum allowed value is 50.</td></tr></tbody></table>

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="182">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require("axios");
const crypto = require("crypto");

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const instanceId = "ccacfd2d-d277-4938-b0b3-07d04cb10dbb";

// Use this payload when using instanceId in the URL
const signingPayload = JSON.stringify({
  instanceId: String(instanceId),
});

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(signingPayload)
  .digest("hex");

axios
  .get(`https://api.tylt.money/v2/prime-ntx/instance/${instanceId}/trade-details`, {
    headers: {
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature,
    },
  })
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    console.error(error.response?.data || error.message);
  });
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Trade details fetched successfully",
  "data": {
    "trade": {
      "event": {
        "id": 4,
        "deadline": "2026-06-05T11:46:33Z",
        "description": "Seller Acknowledges Payment Receipt. Trade Completed."
      },
      "pixCode": "00020101021226850014br.gov.bcb.pix2563qrcode.brzip.com.br/pix/qr/db944974-de9b-4f54-a251-7d80a0fec7515204000053039865802BR5925GESTAO EMPRESARIAL CIOTTA6009SAO PAULO62070503***6304C403",
      "tradeId": 1197457,
      "qrString": "data:image/png;base64,...",
      "createdAt": "2026-06-05T11:35:18Z",
      "updatedAt": "2026-06-05T11:37:30Z",
      "isBuyTrade": 1,
      "fiatCurrency": {
        "name": "Brazilian Real",
        "symbol": "BRL"
      },
      "priceDetails": {
        "price": 0.1968,
        "amount": 0.39,
        "paymentAmount": 2
      },
      "cryptoCurrency": {
        "name": "Tether",
        "symbol": "USDT"
      }
    },
    "transaction": {
      "amount": 0.34,
      "status": "Completed",
      "isFinal": 1,
      "orderId": "af36d51c-f826-45fc-a510-4dd04a16795e",
      "createdAt": "2026-06-05T11:37:24Z",
      "isDebited": 1,
      "updatedAt": "2026-06-05T11:37:33Z",
      "merchantOrderId": "gaming-test-1780659318730"
    },
    "accounts": {
      "network": "ETH",
      "MDR_Rate": 0.75,
      "localCurrency": "BRL",
      "transactionHash": null,
      "transactionType": "pay-in",
      "merchantAccountDebited": null,
      "merchantAccountCredited": 0.34,
      "amountPaidInLocalCurrency": 2,
      "conversionRate": 0.1968,
      "amountPaidInCryptoCurrency": 10.16260162601626,
      "cryptoCurrencySymbol": "USDT"
    },
    "user": {
      "name": "John Doe"
    },
    "callBackUrl": "https://api.tylt.money/common/postback",
    "insufficientBalance": 0,
    "manualSettlement": 0,
    "instanceExpired": 1
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}
**Response Parameters**

| Field |   Type | Description                                                           |
| ----- | -----: | --------------------------------------------------------------------- |
| msg   | string | Response message.                                                     |
| data  | object | Contains the trade, transaction, account, user, and callback details. |

**Trade Object**

| Field                            |    Type | Description                                 |
| -------------------------------- | ------: | ------------------------------------------- |
| trade.event.id                   | integer | Event ID of the trade.                      |
| trade.event.deadline             |  string | Trade deadline timestamp.                   |
| trade.event.description          |  string | Description of the current trade event.     |
| trade.pixCode                    |  string | PIX payment code.                           |
| trade.tradeId                    | integer | Unique Tylt trade ID.                       |
| trade.qrString                   |  string | Base64 QR image string, where available.    |
| trade.createdAt                  |  string | Trade creation timestamp.                   |
| trade.updatedAt                  |  string | Last trade update timestamp.                |
| trade.isBuyTrade                 | integer | Indicates whether the trade is a buy trade. |
| trade.fiatCurrency.name          |  string | Fiat currency name.                         |
| trade.fiatCurrency.symbol        |  string | Fiat currency symbol.                       |
| trade.priceDetails.price         |  number | Conversion price used for the trade.        |
| trade.priceDetails.amount        |  number | Crypto amount calculated for the trade.     |
| trade.priceDetails.paymentAmount |  number | Fiat payment amount.                        |
| trade.cryptoCurrency.name        |  string | Crypto currency name.                       |
| trade.cryptoCurrency.symbol      |  string | Crypto currency symbol.                     |

**Transaction Object**

| Field                       |    Type | Description                                    |
| --------------------------- | ------: | ---------------------------------------------- |
| transaction.amount          |  number | Transaction amount credited or debited.        |
| transaction.status          |  string | Current transaction status.                    |
| transaction.isFinal         | integer | Indicates whether the transaction is final.    |
| transaction.orderId         |  string | Tylt order ID.                                 |
| transaction.createdAt       |  string | Transaction creation timestamp.                |
| transaction.updatedAt       |  string | Last transaction update timestamp.             |
| transaction.isDebited       | integer | Indicates whether the transaction was debited. |
| transaction.merchantOrderId |  string | Merchant-provided order ID.                    |

**Accounts Object**

| Field                               |          Type | Description                                        |
| ----------------------------------- | ------------: | -------------------------------------------------- |
| accounts.network                    |        string | Blockchain network.                                |
| accounts.MDR\_Rate                  |        number | Merchant discount rate applied to the transaction. |
| accounts.localCurrency              |        string | Local fiat currency.                               |
| accounts.transactionHash            | string / null | Blockchain transaction hash, where applicable.     |
| accounts.transactionType            |        string | Transaction type, such as pay-in or pay-out.       |
| accounts.merchantAccountDebited     | number / null | Amount debited from the merchant account.          |
| accounts.merchantAccountCredited    | number / null | Amount credited to the merchant account.           |
| accounts.amountPaidInLocalCurrency  |        number | Amount paid by the user in local fiat currency.    |
| accounts.conversionRate             |        number | Conversion rate used for the transaction.          |
| accounts.amountPaidInCryptoCurrency |        number | Crypto equivalent of the local currency amount.    |
| accounts.cryptoCurrencySymbol       |        string | Crypto currency symbol.                            |
| {% endtab %}                        |               |                                                    |
| {% endtabs %}                       |               |                                                    |


# Transactions Report

This API allows merchants to fetch all PIX cross-ramp transactions for a specific calendar date.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/transactions/report?date={yyyy-mm-dd}`

**Example Request**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/transactions/report?date=2026-07-04`

OR

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/v2/prime-ntx/transactions/report?hours=12`

**Request Parameters**

<table><thead><tr><th>Parameter</th><th align="right">Type</th><th width="154" align="right">Required</th><th>Description</th></tr></thead><tbody><tr><td>date</td><td align="right">string</td><td align="right">Yes (if no <code>hours</code>)</td><td>Calendar date for which the report is required. Format: YYYY-MM-DD. The backend maps this date from 00:00:00Z to 23:59:59Z.</td></tr><tr><td>hours</td><td align="right">integer</td><td align="right">Yes (if no <code>date</code>)</td><td>Number of past hours to fetch transactions for. Must be an integer between 1 and 24.</td></tr><tr><td>page</td><td align="right">integer</td><td align="right">No</td><td>Pagination page number. Defaults to 1.</td></tr><tr><td>limit</td><td align="right">integer</td><td align="right">No</td><td>Number of records to return per page. Defaults to 20. Maximum allowed value is 50.</td></tr></tbody></table>

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="182">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require("axios");
const crypto = require("crypto");

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const params = {
  date: "2026-07-04",
  page: "1",
  limit: "50",
};

// 1. Sort keys to keep the signing payload consistent
const sortedParams = Object.keys(params)
  .sort()
  .reduce((acc, key) => {
    acc[key] = String(params[key]);
    return acc;
  }, {});

// 2. Stringify the sorted object
const signingPayload = JSON.stringify(sortedParams);

// 3. Generate the HMAC signature
const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(signingPayload)
  .digest("hex");

axios
  .get("https://api.tylt.money/v2/prime-ntx/transactions/report", {
    // CRITICAL: We pass the exactly sorted parameters into Axios here
    // so the URL generated natively matches the hash order.
    params: sortedParams,
    headers: {
      "X-TLP-APIKEY": apiKey,
      "X-TLP-SIGNATURE": signature,
    },
  })
  .then((response) => {
    console.log(response.data);
  })
  .catch((error) => {
    console.error(error.response?.data || error.message);
  });

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "msg": "Transactions fetched successfully",
  "data": {
    "list": [
      {
        "trade": {
          "event": {
            "id": 4,
            "deadline": "2026-06-05T11:46:33Z",
            "description": "Seller Acknowledges Payment Receipt. Trade Completed."
          },
          "pixCode": "00020101021226850014br.gov.bcb.pix2563qrcode.brzip.com.br/pix/qr/db944974-de9b-4f54-a251-7d80a0fec7515204000053039865802BR5925GESTAO EMPRESARIAL CIOTTA6009SAO PAULO62070503***6304C403",
          "tradeId": 1197457,
          "qrString": "data:image/png;base64,...",
          "createdAt": "2026-06-05T11:35:18Z",
          "updatedAt": "2026-06-05T11:37:30Z",
          "isBuyTrade": 1,
          "fiatCurrency": {
            "name": "Brazilian Real",
            "symbol": "BRL"
          },
          "priceDetails": {
            "price": 0.1968,
            "amount": 0.39,
            "paymentAmount": 2
          },
          "cryptoCurrency": {
            "name": "Tether",
            "symbol": "USDT"
          }
        },
        "transaction": {
          "amount": 0.34,
          "status": "Completed",
          "isFinal": 1,
          "orderId": "af36d51c-f826-45fc-a510-4dd04a16795e",
          "createdAt": "2026-06-05T11:37:24Z",
          "isDebited": 1,
          "updatedAt": "2026-06-05T11:37:33Z",
          "merchantOrderId": "gaming-test-1780659318730"
        },
        "accounts": {
          "network": "ETH",
          "MDR_Rate": 0.75,
          "localCurrency": "BRL",
          "transactionHash": null,
          "transactionType": "pay-in",
          "merchantAccountDebited": null,
          "merchantAccountCredited": 0.34,
          "amountPaidInLocalCurrency": 2,
          "conversionRate": 0.1968,
          "amountPaidInCryptoCurrency": 10.16260162601626,
          "cryptoCurrencySymbol": "USDT"
        },
        "user": {
          "name": "John Doe"
        },
        "callBackUrl": "https://api.tylt.money/common/postback",
        "insufficientBalance": 0,
        "manualSettlement": 0,
        "instanceExpired": 1
      }
    ],
    "pagination": {
      "total": 481,
      "current_page": 1,
      "limit": 50,
      "total_pages": 10
    }
  }
}
```

{% endtab %}

{% tab title="Response Fields" %}
**Response Parameters**

| Field           |   Type | Description                                           |
| --------------- | -----: | ----------------------------------------------------- |
| msg             | string | Response message.                                     |
| data            | object | Contains the transaction list and pagination details. |
| data.list       |  array | List of transactions for the selected date.           |
| data.pagination | object | Pagination details for the report.                    |

**Trade Object**

| Field                            |    Type | Description                                 |
| -------------------------------- | ------: | ------------------------------------------- |
| trade.event.id                   | integer | Event ID of the trade.                      |
| trade.event.deadline             |  string | Trade deadline timestamp.                   |
| trade.event.description          |  string | Description of the trade event.             |
| trade.pixCode                    |  string | PIX payment code.                           |
| trade.tradeId                    | integer | Unique Tylt trade ID.                       |
| trade.qrString                   |  string | Base64 QR image string, where available.    |
| trade.createdAt                  |  string | Trade creation timestamp.                   |
| trade.updatedAt                  |  string | Last trade update timestamp.                |
| trade.isBuyTrade                 | integer | Indicates whether the trade is a buy trade. |
| trade.fiatCurrency.name          |  string | Fiat currency name.                         |
| trade.fiatCurrency.symbol        |  string | Fiat currency symbol.                       |
| trade.priceDetails.price         |  number | Conversion price used for the trade.        |
| trade.priceDetails.amount        |  number | Crypto amount calculated for the trade.     |
| trade.priceDetails.paymentAmount |  number | Fiat payment amount.                        |
| trade.cryptoCurrency.name        |  string | Crypto currency name.                       |
| trade.cryptoCurrency.symbol      |  string | Crypto currency symbol.                     |

**Transaction Object**

| Field                       |    Type | Description                                    |
| --------------------------- | ------: | ---------------------------------------------- |
| transaction.amount          |  number | Transaction amount credited or debited.        |
| transaction.status          |  string | Transaction status.                            |
| transaction.isFinal         | integer | Indicates whether the transaction is final.    |
| transaction.orderId         |  string | Tylt order ID.                                 |
| transaction.createdAt       |  string | Transaction creation timestamp.                |
| transaction.updatedAt       |  string | Last transaction update timestamp.             |
| transaction.isDebited       | integer | Indicates whether the transaction was debited. |
| transaction.merchantOrderId |  string | Merchant-provided order ID.                    |

**Accounts Object**

| Field                               |          Type | Description                                        |
| ----------------------------------- | ------------: | -------------------------------------------------- |
| <p></p><p>accounts.network</p>      |        string | Blockchain network.                                |
| accounts.MDR\_Rate                  |        number | Merchant discount rate applied to the transaction. |
| accounts.localCurrency              |        string | Local fiat currency.                               |
| accounts.transactionHash            | string / null | Blockchain transaction hash, where applicable.     |
| accounts.transactionType            |        string | Transaction type, such as pay-in.                  |
| accounts.merchantAccountDebited     | number / null | Amount debited from the merchant account.          |
| accounts.merchantAccountCredited    | number / null | Amount credited to the merchant account.           |
| accounts.amountPaidInLocalCurrency  |        number | Amount paid by the user in local fiat currency.    |
| accounts.conversionRate             |        number | Conversion rate used for the transaction.          |
| accounts.amountPaidInCryptoCurrency |        number | Crypto equivalent of the local currency amount.    |
| accounts.cryptoCurrencySymbol       |        string | Crypto currency symbol.                            |

**Pagination Object**

| Field                    |    Type | Description                            |
| ------------------------ | ------: | -------------------------------------- |
| pagination.total         | integer | Total number of matching transactions. |
| pagination.current\_page | integer | Current page number.                   |
| pagination.limit         | integer | Number of records returned per page.   |
| pagination.total\_pages  | integer | Total number of pages available.       |
| {% endtab %}             |         |                                        |
| {% endtabs %}            |         |                                        |


# Order Analytics: PIX

This endpoint allows merchants to retrieve analytics for PIX Pay-In orders processed through Tylt. The response provides a summary of transaction activity, including order counts, completed orders, expired orders, pending orders, total PIX volume, settlement amount, fees, and day-wise transaction performance.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/orderAnalyticsPix`

**Example Request**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/orderAnalyticsPix?mo th=2026-06`

**Request Parameters**

The request requires the month parameter.

| Name  | Type   | Example | Description                                                                                  |
| ----- | ------ | ------- | -------------------------------------------------------------------------------------------- |
| month | string | 2026-06 | The month for which PIX order analytics are to be retrieved. The required format is YYYY-MM. |

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="182">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

const params = {
  month: '2026-06'
};

// Create query string
const queryString = new URLSearchParams(params).toString();

// Create HMAC SHA-256 signature
const signaturePayload = JSON.stringify(params);

const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(signaturePayload)
  .digest('hex');

// Define headers
const headers = {
  'X-TLP-APIKEY': apiKey,
  'X-TLP-SIGNATURE': signature
};

// Send the GET request
axios
  .get(`https://api.tylt.money/transactions/merchant/orderAnalyticsPix?${queryString}`, { headers })
  .then(response => console.log(response.data))
  .catch(error => console.error(error));
```

{% endtab %}
{% endtabs %}

**Response**

{% hint style="warning" %}
Note: The first object in the `rows` array represents the monthly aggregate for the selected month and is marked as `MONTH TOTAL`. All subsequent objects represent date-wise analytics, returned in descending order based on the transaction date in UTC.
{% endhint %}

{% tabs %}
{% tab title="200" %}

```json
{
  "data": {
    "month": "2026-06",
    "rows": [
      {
        "date": "MONTH TOTAL",
        "totalOrdersPayIn": 144,
        "completedPayIn": 30,
        "conversionPctPayIn": 20.83,
        "brlPayIn": 484,
        "usdtPayIn": 92.88,
        "feesPayIn": 2.58,
        "totalOrdersPayOut": 54,
        "completedPayOut": 36,
        "conversionPctPayOut": 66.67,
        "brlPayOut": 441,
        "usdtPayOut": 85.72,
        "feesPayOut": 2.99
      },
      {
        "date": "2026-06-01",
        "totalOrdersPayIn": 6,
        "completedPayIn": 0,
        "conversionPctPayIn": 0,
        "brlPayIn": 0,
        "usdtPayIn": 0,
        "feesPayIn": 0,
        "totalOrdersPayOut": 0,
        "completedPayOut": 0,
        "conversionPctPayOut": 0,
        "brlPayOut": 0,
        "usdtPayOut": 0,
        "feesPayOut": 0
      },
      {
        "date": "2026-06-02",
        "totalOrdersPayIn": 1,
        "completedPayIn": 1,
        "conversionPctPayIn": 100,
        "brlPayIn": 1,
        "usdtPayIn": 0.2,
        "feesPayIn": 0.05,
        "totalOrdersPayOut": 2,
        "completedPayOut": 0,
        "conversionPctPayOut": 0,
        "brlPayOut": 0,
        "usdtPayOut": 0,
        "feesPayOut": 0
      }
    ]
  },
  "errorCode": 0,
  "msg": "Retrieved PIX order analytics for 2026-06"
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field Name            | Type   | Description                                                                                                                                |
| --------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `data`                | object | Contains the PIX order analytics data for the requested month.                                                                             |
| `month`               | string | The month for which the analytics are returned, in `YYYY-MM` format.                                                                       |
| `rows`                | array  | List of analytics rows. The first row provides the monthly total, followed by date-wise analytics rows.                                    |
| `date`                | string | The date for the analytics row. `MONTH TOTAL` represents the aggregated monthly total. Date-wise rows are returned in `YYYY-MM-DD` format. |
| `totalOrdersPayIn`    | number | Total number of PIX Pay-In orders created for the relevant row.                                                                            |
| `completedPayIn`      | number | Number of PIX Pay-In orders completed for the relevant row.                                                                                |
| `conversionPctPayIn`  | number | Percentage of PIX Pay-In orders that were completed.                                                                                       |
| `brlPayIn`            | number | Total completed PIX Pay-In volume in BRL.                                                                                                  |
| `usdtPayIn`           | number | Total completed PIX Pay-In volume in USDT.                                                                                                 |
| `feesPayIn`           | number | Total fees charged on completed PIX Pay-In transactions.                                                                                   |
| `totalOrdersPayOut`   | number | Total number of PIX Pay-Out orders created for the relevant row.                                                                           |
| `completedPayOut`     | number | Number of PIX Pay-Out orders completed for the relevant row.                                                                               |
| `conversionPctPayOut` | number | Percentage of PIX Pay-Out orders that were completed.                                                                                      |
| `brlPayOut`           | number | Total completed PIX Pay-Out volume in BRL.                                                                                                 |
| `usdtPayOut`          | number | Total completed PIX Pay-Out volume in USDT.                                                                                                |
| `feesPayOut`          | number | Total fees charged on completed PIX Pay-Out transactions.                                                                                  |
| `errorCode`           | number | Error code returned by the API. A value of `0` indicates a successful request.                                                             |
| `msg`                 | string | Message describing the result of the request.                                                                                              |
| {% endtab %}          |        |                                                                                                                                            |
| {% endtabs %}         |        |                                                                                                                                            |


# Reusable KYC (Didit Integration)

Tylt supports reusable KYC via Didit using a shared-session flow, allowing merchants to reuse an end user’s completed KYC and potentially skip repeating verification.

***

### Overview

To enable reusable KYC:

* The merchant completes KYC on Didit
* The merchant must provide the Didit `sessionId` as part of the Create Instance API request. This is done via the `userDetails` object using the reserved `kyc` key.&#x20;
* Tylt calls a merchant-provided endpoint to retrieve the reusable KYC session. The details of the endpoint that must be exposed to Tylt are provided below.
* The merchant generates a Didit `share_token`
* Tylt imports and validates the KYC session

***

### Passing KYC Details to Tylt

The merchant must provide the Didit `sessionId` as part of the Create Instance API request. This is done via the `userDetails` object using the reserved `kyc` key.&#x20;

```json
{
  "userDetails": {
    "kyc": {
      "source": "Didit",
      "sessionId": "string"
    }
  }
}
```

***

### Merchant Setup

The merchant must expose a secure backend endpoint that Tylt can call to retrieve a reusable KYC session.

***

### Standard Endpoint Specification

#### Endpoint

```http
POST /tylt-kyc/didit/share-session
```

* Must be accessible over HTTPS
* Must be server-to-server only

***

### Request (Tylt → Merchant)

```json
{
  "merchantOrderId": "string",
  "sessionId": "string",
  "tyltDiditApplicationId": "string"
}
```

#### Field Definitions

| Field                    | Type   | Required | Description                           |
| ------------------------ | ------ | -------: | ------------------------------------- |
| `merchantOrderId`        | string |      Yes | Unique identifier for the transaction |
| `sessionId`              | string |      Yes | Didit session ID of completed KYC     |
| `tyltDiditApplicationId` | string |      Yes | Tylt’s Didit application ID           |

***

### Expected Merchant Behavior

Upon receiving the request, the merchant must:

1. Authenticate and validate the request
2. Verify the `sessionId` exists and is eligible
3. Call Didit Share Session API internally
4. Generate a `share_token`
5. Return the token to Tylt

***

### Internal Didit API Call

#### Endpoint

```http
POST https://verification.didit.me/v3/session/{sessionId}/share/
```

#### Headers

```http
Content-Type: application/json
x-api-key: <merchant-didit-api-key>
```

#### Body

```json
{
  "for_application_id": "<tyltDiditApplicationId>",
  "ttl_in_seconds": 300
}
```

***

### Response (Merchant → Tylt)

#### Success

```json
{
  "success": true,
  "merchantOrderId": "string",
  "sessionId": "string",
  "shareToken": "string"
}
```

#### Error

```json
{
  "success": false,
  "merchantOrderId": "string",
  "sessionId": "string",
  "errorCode": "string",
  "message": "string"
}
```

***

### Error Codes

| Code                   | Description                     |
| ---------------------- | ------------------------------- |
| `INVALID_REQUEST`      | Missing or invalid fields       |
| `UNAUTHORISED`         | Authentication failed           |
| `SESSION_NOT_FOUND`    | Session does not exist          |
| `SESSION_NOT_ELIGIBLE` | Session cannot be reused        |
| `SHARE_SESSION_FAILED` | Didit share-session call failed |
| `INTERNAL_ERROR`       | Unexpected error                |

***

### End-to-End Flow

1. Merchant completes KYC on Didit
2. Merchant stores `sessionId`
3. Merchant sends `sessionId` to Tylt
4. Tylt calls merchant endpoint
5. Merchant calls Didit `/share/` API
6. Merchant returns `shareToken`
7. Tylt imports and validates session

***

### Outcome

* **Valid & accepted** → User skips KYC
* **Invalid / expired / rejected** → Standard KYC flow

***

### Important Notes

* Only completed Didit sessions are eligible
* `shareToken` is time-limited and single-use
* Merchant must use their own Didit API credentials
* `tyltDiditApplicationId` must be used as `for_application_id`
* Reusable KYC is subject to Tylt compliance checks
* KYC bypass is not guaranteed
* Merchant must ensure user consent for sharing KYC data


# User KYC Verification APIs

The User Verification APIs allow merchants to create and update end users, submit identity and address documents, perform AML screening, and initiate a liveness-verification session.

The APIs are designed for server-to-server integration and must only be called from the merchant’s secure backend.

### Available Operations

| Operation                      | Endpoint                    | Purpose                                                          |
| ------------------------------ | --------------------------- | ---------------------------------------------------------------- |
| Create or update user          | `POST /common/initiateUser` | Insert a new user or update the user’s basic profile information |
| Update proof of identity       | `POST /common/initiateKyc`  | Submit the user’s identity-document images                       |
| Update proof of address        | `POST /common/initiateKyc`  | Submit the user’s proof-of-address document                      |
| Run AML screening              | `POST /common/initiateKyc`  | Screen the user against applicable AML data sources              |
| Initiate liveness verification | `POST /common/initiateKyc`  | Generate a liveness-verification link for the user               |

***

## Authentication

Every request must include the following headers:

```http
Content-Type: application/json
x-tlp-apikey: <merchant-api-key>
x-tlp-signature: <hmac-signature>
```

The merchant API secret must remain confidential and must never be exposed in:

* Browser applications
* Mobile applications
* Public repositories
* Client-side JavaScript
* Logs
* Analytics platforms
* Published documentation

### Generating the Signature

The signature is generated by applying HMAC-SHA256 to the exact JSON request body:

```
HMAC_SHA256(merchantApiSecret, JSON.stringify(requestBody))
```

Example:

```javascript
const crypto = require("crypto");

const rawPayload = JSON.stringify(requestBody);

const signature = crypto
  .createHmac("sha256", process.env.TYLT_API_SECRET)
  .update(rawPayload)
  .digest("hex");
```

The body sent to Tylt must be exactly the same body used to generate the signature.

Changes to any of the following after signing may cause authentication to fail:

* Field order
* Field names
* Field values
* Data types
* Nested object structure
* Whitespace, where the raw serialized payload differs

***

## Base URL

### Development

```json
https://api.tylt.money/
```


# Create or Update User

Creates a new user or updates the basic information of an existing user. The merchant must provide a stable `externalUserId` for each user. Tylt uses this value as the merchant-specific identifier for locating and updating the user.

### Endpoint

```http
POST https://api.tylt.money/common/initiateUser
```

### Request Headers

```http
Content-Type: application/json
x-tlp-apikey: <merchant-api-key>
x-tlp-signature: <hmac-signature>
```

### Request Body

```json
{
  "emailId": "joe@example.com",
  "externalUserId": "merchant-user-10021",
  "firstName": "Joe",
  "lastName": "Doe",
  "dob": "2001-04-25",
  "countryOfResidence": "BRA",
  "countryOfCitizenship": "BRA", //optional (recommended)
  "countryOfBirth": "BRA", //optional (recommended)
  "taxId": "3100299900", //optional (recommended)
  "phone": "+14165550123" //optional (recommended)
}
```

### Request Parameters

| Field                  | Type   | Required | Description                                                                                                                                           |
| ---------------------- | ------ | -------: | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `emailId`              | String |      Yes | User’s valid email address                                                                                                                            |
| `externalUserId`       | String |      Yes | Unique identifier assigned to the user by the merchant                                                                                                |
| `firstName`            | String |      Yes | User’s legal first name                                                                                                                               |
| `lastName`             | String |      Yes | User’s legal last name                                                                                                                                |
| `dob`                  | String |      Yes | User’s date of birth in `YYYY-MM-DD` format                                                                                                           |
| `countryOfResidence`   | String |      Yes | User’s current country of residence, provided as an ISO 3166-1 alpha-3 country code                                                                   |
| `countryOfCitizenship` | String |       No | User’s country of citizenship, provided as an ISO 3166-1 alpha-3 country code. Although optional, this field is recommended for KYC and AML screening |
| `countryOfBirth`       | String |       No | User’s country of birth, provided as an ISO 3166-1 alpha-3 country code. Although optional, this field is recommended for KYC and AML screening       |
| `taxId`                | String |       No | User’s tax identification number. The format varies by country, for example a CPF for users in Brazil                                                 |
| `phone`                | String |       No | User’s telephone number in international format, including the country calling code                                                                   |

### Country Codes

The following fields must use ISO 3166-1 alpha-3 country codes:

* `countryOfResidence`
* `countryOfCitizenship`
* `countryOfBirth`

Examples:

| Country        | Code  |
| -------------- | ----- |
| Brazil         | `BRA` |
| Canada         | `CAN` |
| Portugal       | `PRT` |
| United States  | `USA` |
| United Kingdom | `GBR` |

### Insert or Update Behaviour

The endpoint operates as an insert-or-update operation.

* If the user does not exist, Tylt creates a new user.
* If the user already exists, Tylt updates the submitted basic profile information.
* The merchant should continue using the same `externalUserId` for subsequent requests relating to the user.
* An `externalUserId` must not be reassigned to a different user.
* Fields omitted from an update request may remain unchanged, depending on the deployed API behaviour.
* The merchant should submit the user’s current and accurate information whenever an update is required.

### Recommended Identification Fields

For effective KYC and AML screening, merchants are strongly encouraged to provide:

* Full legal name
* Date of birth
* Country of residence
* Country of citizenship
* Country of birth
* Tax identification number
* Telephone number

Although `countryOfCitizenship` and `countryOfBirth` are optional, providing them may improve identity matching and reduce false-positive AML screening results.

### JavaScript Example

```javascript
const axios = require("axios");
const crypto = require("crypto");

const baseUrl = "https://dev-api.tylt.money";
const merchantApiKey = process.env.TYLT_API_KEY;
const merchantApiSecret = process.env.TYLT_API_SECRET;

const requestBody = {
  emailId: "joe@example.com",
  externalUserId: "merchant-user-10021",
  firstName: "Joe",
  lastName: "Doe",
  dob: "2001-04-25",
  countryOfResidence: "BRA",
  countryOfCitizenship: "BRA",
  countryOfBirth: "BRA",
  taxId: "3100299900",
  phone: "+14165550123"
};

const rawPayload = JSON.stringify(requestBody);

const signature = crypto
  .createHmac("sha256", merchantApiSecret)
  .update(rawPayload)
  .digest("hex");

const response = await axios.post(
  `${baseUrl}/common/initiateUser`,
  rawPayload,
  {
    headers: {
      "Content-Type": "application/json",
      "x-tlp-apikey": merchantApiKey,
      "x-tlp-signature": signature
    }
  }
);

console.log(response.data);
```

### Validation Requirements

The merchant should ensure that:

* `emailId` contains a valid email address.
* `externalUserId` is unique within the merchant’s system.
* `dob` uses the `YYYY-MM-DD` format.
* Country fields contain valid ISO 3166-1 alpha-3 codes.
* `taxId` is submitted as a string so that leading zeros are preserved.
* `phone` includes the international country calling code.
* Names are submitted using the user’s legal identity-document spelling.

### Example Response

```json
{
"msg": "User provisioned successfully.",
"data": {
"endUserId": 20413,
"externalUserId": "merchant-demo-test",
"kycStatus": "incomplete"
}
}
```


# KYC Module Endpoint

KYC verification modules are initiated through the following endpoint:

```http
POST /common/initiateKyc
```

The verification operation is selected using the `module` field.

Supported modules include:

| **Module** | **Purpose**                    |
| ---------- | ------------------------------ |
| `POI`      | Proof of Identity verification |
| `POA`      | Proof of Address verification  |
| `AML`      | AML screening                  |
| `Liveness` | Liveness verification          |

***

### Proof of Identity — POI

Use the `POI` module to submit the user's identity document for verification.

#### Request Parameters

| **Field**                  | **Type** | **Required** | **Description**                                  |
| -------------------------- | -------- | ------------ | ------------------------------------------------ |
| `emailId`                  | String   | Yes          | Email address of the user                        |
| `module`                   | String   | Yes          | Must be `POI`                                    |
| `payload`                  | Object   | Yes          | Proof-of-identity document information           |
| `payload.poiImageFrontUrl` | String   | Yes          | Secure URL of the front of the identity document |
| `payload.poiImageBackUrl`  | String   | Conditional  | Secure URL of the back of the identity document  |

The back image is not required for single-sided documents such as passports.

#### JavaScript Example

```javascript
const requestBody = {
  emailId: "joe@example.com",
  module: "POI",
  payload: {
    poiImageFrontUrl:
      "https://merchant.example.com/documents/id-front.jpg",
    poiImageBackUrl:
      "https://merchant.example.com/documents/id-back.jpg"
  }
};
```

#### Document URL Requirements

Document URLs should:

* Use HTTPS
* Be accessible by Tylt's verification service
* Point directly to the relevant document image
* Remain valid long enough for verification processing
* Not require an interactive login
* Not expose unrelated user documents
* Use short-lived or restricted-access URLs where supported

The merchant should not use public image-hosting services for production identity documents.

#### Response

```json
{
  "msg": "Didit POI initiation started.",
  "data": {
    "userId": 20413,
    "module": "POI",
    "status": "approved",
    "sessionUrl": null,
    "requestId": "512f270b-e604-40ce-84df-db3063a5c72a",
    "overallKycStatus": "incomplete"
  }
}
```

***

### Proof of Address — POA

Use the `POA` module to submit a proof-of-address document for verification.

#### Request Parameters

| **Field**                | **Type** | **Required** | **Description**                             |
| ------------------------ | -------- | ------------ | ------------------------------------------- |
| `emailId`                | String   | Yes          | Email address of the user                   |
| `module`                 | String   | Yes          | Must be `POA`                               |
| `payload`                | Object   | Yes          | Proof-of-address document information       |
| `payload.poaDocumentUrl` | String   | Yes          | Secure URL of the proof-of-address document |

#### Common Proof-of-Address Documents

Subject to the applicable verification policy, acceptable documents may include:

* Bank statement
* Utility bill
* Government-issued residence document
* Tax document
* Credit-card statement
* Official correspondence showing the user's residential address

Supported document types and document-age requirements are determined by the applicable KYC policy.

#### JavaScript Example

```javascript
const requestBody = {
  emailId: "joe@example.com",
  module: "POA",
  payload: {
    poaDocumentUrl:
      "https://merchant.example.com/documents/address-document.jpg"
  }
};
```

#### Response

```json
{
  "msg": "Didit POA initiation started.",
  "data": {
    "userId": 20413,
    "module": "POA",
    "status": "approved",
    "sessionUrl": null,
    "requestId": "25eb2bf7-3bba-49e3-afa7-bab12d9c5531",
    "overallKycStatus": "incomplete"
  }
}
```

***

### AML Screening

Use the `AML` module to initiate AML screening for the user.

#### Request Parameters

| **Field** | **Type** | **Required** | **Description**           |
| --------- | -------- | ------------ | ------------------------- |
| `emailId` | String   | Yes          | Email address of the user |
| `module`  | String   | Yes          | Must be `AML`             |

No additional `payload` is required for this operation.

#### JavaScript Example

```javascript
const requestBody = {
  emailId: "joe@example.com",
  module: "AML"
};
```

#### Response

```json
{
  "msg": "Didit AML initiation started.",
  "data": {
    "userId": 20413,
    "module": "AML",
    "status": "approved",
    "sessionUrl": null,
    "requestId": "961e0dc6-d035-4a95-aed0-7027b8bcb968",
    "overallKycStatus": "incomplete"
  }
}
```

Depending on the screening result, AML verification may be completed immediately or may require additional review.

#### Possible AML Outcomes

| **Status**        | **Description**                              |
| ----------------- | -------------------------------------------- |
| `approved`        | AML screening has been approved              |
| `pending`         | Screening is still being processed           |
| `requires_review` | Screening requires manual review             |
| `rejected`        | The user did not pass the AML screening      |
| `failed`          | The screening request could not be completed |

> The supported status values should correspond to the statuses returned by the deployed Tylt API.

***

### Liveness Verification

Use the `Liveness` module to initiate a liveness-verification session for the user.

The API returns a user-specific session URL that should be provided to the user to complete the liveness check.

#### Security Requirements

The merchant should:

* Only provide the session link to the relevant user
* Treat the link as sensitive and user-specific
* Avoid logging the complete session URL
* Avoid forwarding the session URL to analytics or third-party tracking services
* Respect the link's expiry period
* Request a new session where the existing session has expired
* Prevent one user from accessing another user's verification session

***

### JavaScript Helper

The following helper can be used to submit signed requests for all supported KYC modules.

```javascript
const axios = require("axios");
const crypto = require("crypto");

const baseUrl = "https://dev-api.tylt.money";

const merchantApiKey = process.env.TYLT_API_KEY;
const merchantApiSecret = process.env.TYLT_API_SECRET;

async function sendSignedRequest(endpoint, requestBody) {
  if (!merchantApiKey || !merchantApiSecret) {
    throw new Error("Missing TYLT API credentials.");
  }

  const rawPayload = JSON.stringify(requestBody);

  const signature = crypto
    .createHmac("sha256", merchantApiSecret)
    .update(rawPayload)
    .digest("hex");

  try {
    const response = await axios.post(
      `${baseUrl}${endpoint}`,
      rawPayload,
      {
        headers: {
          "Content-Type": "application/json",
          "x-tlp-apikey": merchantApiKey,
          "x-tlp-signature": signature
        },
        timeout: 30000
      }
    );

    return response.data;
  } catch (error) {
    const status = error.response?.status;
    const responseData = error.response?.data;

    throw new Error(
      `Tylt API request failed${
        status ? ` with status ${status}` : ""
      }: ${responseData?.msg || error.message}`
    );
  }
}
```

#### Submit POI

```javascript
const result = await sendSignedRequest(
  "/common/initiateKyc",
  {
    emailId: "joe@example.com",
    module: "POI",
    payload: {
      poiImageFrontUrl:
        "https://merchant.example.com/documents/id-front.jpg",
      poiImageBackUrl:
        "https://merchant.example.com/documents/id-back.jpg"
    }
  }
);
```

#### Submit POA

```javascript
const result = await sendSignedRequest(
  "/common/initiateKyc",
  {
    emailId: "joe@example.com",
    module: "POA",
    payload: {
      poaDocumentUrl:
        "https://merchant.example.com/documents/address-document.jpg"
    }
  }
);
```

#### Run AML Screening

```javascript
const result = await sendSignedRequest(
  "/common/initiateKyc",
  {
    emailId: "joe@example.com",
    module: "AML"
  }
);
```

***

### Recommended Verification Sequence

A typical individual KYC flow should follow this sequence:

1. Create or update the user through `/common/initiateUser`.
2. Submit the user's proof of identity using the `POI` module.
3. Submit proof of address using the `POA` module, where required.
4. Run AML screening using the `AML` module.
5. Initiate a liveness-verification session.
6. Ask the user to complete the liveness verification.
7. Retrieve the user's KYC status.
8. Enable regulated wallet or transaction functionality only after all required verification modules have been successfully completed.

***

### Error Handling

A failed request follows the standard response structure:

```json
{
  "msg": "Description of the error",
  "data": {}
}
```

For example:

```json
{
  "msg": "Invalid signature.",
  "data": {}
}
```

Merchants should handle the following HTTP response categories:

| **HTTP Status** | **Description**                                          |
| --------------- | -------------------------------------------------------- |
| `400`           | Missing, malformed, or unsupported request parameters    |
| `401`           | Missing or invalid API authentication                    |
| `403`           | Merchant, user, or requested operation is not authorized |
| `404`           | User or requested resource was not found                 |
| `409`           | Conflicting user or verification data                    |
| `422`           | Submitted verification data could not be processed       |
| `429`           | Too many requests                                        |
| `500`           | Unexpected processing error                              |
| `503`           | Verification service temporarily unavailable             |


# Hosted KYC Widget

Creates a new KYC instance for an individual user and returns a hosted KYC link that can be shared with the user to complete verification.

This endpoint is intended for server-to-server use only and must be called from the merchant's backend.

### Endpoint

```http
POST https://api.tylt.money/kycIndividualUserMerchant/createKYCLinkIndividualUser
```

### Authentication

The request must include the merchant API key and an HMAC-SHA256 signature.

| Header            | Description                                                             |
| ----------------- | ----------------------------------------------------------------------- |
| `x-tlp-apikey`    | Merchant API key                                                        |
| `x-tlp-signature` | HMAC-SHA256 signature of the request body using the merchant API secret |
| `Content-Type`    | `application/json`                                                      |

The merchant is identified from the API key. `merchantId` and `userId` must not be included in the request body.

***

### Request Parameters

| Field       | Type   | Required | Description                                                                           |
| ----------- | ------ | -------- | ------------------------------------------------------------------------------------- |
| `userEmail` | string | Yes      | Valid email address of the individual user for whom the KYC instance is being created |

#### Example Request Body

```json
{
  "userEmail": "user@example.com"
}
```

***

### Example Request

The request signature must be generated from the exact JSON body being sent.

```javascript
import crypto from "crypto";
import axios from "axios";

const apiKey = process.env.TYLT_API_KEY;
const apiSecret = process.env.TYLT_API_SECRET;

const body = {
  userEmail: "user@example.com",
};

const bodyString = JSON.stringify(body);

const signature = crypto
  .createHmac("sha256", apiSecret)
  .update(bodyString)
  .digest("hex");

const response = await axios.post(
  "https://<host>/kycIndividualUserMerchant/createKYCLinkIndividualUser",
  bodyString,
  {
    headers: {
      "Content-Type": "application/json",
      "x-tlp-apikey": apiKey,
      "x-tlp-signature": signature,
    },
  }
);

console.log(response.data);
```

#### Signature Generation

The signature is calculated as:

```
HMAC-SHA256(apiSecret, JSON.stringify(body))
```

The resulting hexadecimal digest must be passed as the `x-tlp-signature` header.

The JSON string used to generate the signature must exactly match the request body sent to the API.

***

### Validation Requirements

The merchant should ensure that:

* `userEmail` contains a valid email address.
* The request is made from the merchant's backend.
* `x-tlp-apikey` and `x-tlp-signature` are included in the request headers.
* The signature is generated using the exact JSON request body.

The merchant identity is automatically resolved from the API key after the signature has been validated.

***

### Response

#### Success Response

**HTTP 201 — Created**

```json
{
  "msg": "KYC instance created successfully.",
  "data": {
    "kycInstanceId": "550e8400-e29b-41d4-a716-446655440000",
    "userEmail": "user@example.com",
    "merchantId": 123,
    "kycLink": "https://app.tylt.money/kyc?kycInstanceId=550e8400-e29b-41d4-a716-446655440000"
  }
}
```

#### Response Parameters

| Field           | Type   | Description                                                                 |
| --------------- | ------ | --------------------------------------------------------------------------- |
| `kycInstanceId` | string | Unique identifier of the KYC instance                                       |
| `userEmail`     | string | Email address of the individual user                                        |
| `merchantId`    | number | Merchant associated with the authenticated API key                          |
| `kycLink`       | string | Hosted KYC URL that should be shared with or opened for the individual user |

The merchant should store the `kycInstanceId` against the user. It can be used to identify the KYC instance for subsequent status checks and KYC operations.

The returned `kycLink` should be used to redirect the user to the hosted KYC verification flow.

***

### Error Responses

#### Invalid User Email

**HTTP 400**

```json
{
  "msg": "A valid userEmail is required.",
  "data": {}
}
```

Returned when `userEmail` is missing, empty, or invalid.

#### Invalid Signature

**HTTP 400**

```json
{
  "msg": "Invalid signature.",
  "data": {}
}
```

Returned when the supplied HMAC signature does not match the request body.

#### Missing Authentication Headers

**HTTP 401**

```json
{
  "msg": "API key and signature headers are required.",
  "data": {}
}
```

Returned when `x-tlp-apikey` or `x-tlp-signature` is missing.

#### Invalid API Key

**HTTP 401**

```json
{
  "msg": "Invalid API key.",
  "data": {}
}
```

Returned when the supplied merchant API key is not recognized.

#### Merchant Identity Missing

**HTTP 403**

```json
{
  "msg": "Merchant identity is missing.",
  "data": {}
}
```

Returned when the API key is not associated with a valid merchant.

#### Server Error

**HTTP 500**

```json
{
  "msg": "Failed to create KYC instance.",
  "data": {}
}
```

Returned when the KYC instance cannot be created because of an internal server or database error.

***

### cURL Example

Generate the `x-tlp-signature` from the exact request body using the merchant API secret.

```bash
curl --location 'https://<host>/kycIndividualUserMerchant/createKYCLinkIndividualUser' \
  --header 'Content-Type: application/json' \
  --header 'x-tlp-apikey: <your_api_key>' \
  --header 'x-tlp-signature: <hmac_sha256_hex>' \
  --data '{"userEmail":"user@example.com"}'
```

***

### Next Step

After receiving the `kycLink`, redirect or share the URL with the individual user.

The hosted KYC flow will collect the required user information and initiate the applicable verification modules, including:

* Basic identity information
* Proof of Identity (POI)
* Proof of Address (POA)
* AML screening
* Liveness verification


# Tylt CPG (crypto gateway )

Tylt CPG is a crypto gateway that enables businesses to accept, transfer, and settle digital assets through a unified API. It provides infrastructure for handling crypto-asset transactions, allowing merchants to receive funds, initiate transfers, and manage balances across supported blockchain networks.

***

#### Accept Crypto-Assets

This section covers the process of enabling end users to transfer crypto-assets to the merchant.

It includes guidance on:

* Creating deposit instances
* Tracking transaction lifecycle and confirmations
* Accessing transaction history and reconciliation data

***

#### Transfer Crypto-Assets

This section covers how merchants can initiate outbound crypto-asset transfers.

Typical use cases include:

* Transfers to external wallet addresses
* Internal treasury movements
* Settlement of obligations in crypto-assets

It also includes guidance on transaction tracking and status monitoring.

***


# Important Concepts

#### **Base URL**

All API requests are made to the following base URL:

```
https://api.tylt.money/
```

Each API request should append the appropriate endpoint to this base URL. For example, for creating a Pay-In request, the endpoint `/transactions/merchant/createPayinRequest` would be appended to the base URL.

#### **BaseCurrency and SettledCurrency in Pay-In Requests**

The **baseCurrency** represents the currency in which the merchant expects to receive the payment, while the **settledCurrency** refers to the currency in which the transaction is processed and settled.

***

**Example 1:**

A merchant sells a pair of shoes on an e-commerce website, priced at $100. The merchant accepts payments in cryptocurrency, and the customer chooses to pay using DAI.

* **baseCurrency**: USD (the currency the merchant prices the shoes in)
* **settledCurrency**: DAI (on Binance Smart Chain or another supported network)

In this case, the merchant expects $100 in USD, but the transaction will be processed in DAI on the BSC network. The merchant will receive the equivalent amount of DAI, calculated automatically by Tylt  based on real-time spot rates at the time of the transaction request.

***

**Example 2:**

The **baseCurrency** doesn't have to be a fiat currency (USD, GBP, EUR, etc.). It can also be a cryptocurrency.

For instance, a merchant providing consulting services charges $100 in USDT.

* If the customer chooses to pay in **USDT**, both the **baseCurrency** and **settledCurrency** will be **USDT**.
* If the customer opts to pay in **DAI**, the **baseCurrency** will be **USDT**, and the **settledCurrency** will be **DAI**.

This scenario shows that both the baseCurrency and settledCurrency can be cryptocurrencies, and Tylt will handle the correct conversion at the moment of the transaction using real-time rates.

{% hint style="info" %}
**Important Notes:**

The **baseCurrency** can be either a supported fiat or cryptocurrency. The **settledCurrency** will always be a cryptocurrency.
{% endhint %}

***

**Good Practices for Using the API**

1. **Use a Unique `merchantOrderId`**

For every transaction, it is highly recommended that you generate and use a unique `merchantOrderId`. This ensures proper tracking and management of each individual payment, reducing the risk of conflicts or duplicate payments.

2. **Utilize Client Name and Notes Fields**

Make good use of the `customerName` and `comments` fields in your API requests. These fields allow you to keep track of payment context, making it easier to identify or reference specific transactions later. Including the client's name or transaction-specific details in these fields can help improve transparency and streamline support in case any issues arise.


# API Reference

The API Reference is your comprehensive guide for integrating the Tylt Crypto Gateway into your application or website with ease. It details every aspect of the available API functionalities, offering clear and concise information for developers, merchants, and businesses alike.

Whether you’re accepting or making crypto payments, reviewing transaction histories, or exploring supporting functionalities like supported currencies and networks, this documentation provides the essential tools for a seamless integration.

#### What You’ll Find in the API Reference:

1. **Accept Crypto Payments**: This section guides you through the process of accepting cryptocurrency payments, including detailed transaction history for pay-ins.
2. **Make Crypto Payments**: Learn how to initiate payouts, including viewing transaction history for payouts.
3. **Supporting APIs**: This section covers additional API functionalities, such as listing supported currencies, networks, and fiat.

Each section provides:

* **Endpoint Descriptions**: A breakdown of each API endpoint.
* **Request & Response Formats**: Clear examples of request and response structures, including status codes.
* **Code Snippets**: Implementations in popular programming languages like Node.js, Python, and more.
* **Error Handling**: Insights into common errors and best practices for managing them.

With this API Reference, you’ll have everything you need to seamlessly integrate Tylt's crypto payment solutions into your platform.


# Accept Crypto-Assets

The Accept Crypto-Assets section covers how merchants can enable end users to transfer crypto-assets to their Tylt-managed wallets. This section provides guidance on creating transaction requests, supporting multiple cryptocurrencies, and managing the lifecycle of incoming crypto-asset transfers.

***

#### Key Capabilities

* **Creating Pay-In Requests**\
  Merchants can generate pay-in instances that allow end users to transfer supported crypto-assets. These requests can be configured using either crypto or fiat-denominated base values.
* **Transaction History**\
  Merchants can access a complete history of all incoming transactions for monitoring, reconciliation, and reporting.
* **Transaction Information**\
  Detailed information for a specific transaction can be retrieved using the associated order or transaction identifier.
* **Webhook Integration**\
  Tylt provides webhook-based callbacks to deliver real-time updates on transaction state changes throughout the lifecycle.

***

#### Overview

This section includes examples for handling incoming crypto-asset transfers across supported networks, configuring base and settlement currencies, and tracking transaction status. The Pay-In Request API is central to this flow and is documented in detail, including request and response formats, authentication requirements, and implementation examples.


# Creating a Pay-in Request

This endpoint allows you to create a new payment link and receive a URL that can be used to complete the accept a crypto payment from your customer. By sending a request to this endpoint with the required parameters, you can generate a payment link for a specific amount and configure various payment options.&#x20;

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/transactions/merchant/createPayinRequest`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>merchantOrderId</code></td><td><code>string</code></td><td>The order ID provided by the Merchant for local reference.</td></tr><tr><td><code>baseAmount</code></td><td><code>number</code></td><td>The amount to be paid.</td></tr><tr><td><code>baseCurrency</code></td><td><code>string</code></td><td>The base currency of the good/service being supplied.</td></tr><tr><td><code>settledCurrency</code></td><td><code>string</code></td><td>The currency in which the payment is to be made.</td></tr><tr><td><code>networkSymbol</code></td><td><code>string</code></td><td>The network symbol for the transaction (e.g., BSC).</td></tr><tr><td><code>callBackUrl</code></td><td><code>string</code></td><td>URL for the callback after transaction completion.</td></tr><tr><td><code>redirectUrl</code></td><td><code>string</code></td><td>URL to redirect the user after completing the payment.</td></tr><tr><td><code>customerName</code></td><td><code>string</code></td><td>Optional: Customer's name for the transaction.</td></tr><tr><td><code>comments</code></td><td><code>string</code></td><td>Optional: Comments for additional context.</td></tr><tr><td><code>settleUnderpayment</code></td><td><code>number</code></td><td><p>This parameter determines how the system handles <strong>underpayments</strong> — cases where the customer pays <strong>less than the expected amount</strong>.</p><hr><p><strong>If <code>settleUnderpayment = 1</code> (Default):</strong></p><ul><li>The transaction will be <strong>automatically settled</strong>, even if the customer sends <strong>less than the required amount</strong>.</li><li>No further payment is expected.</li><li>The merchant assumes responsibility for accepting the shortfall. Refer settledAmountReceived and baseAmountRecieved via the webhook to handle business logic.</li></ul><hr><p><strong>If <code>settleUnderpayment = 0</code>:</strong></p><ul><li>The transaction will <strong>remain unsettled</strong> until the <strong>full expected amount</strong> is received.</li><li>The customer must complete the remaining payment <strong>before the payment intent expires</strong>.</li><li>If the full amount is <strong>not received by the expiry time</strong>, the payment intent will <strong>expire</strong>, and the transaction will Be <strong>settled as underpayment.</strong><br><br>Refer settledAmountReceived and baseAmountRecieved via the webhook to handle business logic.</li></ul></td></tr><tr><td><code>payeeDetails</code></td><td><code>json Object</code></td><td><p>Mandatory object containing Travel Rule data for the transaction originator, required for AML/CFT compliance. <br><br>Structure varies by <code>entityType</code>.</p><p><strong>entityType</strong><br>Specifies originator type: <code>individual</code> or <code>company</code>.<br></p><p><strong>individual</strong><br>Required if <code>entityType = individual</code>. <br>===========================<br><code>firstName</code>, <br><code>lastName</code>, <br><code>DOB</code> (YYYY-MM-DD), <br><code>placeOfBirth</code><br></p><p><strong>company</strong><br>Required if <code>entityType = company</code>.<br>===========================  <br><code>fullName</code>,<br>"<code>address</code>": {<br>"<code>country</code>": "DEU",<br>"<code>town</code>": "Berlin",<br>"<code>postCode</code>": "10115",<br>"<code>street</code>": "Chauseestr.",<br>"<code>buildingNumber</code>": "60"<br>}</p></td></tr></tbody></table>

{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3',
    baseAmount: '1',
    baseCurrency: 'USDT',
    settledCurrency: 'USDT',
    networkSymbol: 'BSC',
    callBackUrl: 'https://www.test.com/callback',
    redirectUrl: 'httpsL//www.test.com/homepage',
    customerName: 'TradingLeagues',
    comments: 'Description testing'
    payeeDetails: {
        entityType: 'induvidual'
        firstName: 'Jon Smith'
        lastName: 'Doe',
        DOB: '1999-09-23'
        placeOfBirth: 'Germany'
    }
        payeeDetails: {
          entityType: 'company'
          fullName: "ACME Corp",
          address: {
          country": 'Germany',
          town: 'Berlin',
          postCode: '10115,
          street: "Chauseestr.",
          buildingNumber: "60"
    }
    
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send the request
axios.post('https://api.tylt.money/transactions/merchant/createPayinRequest', raw, { headers })
    .then(response => console.log("Success:", response.data))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body
{
  "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
  "baseAmount": "1",
  "baseCurrency": "USDT",
  "settledCurrency": "USDT",
  "networkSymbol": "BSC",
  "callBackUrl": "https://www.test.com/callback",
  "customerName": "TradingLeagues",
  "comments": "Description testing",
  "payeeDetails": {
    "entityType": "individual",
    "firstName": "Jon",
    "lastName": "Doe",
    "dateOfBirth": "1999-09-23",
    "placeOfBirth": "Germany"
  },
   "payeeDetails": {
    "entityType": "company",
    "fullName": "ACME Corp",
    "registrationNumber": "HRB123456",
    "address": {
      "country": "DEU",
      "town": "Berlin",
      "postCode": "10115",
      "street": "Chauseestr.",
      "buildingNumber": "60"
    }
}

# Convert request body to JSON
raw = json.dumps(request_body, separators=(',', ':'), ensure_ascii=False)

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Generate signature
signature = create_signature(api_secret, raw)

# Define headers
headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the request
response = requests.post('https://api.tylt.money/transactions/merchant/createPayinRequest', headers=headers, data=raw)
print("Response:", response.json())

```

{% endtab %}

{% tab title="JavaScript (Fetch)" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
const requestBody = {
    merchantOrderId: 'b73b73b-87wtbc-q36gbc-331n3',
    baseAmount: '1',
    baseCurrency: 'USDT',
    settledCurrency: 'USDT',
    networkSymbol: 'BSC',
    callBackUrl: 'https://www.test.com/callback',
    customerName: 'TradingLeagues',
    comments: 'Description testing',
    payeeDetails: {
        entityType: 'induvidual'
        firstName: 'Jon Smith'
        lastName: 'Doe',
        DOB: '1999-09-23'
        placeOfBirth: 'Germany'
    }
        payeeDetails: {
          entityType: 'induvidual'
          fullName: "ACME Corp",
          address: {
          country": 'Germany',
          town: 'Berlin',
          postCode: '10115,
          street: "Chauseestr.",
          buildingNumber: "60"
    }
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: body,
    });
    return response.json();
};

// Send the request
sendRequest('https://api.tylt.money/transactions/merchant/createPayinRequest', headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

<pre class="language-json"><code class="lang-json">{
    "data": {
        "orderId": "d0d6ff5f-79b6-11ef-8277-02d8461243e9",
        "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
        "baseAmount": 1,
        "baseCurrency": "USDT",
        "settledCurrency": "USDT",
        "settledAmountRequested": 1,
        "settledAmountReceived": 0,
        "settledAmountCredited": 0,
        "commission":<a data-footnote-ref href="#user-content-fn-1"> </a>0.01,
        "network": "BSC",
        "depositAddress": "0xbfae84b277c5b791206a58f634b88527287bf2f8",
        "status": "Pending",
        "paymentURL": "https://app.tylt.money/pscreen/d0d6ff5f-79b6-11ef-8277-02d8461243e9",
        "callBackURL": "",
        "redirectURL":"",
        "transactions": [],
        "createdAt": "2024-09-23T14:19:16Z",
        "expiresAt": "2024-09-23T15:19:16Z",
        "updatedAt": "2024-09-23T14:19:16Z",
        "isFinal": 0,
        "isCredited": 0,
        "customerName": "TradingLeagues",
        "comments": "Description testing 234"
    },
    "msg": ""
}
</code></pre>

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>orderId</td><td>string</td><td>The order ID generated by TL Pay.</td></tr><tr><td>merchantOrderId</td><td>string</td><td>The order ID provided by the Merchant at the time of request.</td></tr><tr><td>baseAmount</td><td>number</td><td>The  value of the good/service being supplied expressed in the baseCurrency</td></tr><tr><td>baseCurrency</td><td>string</td><td>The base currency of the good/service. (symbol)</td></tr><tr><td>settledCurrency</td><td>string</td><td>The crypto currency in which the payment is to be made by the customer. (symbol)</td></tr><tr><td>settledAmountRequested</td><td>number</td><td>The amount of crypto currency requested from the customer.</td></tr><tr><td>settledAmountReceived</td><td>number</td><td>The amount of  crypto currency received from the customer.</td></tr><tr><td>settledAmountCredited</td><td>number</td><td>The amount of crypto currency credited to your balance.</td></tr><tr><td>commission</td><td>number</td><td>The commission deducted for the transaction.</td></tr><tr><td>network</td><td>string</td><td>The crypto network used for the payment.</td></tr><tr><td>depositAddress</td><td>string</td><td>The address where the payment should be sent by the customer.</td></tr><tr><td>status</td><td>string</td><td>The status of the transaction (e.g., Pending, Completed).</td></tr><tr><td>paymentURL</td><td>string</td><td>The URL for the customer to make the payment.</td></tr><tr><td>callBackURL</td><td>string</td><td>The URL for callback notifications.</td></tr><tr><td>transactions</td><td>array</td><td>Details of the transactions associated with the payment.</td></tr><tr><td>createdAt</td><td>string</td><td>The timestamp when the request was created.</td></tr><tr><td>expiresAt</td><td>string</td><td>The timestamp when the request expires.</td></tr><tr><td>updatedAt</td><td>string</td><td>The timestamp when the request was last updated.</td></tr><tr><td>isFinal</td><td>number</td><td>Indicates if the transaction is completed (1) or pending (0).</td></tr><tr><td>isCredited</td><td>number</td><td>Indicates if the payment has been credited (1) or not (0).</td></tr><tr><td>customerName</td><td>string</td><td>The name of the customer making the payment.</td></tr><tr><td>comments</td><td>string</td><td>Additional comments provided during the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

***

#### <mark style="background-color:orange;">**Understanding BaseCurrency and SettledCurrency in Pay-In Requests**</mark>

The **baseCurrency** represents the currency in which the merchant expects to receive the payment, while the **settledCurrency** refers to the currency in which the transaction is processed and settled.

***

**Example 1:**

A merchant sells a pair of shoes on an e-commerce website, priced at $100. The merchant accepts payments in cryptocurrency, and the customer chooses to pay using DAI.

* **baseCurrency**: USD (the currency the merchant prices the shoes in)
* **settledCurrency**: DAI (on Binance Smart Chain or another supported network)

In this case, the merchant expects $100 in USD, but the transaction will be processed in DAI on the BSC network. The merchant will receive the equivalent amount of DAI, calculated automatically by Tylt based on real-time spot rates at the time of the transaction request.

***

**Example 2:**

The **baseCurrency** doesn't have to be a fiat currency (USD, GBP, EUR, etc.). It can also be a cryptocurrency.

For instance, a merchant providing consulting services charges $100 in USDT.

* If the customer chooses to pay in **USDT**, both the **baseCurrency** and **settledCurrency** will be **USDT**.
* If the customer opts to pay in **DAI**, the **baseCurrency** will be **USDT**, and the **settledCurrency** will be **DAI**.

This scenario shows that both the baseCurrency and settledCurrency can be cryptocurrencies, and Tylt will handle the correct conversion at the moment of the transaction using real-time rates.

{% hint style="info" %}
**Important Notes:**

The **baseCurrency** can be either a supported fiat or cryptocurrency. The **settledCurrency** will always be a cryptocurrency.
{% endhint %}

[^1]:


# Get Pay-In Transaction History

This endpoint allows you to retrieve the history of all Pay-In transactions associated with your merchant account. The results are paginated, allowing you to specify the number of rows and the page number.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?rows={numberRows}&page={pagenumber}`

**Endpoint  Example**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?rows=20&page=1`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Query Parameters
const params = {rows:20,page:1};
const queryParams = new URLSearchParams(params).toString();

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update( JSON.stringify(params) )
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
axios.get(`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?${queryParams}`, { headers })
  .then(response => {
    console.log("Response:", response.data);
  })
  .catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Query Parameters
params = {"rows":"20","page":"1"}
query_params = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)


# Create the HMAC SHA-256 signature
signature = hmac.new(api_secret.encode(), body_string.encode(), hashlib.sha256).hexdigest()

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the GET request
response = requests.get(f"https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?{query_params}", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Query Parameters
const params = {rows:20,page:1};
const queryParams = new URLSearchParams(params).toString();

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update( JSON.stringify(params) )
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
fetch(`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?${queryParams}`, { headers })
  .then(response => response.json())
  .then(data => console.log("Response:", data))
  .catch(error => console.error('Error:', error));


```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "orderId": "0c635376-769a-11ef-8277-02d8461243e9",
            "merchantOrderId": "0c635376-769a-11ef-8277-02d8461243e9",
            "baseAmount": 1,
            "baseCurrency": "USDT",
            "settledCurrency": "USDT",
            "settledAmountRequested": 1,
            "settledAmountReceived": 0,
            "settledAmountCredited": 0,
            "commission": 0,
            "network": "TPNK",
            "depositAddress": "2828a803-72a7-11ef-8277-02d8461243e9",
            "status": "Completed",
            "paymentURL": "",
            "callBackURL": "",
            "transactions": [
                {
                    "amount": 1,
                    "createdAt": "2024-09-19 15:15:47.000000",
                    "updatedAt": "2024-09-19 15:15:47.000000",
                    "fromAddress": "2828a803-72a7-11ef-8277-02d8461243e9",
                    "transactionHash": "0c6fbc0c-769a-11ef-8277-02d8461243e9",
                    "confirmationStatus": 1
                }
            ],
            "createdAt": "2024-09-19T15:15:47Z",
            "expiresAt": "2024-09-19T15:15:47Z",
            "updatedAt": "2024-09-19T15:15:47Z",
            "isFinal": 1,
            "isCredited": 0,
            "customerName": "",
            "comments": ""
        },
        {
            "orderId": "6e75e180-768d-11ef-8277-02d8461243e9",
            "merchantOrderId": "",
            "baseAmount": 1,
            "baseCurrency": "USDT",
            "settledCurrency": "USDT",
            "settledAmountRequested": 1,
            "settledAmountReceived": 2,
            "settledAmountCredited": 1.99,
            "commission": 0.01,
            "network": "BSC",
            "depositAddress": "0x0b4f3ad04c183573bb5d363cab3e5bf6603088a5",
            "status": "Over Payment",
            "paymentURL": "https://app.tylt.money/pscreen/6e75e180-768d-11ef-8277-02d8461243e9",
            "callBackURL": "",
            "transactions": [
                {
                    "amount": 2,
                    "createdAt": "2024-09-19 13:45:55.000000",
                    "updatedAt": "2024-09-19 13:46:45.000000",
                    "fromAddress": "0xd2af4b117efe474b66fc79e6a8e1938d41a60f4c",
                    "transactionHash": "0x28d22fe7def4b65176ba97793d213b775d0386aa0e22a1c5a3cc8c2b376f83e7",
                    "confirmationStatus": 1
                }
            ],
            "createdAt": "2024-09-19T13:45:28Z",
            "expiresAt": "2024-09-19T14:45:28Z",
            "updatedAt": "2024-09-19T13:46:49Z",
            "isFinal": 1,
            "isCredited": 1,
            "customerName": "",
            "comments": ""
        }
    ],
    "errorCode": 0,
    "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field Name               | Type   | Description                                                                                                                                 |
| ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------- |
| `orderId`                | String | The order ID generated by TL Pay and used as a global identifier.                                                                           |
| `merchantOrderId`        | String | The order ID provided by the merchant at the time of the request (optional).                                                                |
| `baseAmount`             | Number | The base value of the good or service being supplied.                                                                                       |
| `baseCurrency`           | String | The base currency of the good or service being supplied (e.g., "USDT").                                                                     |
| `settledCurrency`        | String | The cryptocurrency or token used for the payment by the customer.                                                                           |
| `settledAmountRequested` | Number | The amount of cryptocurrency or token requested from the customer.                                                                          |
| `settledAmountReceived`  | Number | The amount of cryptocurrency or token received from the customer.                                                                           |
| `settledAmountCredited`  | Number | The amount of cryptocurrency or token credited to your balance (net).                                                                       |
| `commission`             | Number | The commission deducted towards the transaction.                                                                                            |
| `network`                | String | The crypto network over which the payment is made (e.g., "BSC").                                                                            |
| `depositAddress`         | String | The wallet address where the payment is to be deposited.                                                                                    |
| `status`                 | String | The status of the transaction (e.g., "Expired").                                                                                            |
| `paymentURL`             | String | The payment link that needs to be used by the customer to make the payment.                                                                 |
| `callBackURL`            | String | The callback URL specified at the time of request.                                                                                          |
| `transactions`           | Array  | The details of the transactions that result in the payment.                                                                                 |
| `createdAt`              | String | The timestamp when the transaction was created (ISO 8601 format).                                                                           |
| `expiresAt`              | String | The timestamp when the transaction expires (ISO 8601 format).                                                                               |
| `updatedAt`              | String | The timestamp when the transaction was last updated (ISO 8601 format).                                                                      |
| `isFinal`                | Number | Indicates whether the transaction is completed (`1` for completed, `0` for incomplete).                                                     |
| `isCredited`             | Number | Indicates whether the credit associated with the payment has been applied to the merchant account (`1` for credited, `0` for not credited). |
| `customerName`           | String | The customer name provided by the merchant when making the request (optional).                                                              |
| `comments`               | String | Comments provided by the merchant when making the request (optional).                                                                       |
| {% endtab %}             |        |                                                                                                                                             |
| {% endtabs %}            |        |                                                                                                                                             |


# Get Pay-In Transaction Information

This endpoint allows you to retrieve detailed information about a specific Pay-In transaction. The `orderId` is required, and it corresponds to the unique identifier generated by Tylt for the transaction.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?`orderId={orderId}

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?orderId=a49579dd-7711-11ef-8277-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hashlib
import hmac
import json

url = "https://api.tylt.money/transactions/merchant/getPayinTransactionInformation"

params = {
    'orderId': 'a49579dd-7711-11ef-8277-02d8461243e9'
}

api_key = 'your-api-key'
secret_key = 'your-secret-key'

query_string = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)


signature = hmac.new(secret_key.encode(), body_string.encode(), hashlib.sha256).hexdigest()

headers = {
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature
}

response = requests.get(url, headers=headers, params=params)
print(response.text)

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayinTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": {
        "orderId": "a49579dd-7711-11ef-8277-02d8461243e9",
        "merchantOrderId": "b73b73b-87wtbc-q36gbc-331n3",
        "baseAmount": 1,
        "baseCurrency": "USDT",
        "baseAmountRecieved": 10
        "settledCurrency": "USDT",
        "settledAmountRequested": 1,
        "settledAmountReceived": 0,
        "settledAmountCredited": 0,
        "commission": 0.01,
        "network": "BSC",
        "depositAddress": "0xdbfc3d80de367906ccb456fe2eed57c39f05f63c",
        "status": "Expired",
        "paymentURL": "https://app.tylt.money/pscreen/a49579dd-7711-11ef-8277-02d8461243e9",
        "callBackURL": "",
        "transactions": [],
        "createdAt": "2024-09-20T05:31:53Z",
        "expiresAt": "2024-09-20T06:31:53Z",
        "updatedAt": "2024-09-20T06:31:56Z",
        "isFinal": 1,
        "isCredited": 0,
        "customerName": "TradingLeagues",
        "comments": "Description testing 234"
    }
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                              |
| ------------------------ | -------- | -------------------------------------------------------------------------------------------- |
| `orderId`                | string   | The order ID generated by TL Pay, used as a global identifier for the transaction.           |
| `merchantOrderId`        | string   | The order ID provided by the Merchant, used for local reference (optional).                  |
| `baseAmount`             | number   | The base value of the good/service being supplied.                                           |
| `baseCurrency`           | string   | The base currency of the good/service being supplied.                                        |
| `baseAmountReceived`     | number   | The amount of cryptocurrency/token received from the customer expressed in the baseCurrency. |
| `settledCurrency`        | string   | The cryptocurrency/token in which the payment is to be made by the customer.                 |
| `settledAmountRequested` | number   | The amount of cryptocurrency/token requested from the customer.                              |
| `settledAmountReceived`  | number   | The amount of cryptocurrency/token received from the customer.                               |
| `settledAmountCredited`  | number   | The amount of cryptocurrency/token credited to the merchant's balance (net).                 |
| `commission`             | number   | The commission deducted for the transaction.                                                 |
| `network`                | string   | The cryptocurrency network over which the payment is made.                                   |
| `depositAddress`         | string   | The address for receiving the payment.                                                       |
| `status`                 | string   | The status of the transaction (e.g., Expired, Pending, Completed).                           |
| `paymentURL`             | string   | The payment link that needs to be used by the customer to make the payment.                  |
| `callBackURL`            | string   | The callback URL for post-payment notifications (if applicable).                             |
| `transactions`           | array    | Details of the transactions resulting in the payment (if any).                               |
| `createdAt`              | string   | The timestamp when the transaction was created.                                              |
| `expiresAt`              | string   | The timestamp when the transaction expires.                                                  |
| `updatedAt`              | string   | The timestamp when the transaction was last updated.                                         |
| `isFinal`                | number   | Indicates if the transaction is complete (1) or still processing (0).                        |
| `isCredited`             | number   | Indicates if the payment has been credited to the merchant account (1: Yes, 0: No).          |
| `customerName`           | string   | The name of the customer provided by the merchant (optional).                                |
| `comments`               | string   | Comments provided by the merchant about the transaction (optional).                          |

{% endtab %}
{% endtabs %}

### Understanding and Handling Transactions Based on Status

The response field **`status`** represents the current state of a transaction. Applications should interpret and handle transactions according to the following possible states:

| Status        | Description                                                                                                            |
| ------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Pending       | The transaction is awaiting payment or confirmation.                                                                   |
| Completed     | The transaction is successfully completed and settled. The customer has paid **exactly** the `settledAmountRequested`. |
| Under Payment | The transaction is completed and settled, but the customer paid **less** than the `settledAmountRequested`.            |
| Over Payment  | The transaction is completed and settled, but the customer paid **more** than the `settledAmountRequested`.            |
| Expired       | The transaction expired without any payment being received from the customer.                                          |

***

## Understanding and Handling Over-Payment and Under-Payment

How a merchant handles over-payments and under-payments depends on their **business model**, **use case**, and **internal policies**. Broadly, practices differ between industries that **accept deposits** and those that **sell goods or services**.

***

### 1. Industries Accepting Deposits

*(e.g., iGaming, Trading, Forex, Wallet Services, Insurance)*

In these industries, payments are treated as **deposits into a user account/wallet**. The user’s balance is updated based on either:

* **baseCurrencyReceived** → The fiat or local equivalent value at the time of receipt (e.g., BRL, AED).
* **settledCurrencyReceived** → The actual crypto amount received in the settlement currency (e.g., USDT).

#### Under-Payment

* Merchant may accept the partial payment and **credit proportionally**.
* Merchant may choose to **refund the entire amount**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

#### Over-Payment

* Merchant may **refund the excess**.
* Merchant may accept the full amount and **credit the total received**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

***

**Example A: Deposit Requested in Crypto (USDT)**

* **Requested**: 100 USDT
* **Received**: 95 USDT (under-payment) → Merchant credits **95 USDT** to user wallet.
* **Received**: 105 USDT (over-payment) → Merchant credits **105 USDT** to user wallet.

Since both the **baseCurrency** and **settledCurrency** are the same (USDT), the merchant may use either `baseCurrencyReceived` or `settledCurrencyReceived` to handle the business logic.

***

**Example B: Deposit Requested in Fiat (FX-Denominated)**

* **Requested**: 500 BRL equivalent

1. **Received**: 95 USDT → At settlement, worth **475 BRL**.
   * Merchant may credit:
     * **475 BRL** (using `baseCurrencyReceived`), OR
     * **95 USDT** (using `settledCurrencyReceived`).
2. **Received**: 105 USDT → At settlement, worth **525 BRL**.
   * Merchant may credit:
     * **525 BRL** (using `baseCurrencyReceived`), OR
     * **105 USDT** (using `settledCurrencyReceived`).

{% hint style="warning" %}
**Response Records:**

* `baseCurrencyReceived = 475 BRL / 525 BRL`
* `settledCurrencyReceived = 95 USDT / 105 USDT`

This **dual recording** ensures flexibility: deposits can be credited in either **fiat terms** or **crypto terms**, depending on merchant policy.
{% endhint %}

***

### 2. Industries Accepting Payments for Sale of Merchandise

*(e.g., Retail, eCommerce, SaaS, Subscriptions)*

Here, payments correspond to a **specific invoice** for goods or services. Merchants may settle either in **fiat equivalent value** or in the **crypto amount received**.

#### Under-Payment

* Merchant may **hold the order** until the missing balance is paid.&#x20;
* Merchant may **accept partial payment** and adjust/store credit accordingly.

#### Over-Payment

* Merchant may **refund the excess amount**.
* Merchant may **apply the excess as store credit**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

***

#### 📌 Example A: Invoice Requested in Crypto (USDT)

* **Invoice**: 100 USDT

1. **Received = 95 USDT (under-payment)**

   * (a) Hold order until extra 5 USDT is received.
   * (b) Accept 95 USDT and adjust/store credit.

   **Response Records:**

   * `baseCurrencyReceived = 95 USDT`
   * `settledCurrencyReceived = 95 USDT`
2. **Received = 105 USDT (over-payment)**

   * (a) Ship order and refund 5 USDT.
   * (b) Apply 5 USDT as store credit.

   **Response Records:**

   * `baseCurrencyReceived = 105 USDT`
   * `settledCurrencyReceived = 105 USDT`

***

#### 📌 Example B: Invoice Requested in Fiat (AED)

* **Invoice**: 1,000 AED

1. **Received = 95 USDT → 950 AED (under-payment)**

   * (a) Hold order until missing 50 AED is received.
   * (b) Process order for 950 AED value.
   * (c) Refund the entire amount.

   **Response Records:**

   * `baseCurrencyReceived = 950 AED`
   * `settledCurrencyReceived = 95 USDT`
2. **Received = 105 USDT → 1,050 AED (over-payment)**

   * (a) Ship order for 1,000 AED and refund 50 AED.
   * (b) Apply 50 AED as store credit.
   * (c) Refund the entire 1,050 AED.

   **Response Records:**

   * `baseCurrencyReceived = 1,050 AED`
   * `settledCurrencyReceived = 105 USDT`

{% hint style="warning" %}
**Response Records:**

* `baseCurrencyReceived = 1,050 AED / 950 AED`
* `settledCurrencyReceived = 95 USDT / 105 USDT`

This **dual recording** ensures flexibility: deposits can be credited in either **fiat terms** or **crypto terms**, depending on merchant policy.
{% endhint %}

***


# Set Custom Conversion Rate

{% hint style="warning" %}

#### **Important Notes:**

The **Custom Conversion Rate** feature is restricted and must be explicitly enabled by an administrator. Only merchants with prior approval will be able to set custom crypto-to-fiat conversion rates.

If you wish to use this feature, please contact customer support or your account administrator to request access.
{% endhint %}

This endpoint allows a merchant to configure a custom exchange rate between a cryptocurrency (e.g., USDT) and a fiat currency (e.g., Brazilian Real).

For example, if your products or services are priced in Brazilian Real (BRL), but you want your customers to pay in USDT, you can define the conversion rate manually. By doing so, you control how many USDT the customer must pay for a given BRL-denominated price, instead of relying on live market rates.

This is particularly useful in the following scenarios:

* You want to apply a fixed or preferential rate for your customers.
* You operate in markets with volatile exchange rates.
* You wish to include your own markup or discount within the rate.

Once set, this custom rate will be used during the checkout or payment process for conversions from BRL to USDT.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/transactions/merchant/setRate`

**Request Headers**

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>transactionType</code></td><td><code>string</code></td><td>Represents the type of transaction for which the custom rate should be applied (e.g., "payin" or "payout"). <strong>Note:</strong> If not specified, the default value is "payin".      </td></tr><tr><td><code>fromCurrencySymbol</code></td><td><code>string</code></td><td>Represents the symbol/code of the fiat currency (e.g., "BRL", "INR", "USD"). <strong>Note:</strong> <code>fromCurrencySymbol</code> must belong to a fiat currency</td></tr><tr><td><code>toCurrencySymbol</code></td><td><code>number</code></td><td>Represents the symbol/code of the crypto currency (e.g., "USDT", "USDC", "DAI"). <strong>Note:</strong> toCurrencySymbol must belong to a crypto currency</td></tr><tr><td><code>rate</code></td><td><code>number</code></td><td>The custom conversion rate. </td></tr><tr><td><code>isReciprocal</code></td><td><code>number</code></td><td><p>Determines the direction of the exchange rate you are providing.</p><ul><li>Set <code>isReciprocal = 0</code> if your rate means:<br><strong>1 unit of <code>fromCurrencySymbol</code> = </strong><em><strong>N</strong></em><strong> units of <code>toCurrencySymbol</code></strong><br>(e.g., 1 BRL = 0.20 USDT)</li><li>Set <code>isReciprocal = 1</code> if your rate means:<br><strong>1 unit of <code>toCurrencySymbol</code> = </strong><em><strong>N</strong></em><strong> units of <code>fromCurrencySymbol</code></strong><br>(e.g., 1 USDT = 5 BRL)</li></ul><p>This flag ensures clarity on whether the rate is expressed in a direct or inverse form.</p></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
import axios from "axios";
import crypto from "crypto";

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const data = {
    transactionType: "payin", 
    fromCurrencySymbol: "INR", // compulsory
    toCurrencySymbol: "USDT", // compulsory
    rate: 90.50, // compulsory
    isReceiprocal: 1
};

/*
    fromCurrencySymbol and toCurrencySymbol are compulsory
    rate is compulsory
    fromCurrencySymbol can only be of currenctType 'fiat'
    toCurrencySymbol can only be of currenctType 'crypto'

    currencyType of a currency can be checked here - 
    https://docs.tylt.money/tylt-cpg-crypto-payment-gateway/api-reference/supporting-apis/supported-base-currency-list

    For your reference - 
    fromCurrencySymbol can be 'INR' and other fiat currencies
    toCurrencySymbol can be 'USDT' and other crypto currencies
*/

const signaturePayload = JSON.stringify(data);
const signature = crypto
    .createHmac("sha256", apiSecret)
    .update(signaturePayload)
    .digest("hex");

const url = `https://api.tylt.money/transactions/merchant/setRate`;

const config = {
    method: "post",
    url: url,
    headers: {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature,
    },
    data: data,
};

axios
    .request(config)
    .then((response) => {
        console.log(JSON.stringify(response.data));
    })
    .catch((error) => {
        console.error(error);
    });import requests
```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body (all fields are compulsory)
body = {
    "transactionType": "payin", 
    "fromCurrencySymbol": "INR",   # fiat
    "toCurrencySymbol": "USDT",   # crypto
    "rate": 90.50,
    "isReceiprocal": 1
}

# Prepare body for signature
body_string = json.dumps(body, separators=(',', ':'), ensure_ascii=False)

# Create the HMAC SHA-256 signature
signature = hmac.new(api_secret.encode(), body_string.encode(), hashlib.sha256).hexdigest()

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature,
    "Content-Type": "application/json"
}

# Send the POST request
response = requests.post("https://api.tylt.money/transactions/merchant/setRate", headers=headers, data=body_string)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript (Fetch)" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body for setting the rate
const requestBody = {
    transactionType: "payin", 
    fromCurrencySymbol: 'INR',  // fiat
    toCurrencySymbol: 'USDT',   // crypto
    rate: 90.50,
    isReceiprocal: 1
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await fetch(url, {
        method: 'POST',
        headers: headers,
        body: body,
    });

    if (!response.ok) {
        const errorText = await response.text();
        throw new Error(`HTTP ${response.status}: ${errorText}`);
    }

    return response.json();
};

// Send the request
sendRequest('https://api.tylt.money/transactions/merchant/setRate', headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": {},
    "errorCode": 0,
    "msg": "Rate inserted successfully"
}
```

{% endtab %}
{% endtabs %}

***


# Get Custom Conversion Rate History

This endpoint retrieves the custom crypto-to-FX rate configured by the merchant

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getRateHistory?fromCurrencySymbol={fromCurrencySymbol}&toCurrencySymbol={toCurrencySymbol}&transactionType={transactionType}`

**Endpoint  Example**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getRateHistory?fromCurrencySymbol=INR&toCurrencySymbol=USDT&transactionType=payin`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
import axios from "axios";
import crypto from "crypto";

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

const data = {
    fromCurrencySymbol: "INR", // optional
    toCurrencySymbol: "USDT", // optional
    transactionType: "payin" // optional. Accepted values: "payin" , "payout"
};

/*
    If you pass both, it gives 10 most recent rates with fromCurrencySymbol and toCurrencySymbol
    If you pass one, it gives 10 most recent rates with that fromCurrencySymbol or toCurrencySymbol, whichever one is passed
    If you pass none, it gives 10 most recent rates irrespective of currencySymbol
    If you pass either the fromCurrencySymbol or the toCurrencySymbol, remember -
    
    fromCurrencySymbol can only be of currenctType 'fiat'
    toCurrencySymbol can only be of currenctType 'crypto'

    currencyType of a currency can be checked here - 
    https://docs.tylt.money/tylt-cpg-crypto-payment-gateway/api-reference/supporting-apis/supported-base-currency-list

    For your reference - 
    fromCurrencySymbol can be 'INR' and other fiat currencies
    toCurrencySymbol can be 'USDT' and other crypto currencies
*/

const queryString = new URLSearchParams(data).toString();
const signaturePayload = JSON.stringify(data);
const signature = crypto
    .createHmac("sha256", apiSecret)
    .update(signaturePayload)
    .digest("hex");

const url = `https://api.tylt.money/transactions/merchant/getRateHistory?${queryString}`;

const config = {
    method: "get",
    url: url,
    headers: {
        "X-TLP-APIKEY": apiKey,
        "X-TLP-SIGNATURE": signature,
    },
};

axios
    .request(config)
    .then((response) => {
        console.log(JSON.stringify(response.data));
    })
    .catch((error) => {
        console.error(error);
    });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Query Parameters
params = {
    "fromCurrencySymbol": "INR",  # optional
    "toCurrencySymbol": "USDT",   # optional
    "transactionType": "payin" # optional. Accepted values: "payin" , "payout"
}

# Create query string for URL
query_params = '&'.join([f"{key}={value}" for key, value in params.items()])

# Use compact JSON string for signing
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)

# Generate HMAC SHA-256 signature
signature = hmac.new(api_secret.encode(), body_string.encode(), hashlib.sha256).hexdigest()

# Set headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send GET request
response = requests.get(
    f"https://api.tylt.money/transactions/merchant/getRateHistory?{query_params}",
    headers=headers
)

# Print response
if response.status_code == 200:
    print("Response:", json.dumps(response.json(), indent=2))
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const fetch = require('node-fetch');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Query Parameters
const params = {
  fromCurrencySymbol: 'INR',  // optional
  toCurrencySymbol: 'USDT'    // optional
  transactionType: "payin" // optional. Accepted values: "payin" , "payout"
};

const queryParams = new URLSearchParams(params).toString();

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(JSON.stringify(params))  // compact JSON body
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
fetch(`https://api.tylt.money/transactions/merchant/getRateHistory?${queryParams}`, { headers })
  .then(response => {
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response.json();
  })
  .then(data => console.log("Response:", data))
  .catch(error => console.error("Error:", error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "data": [
    {
      "fromCurrencySymbol": "INR",
      "toCurrencySymbol": "USDT",
      "rate": "90.000000000000000000000000000000",
      "createdAt": "2025-08-04T12:18:07Z",
      "isReciprocal": 0
      "transactionType": "payin" 
    }
  ],
  "errorCode": 0,
  "msg": "Rate history fetched successfully"
}
```

{% endtab %}
{% endtabs %}


# Transfer Crypto-Assets

The Transfer Crypto-Assets section covers how merchants can initiate outbound transfers of crypto-assets using the Tylt API.This section provides guidance on creating transfer requests, managing transaction execution, and tracking the lifecycle of outbound crypto-asset movements across supported blockchain networks.

***

#### Key Capabilities

* **Creating Transfer Requests**\
  Merchants can initiate transfers of supported crypto-assets to external wallet addresses or internal accounts. Transfers can be configured using crypto-denominated values.
* **Transaction Tracking**\
  Merchants can monitor the status of each transfer, including initiation, broadcast, and on-chain confirmation.
* **Transaction Information**\
  Detailed information for a specific transfer can be retrieved using the associated transaction or order identifier.
* **Webhook Integration**\
  Tylt provides webhook-based callbacks to deliver real-time updates on transfer status and lifecycle events.


# Creating a Payout Request

This resource allows users to submit cryptocurrency payouts to active recipients. It caters to various use cases such as offering cryptocurrency withdrawals to clients, facilitating payouts for marketplaces or affiliate networks, or managing payroll by creating multiple payouts at a time.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/transactions/merchant/createPayoutRequest`

**Request Headers**

{% tabs %}
{% tab %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="172"></th><th width="136"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>merchantOrderId</td><td>string</td><td>The order ID provided by the Merchant for local reference.</td></tr><tr><td>baseAmount</td><td>number</td><td>The amount of currency to be sent.</td></tr><tr><td>baseCurrency</td><td>string</td><td><strong>Optional:</strong> To be used if the amount into crypto to be sent is expressed as FIAT. The baseCurrency symbol must be of the FIAT currency. Check supporting baseCurrency API for more details.</td></tr><tr><td>address</td><td>string</td><td>The recipient's address for the payout.</td></tr><tr><td>settledCurrency</td><td>string</td><td>The currency in which the payout will be made (symbol).</td></tr><tr><td>networkSymbol</td><td>string</td><td>The network to be used for the payout (e.g., BSC).</td></tr><tr><td>customerName</td><td>string</td><td>Optional: Customer's name for the transaction.</td></tr><tr><td>comments</td><td>string</td><td>Optional: Comments for additional context.</td></tr><tr><td>callBackUrl</td><td>string</td><td>Optional: URL for the callback after transaction completion.</td></tr><tr><td>redirectUrl</td><td>string</td><td>Optional: URL for the redirection after transaction completion.</td></tr><tr><td>beneficiaryDetails</td><td>jsonObject</td><td><p>Mandatory object containing Travel Rule data for the transaction originator, required for AML/CFT compliance. <br><br>Structure varies by <code>entityType</code>.</p><p><strong>entityType</strong><br>Specifies originator type: <code>individual</code> or <code>company</code>.<br></p><p><strong>individual</strong><br>Required if <code>entityType = individual</code>. <br>===========================<br><code>firstName</code>, <br><code>lastName</code>, <br><code>DOB</code> (YYYY-MM-DD), <br><code>placeOfBirth</code><br></p><p><strong>company</strong><br>Required if <code>entityType = company</code>.<br>===========================  <br><code>fullName</code>,<br>"<code>address</code>": {<br>"<code>country</code>": "DEU",<br>"<code>town</code>": "Berlin",<br>"<code>postCode</code>": "10115",<br>"<code>street</code>": "Chauseestr.",<br>"<code>buildingNumber</code>": "60"<br>}</p></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
// In this example we are sending USDT worth INR 10000 to the web3 address
const requestBody = {
    merchantOrderId: UUID(),
    baseAmount: 10000,
    baseCurrency: "INR"
    address: "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
    settledCurrency: "USDT",
    networkSymbol: "BSC",
    callBackUrl:"www.callback.com",
    redirectUrl:"www.redirect.com",
    beneficiaryDetails: {
        entityType: 'induvidual'
        firstName: 'Jon Smith'
        lastName: 'Doe',
        DOB: '1999-09-23'
        placeOfBirth: 'Germany'
    }
    beneficiaryDetails: {
          entityType: 'company'
          fullName: "ACME Corp",
          address: {
          country": 'Germany',
          town: 'Berlin',
          postCode: '10115,
          street: "Chauseestr.",
          buildingNumber: "60"
    }
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await axios.post(url, body, { headers: headers });
    return response.data;
};

// Send the request
sendRequest("https://api.tylt.money/transactions/merchant/createPayoutRequest", headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body
request_body = {
    "baseAmount": 10000,
    "baseCurrency": "INR"
    "address": "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
    "settledCurrency": "USDT",
    "networkSymbol": "BSC",
    "callBackUrl":"www.callback.com",
    "redirectUrl":"www.redirect.com"
}

# Convert request body to JSON
raw = json.dumps(request_body, separators=(',', ':'), ensure_ascii=False)

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Generate signature
signature = create_signature(api_secret, raw)

# Define headers
headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the request
response = requests.post("https://api.tylt.money/transactions/merchant/createPayoutRequest", headers=headers, data=raw)

# Print the response
print("Success:", response.json())

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": {
        "orderId": "1deecabb-79b8-11ef-8277-02d8461243e9",
        "merchantOrderId": "9ghehjbb-59o8-11ff-0292-15y8461288h3",
        "settledCurrency": "USDT",
        "settledAmountRequested": 0.1,
        "settledAmountDebited": 0,
        "settledAmountSent": 0,
        "commission": 0,
        "network": "BSC",
        "toAddress": "0xh22kbbq3hbth4bjwh433adgda",
        "status": "Pending",
        "insufficientBalance": 0,
        "paymentURL": "",
        "callBackURL": "",
        "transactions": [],
        "createdAt": "2024-09-23T14:28:35Z",
        "expiresAt": "2024-09-23T14:28:35Z",
        "updatedAt": "2024-09-23T14:28:35Z",
        "isFinal": 0,
        "isDebited": 0,
        "customerName": "",
        "comments": "",
        "payeeDetails": {
            "entityType": "individual",
            "firstName": "Jon",
            "lastName": "Doe",
            "dateOfBirth": "1999-09-23",
            "placeOfBirth": "Germany"
             },
       "payeeDetails": {
            "entityType": "company",
            "fullName": "ACME Corp",
            "registrationNumber": "HRB123456",
            "address": {
                  "country": "DEU",
                  "town": "Berlin",
                  "postCode": "10115",
                  "street": "Chauseestr.",
                  "buildingNumber": "60"
            }
        },
    "msg": "Withdrawal request accepted"
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                   |
| ------------------------ | -------- | --------------------------------------------------------------------------------- |
| `orderId`                | String   | The order ID generated by TL Pay, used as a global identifier.                    |
| `merchantOrderId`        | String   | The merchant's local order ID for reference (optional).                           |
| `settledCurrency`        | String   | The cryptocurrency or token used for payout.                                      |
| `settledAmountRequested` | Number   | The amount of cryptocurrency or token requested to be paid out.                   |
| `settledAmountDebited`   | Number   | The amount of cryptocurrency debited from your merchant balance.                  |
| `settledAmountSent`      | Number   | The total amount of cryptocurrency sent to the recipient.                         |
| `commission`             | Number   | The commission deducted from the payout transaction.                              |
| `network`                | String   | The blockchain network over which the payout is made (e.g., "BSC").               |
| `toAddress`              | String   | The recipient's wallet address where the payout will be sent.                     |
| `status`                 | String   | The status of the payout (e.g., "Pending", "Completed", "Failed").                |
| `insufficientBalance`    | Number   | Indicates if there is insufficient balance for the transaction (1 = Yes, 0 = No). |
| `paymentURL`             | String   | The URL where the customer can make the payment (if applicable).                  |
| `callBackURL`            | String   | The callback URL specified by the merchant (optional).                            |
| `transactions`           | Array    | Details of any individual transactions linked to this payout (if applicable).     |
| `createdAt`              | String   | The timestamp when the payout request was created.                                |
| `expiresAt`              | String   | The timestamp when the payout request will expire.                                |
| `updatedAt`              | String   | The timestamp when the payout request was last updated.                           |
| `isFinal`                | Number   | Indicates if the transaction is final (`1` for completed, `0` for pending).       |
| `isDebited`              | Number   | Indicates if the payout amount has been debited from your merchant account.       |
| `customerName`           | String   | The name of the customer associated with the transaction (optional).              |
| `comments`               | String   | Any comments or notes provided by the merchant (optional).                        |
| {% endtab %}             |          |                                                                                   |
| {% endtabs %}            |          |                                                                                   |


# Get Pay-Out Transaction History

This endpoint allows you to retrieve the history of all Pay-In transactions associated with your merchant account. The results are paginated, allowing you to specify the number of rows and the page number.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?rows={numberRows}20&page={pagenumber}`

#### Endpoint Example

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayinTransactionHistory?rows=20&page=1`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create signature for the GET request
const params = {rows:20,page:1};
const queryParams = new URLSearchParams(params).toString();
const signature = crypto.createHmac('sha256', apiSecret)
  .update( JSON.stringify(params) )
  .digest('hex');

const config = {
  method: 'get',
  url: `https://api.tylt.money/transactions/merchant/getPayoutTransactionHistory?${queryParams}`,
  headers: {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
  }
};

axios(config)
  .then(response => {
    console.log(response.data);
  })
  .catch(error => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Create signature for the GET request
params = {"rows":"20","page":"1"}
query_params = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)

signature = hmac.new(api_secret.encode(), body_string.encode(), hashlib.sha256).hexdigest()

url = f"https://api.tylt.money/transactions/merchant/getPayoutTransactionHistory?{query_params}"

headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

response = requests.get(url, headers=headers)

if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const fetch = require('node-fetch');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create signature for the GET request
const params = {rows:20,page:1};
const queryParams = new URLSearchParams(params).toString();

const signature = crypto.createHmac('sha256', apiSecret)
  .update( JSON.stringify(params) )
  .digest('hex');

const url = `https://api.tylt.money/transactions/merchant/getPayoutTransactionHistory?${queryParams}`;

const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

fetch(url, {
  method: 'GET',
  headers: headers,
})
  .then(response => response.json())
  .then(data => console.log(data))
  .catch(error => console.error('Error:', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "orderId": "74ea3ace-7740-11ef-8277-02d8461243e9",
            "merchantOrderId": "74ea3ace-7740-11ef-8277-02d8461243e9",
            "settledCurrency": "USDT",
            "settledAmountRequested": 0.1,
            "settledAmountDebited": 0,
            "settledAmountSent": 0,
            "commission": 0,
            "network": "BSC",
            "toAddress": "0xh22kbbq3hbth4bjwh433adgda",
            "status": "Pending",
            "insufficientBalance": 0,
            "paymentURL": "",
            "callBackURL": "",
            "transactions": [],
            "createdAt": "2024-09-20T11:06:59Z",
            "expiresAt": "2024-09-20T11:06:59Z",
            "updatedAt": "2024-09-20T11:06:59Z",
            "isFinal": 0,
            "isDebited": 0,
            "customerName": "",
            "comments": ""
        },
        {
            "orderId": "cc2b2c95-7699-11ef-8277-02d8461243e9",
            "merchantOrderId": "cc2b2c95-7699-11ef-8277-02d8461243e9",
            "settledCurrency": "USDT",
            "settledAmountRequested": 1,
            "settledAmountDebited": 0,
            "settledAmountSent": 0,
            "commission": 0,
            "network": "TPNK",
            "toAddress": "2828a803-72a7-11ef-8277-02d8461243e9",
            "status": "Completed",
            "insufficientBalance": 0,
            "paymentURL": "",
            "callBackURL": "",
            "transactions": [
                {
                    "amount": 1,
                    "createdAt": "2024-09-19 15:13:59.000000",
                    "updatedAt": "2024-09-19 15:13:59.000000",
                    "fromAddress": "2828a803-72a7-11ef-8277-02d8461243e9",
                    "transactionHash": "cc2fe789-7699-11ef-8277-02d8461243e9",
                    "confirmationStatus": 1
                }
            ],
            "createdAt": "2024-09-19T15:13:59Z",
            "expiresAt": "2024-09-19T15:13:59Z",
            "updatedAt": "2024-09-19T15:13:59Z",
            "isFinal": 1,
            "isDebited": 1,
            "customerName": "",
            "comments": ""
        },            
        {
            "orderId": "3249f4a4-7693-11ef-8277-02d8461243e9",
            "merchantOrderId": "3249f4a4-7693-11ef-8277-02d8461243e9",
            "settledCurrency": "USDT",
            "settledAmountRequested": 1,
            "settledAmountDebited": 1,
            "settledAmountSent": 1,
            "commission": 0,
            "network": "BSC",
            "toAddress": "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
            "status": "Completed",
            "insufficientBalance": 0,
            "paymentURL": "",
            "callBackURL": "",
            "transactions": [
                {
                    "amount": 1,
                    "createdAt": "2024-09-19 14:26:53.000000",
                    "updatedAt": "2024-09-19 14:27:42.000000",
                    "fromAddress": "0x1B3ec402Df254a66B97DE199541295AF2e0F5baA",
                    "transactionHash": "0xf7b0c37e5113311ab9f87f0df81c4e2b77cac04fd767862e23de1b63bd06a140",
                    "confirmationStatus": 1
                }
            ],
            "createdAt": "2024-09-19T14:26:44Z",
            "expiresAt": "2024-09-19T14:26:44Z",
            "updatedAt": "2024-09-19T14:27:42Z",
            "isFinal": 1,
            "isDebited": 1,
            "customerName": "",
            "comments": ""
        },
        {
            "orderId": "85831093-7692-11ef-8277-02d8461243e9",
            "merchantOrderId": "85831093-7692-11ef-8277-02d8461243e9",
            "settledCurrency": "USDT",
            "settledAmountRequested": 2,
            "settledAmountDebited": 2,
            "settledAmountSent": 2,
            "commission": 0,
            "network": "BSC",
            "toAddress": "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
            "status": "Completed",
            "insufficientBalance": 0,
            "paymentURL": "",
            "callBackURL": "",
            "transactions": [
                {
                    "amount": 2,
                    "createdAt": "2024-09-19 14:24:47.000000",
                    "updatedAt": "2024-09-19 14:25:36.000000",
                    "fromAddress": "0x1B3ec402Df254a66B97DE199541295AF2e0F5baA",
                    "transactionHash": "0xb8a583a821234484a6811215d1ecc8b16e5bf35bc01699f8676d646db3b74a5b",
                    "confirmationStatus": 1
                }
            ],
            "createdAt": "2024-09-19T14:21:54Z",
            "expiresAt": "2024-09-19T14:21:54Z",
            "updatedAt": "2024-09-19T14:25:36Z",
            "isFinal": 1,
            "isDebited": 1,
            "customerName": "",
            "comments": ""
        }
    ],
    "errorCode": 0,
    "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                   |
| ------------------------ | -------- | --------------------------------------------------------------------------------- |
| `orderId`                | String   | The order ID generated by TL Pay, used as a global identifier.                    |
| `merchantOrderId`        | String   | The merchant's local order ID for reference (optional).                           |
| `settledCurrency`        | String   | The cryptocurrency or token used for payout.                                      |
| `settledAmountRequested` | Number   | The amount of cryptocurrency or token requested to be paid out.                   |
| `settledAmountDebited`   | Number   | The amount of cryptocurrency debited from your merchant balance.                  |
| `settledAmountSent`      | Number   | The total amount of cryptocurrency sent to the recipient.                         |
| `commission`             | Number   | The commission deducted from the payout transaction.                              |
| `network`                | String   | The blockchain network over which the payout is made (e.g., "BSC").               |
| `toAddress`              | String   | The recipient's wallet address where the payout will be sent.                     |
| `status`                 | String   | The status of the payout (e.g., "Pending", "Completed", "Failed").                |
| `insufficientBalance`    | Number   | Indicates if there is insufficient balance for the transaction (1 = Yes, 0 = No). |
| `paymentURL`             | String   | The URL where the customer can make the payment (if applicable).                  |
| `callBackURL`            | String   | The callback URL specified by the merchant (optional).                            |
| `transactions`           | Array    | Details of any individual transactions linked to this payout (if applicable).     |
| `createdAt`              | String   | The timestamp when the payout request was created.                                |
| `expiresAt`              | String   | The timestamp when the payout request will expire.                                |
| `updatedAt`              | String   | The timestamp when the payout request was last updated.                           |
| `isFinal`                | Number   | Indicates if the transaction is final (`1` for completed, `0` for pending).       |
| `isDebited`              | Number   | Indicates if the payout amount has been debited from your merchant account.       |
| `customerName`           | String   | The name of the customer associated with the transaction (optional).              |
| `comments`               | String   | Any comments or notes provided by the merchant (optional).                        |
| {% endtab %}             |          |                                                                                   |
| {% endtabs %}            |          |                                                                                   |


# Get Pay-Out Transaction Information

This endpoint allows you to retrieve detailed information about a specific Pay-Out transaction. The `orderId` is required, and it corresponds to the unique identifier generated by Tylt for the transaction.

#### Endpoint

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayoutTransactionInformation?orderId={orderId}`

#### Example Request

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getPayoutTransactionInformation?orderId=a49579dd-7711-11ef-8277-02d8461243e9`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayoutTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const config = {
  method: 'get',
  url: url,
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  }
};

axios.request(config)
  .then((response) => {
    console.log(JSON.stringify(response.data));
  })
  .catch((error) => {
    console.error(error);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hashlib
import hmac

url = "https://api.tylt.money/transactions/merchant/getPayoutTransactionInformation"

params = {
    'orderId': 'a49579dd-7711-11ef-8277-02d8461243e9'
}

api_key = 'your-api-key'
secret_key = 'your-secret-key'

query_string = '&'.join([f"{key}={value}" for key, value in params.items()])
body_string = json.dumps(params, separators=(',', ':'), ensure_ascii=False)

signature = hmac.new(secret_key.encode(), body_string.encode(), hashlib.sha256).hexdigest()

headers = {
    'X-TLP-APIKEY': api_key,
    'X-TLP-SIGNATURE': signature
}

response = requests.get(url, headers=headers, params=params)
print(response.text)

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

const params = {
  orderId: 'a49579dd-7711-11ef-8277-02d8461243e9'
};

const queryString = new URLSearchParams(params).toString();
const url = `https://api.tylt.money/transactions/merchant/getPayoutTransactionInformation?${queryString}`;

const apiKey = 'your-api-key';
const secretKey = 'your-secret-key';

const signaturePayload = JSON.stringify(params);
const signature = crypto.createHmac('sha256', secretKey)
  .update(signaturePayload)
  .digest('hex');

const requestOptions = {
  method: 'GET',
  headers: {
    'X-TLP-APIKEY': apiKey,
    'X-TLP-SIGNATURE': signature
  },
  redirect: 'follow'
};

fetch(url, requestOptions)
  .then(response => response.text())
  .then(result => console.log(result))
  .catch(error => console.error('error', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": {
        "orderId": "85831093-7692-11ef-8277-02d8461243e9",
        "merchantOrderId": "85831093-7692-11ef-8277-02d8461243e9",
        "settledCurrency": "USDT",
        "settledAmountRequested": 2,
        "settledAmountDebited": 2,
        "settledAmountSent": 2,
        "commission": 0,
        "network": "BSC",
        "toAddress": "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
        "status": "Completed",
        "insufficientBalance": 0,
        "paymentURL": "",
        "callBackURL": "",
        "transactions": [
            {
                "amount": 2,
                "createdAt": "2024-09-19 14:24:47.000000",
                "updatedAt": "2024-09-19 14:25:36.000000",
                "fromAddress": "0x1B3ec402Df254a66B97DE199541295AF2e0F5baA",
                "transactionHash": "0xb8a583a821234484a6811215d1ecc8b16e5bf35bc01699f8676d646db3b74a5b",
                "confirmationStatus": 1
            }
        ],
        "createdAt": "2024-09-19T14:21:54Z",
        "expiresAt": "2024-09-19T14:21:54Z",
        "updatedAt": "2024-09-19T14:25:36Z",
        "isFinal": 1,
        "isDebited": 1,
        "customerName": "",
        "comments": ""
    }
}
```

{% endtab %}

{% tab title="400" %}

<pre class="language-json"><code class="lang-json"><strong>{
</strong>    "msg": "Not a payout order id",
    "data": {}
}
</code></pre>

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                   |
| ------------------------ | -------- | --------------------------------------------------------------------------------- |
| `orderId`                | String   | The order ID generated by TL Pay, used as a global identifier.                    |
| `merchantOrderId`        | String   | The merchant's local order ID for reference (optional).                           |
| `settledCurrency`        | String   | The cryptocurrency or token used for payout.                                      |
| `settledAmountRequested` | Number   | The amount of cryptocurrency or token requested to be paid out.                   |
| `settledAmountDebited`   | Number   | The amount of cryptocurrency debited from your merchant balance.                  |
| `settledAmountSent`      | Number   | The total amount of cryptocurrency sent to the recipient.                         |
| `commission`             | Number   | The commission deducted from the payout transaction.                              |
| `network`                | String   | The blockchain network over which the payout is made (e.g., "BSC").               |
| `toAddress`              | String   | The recipient's wallet address where the payout will be sent.                     |
| `status`                 | String   | The status of the payout (e.g., "Pending", "Completed", "Failed").                |
| `insufficientBalance`    | Number   | Indicates if there is insufficient balance for the transaction (1 = Yes, 0 = No). |
| `paymentURL`             | String   | The URL where the customer can make the payment (if applicable).                  |
| `callBackURL`            | String   | The callback URL specified by the merchant (optional).                            |
| `transactions`           | Array    | Details of any individual transactions linked to this payout (if applicable).     |
| `createdAt`              | String   | The timestamp when the payout request was created.                                |
| `expiresAt`              | String   | The timestamp when the payout request will expire.                                |
| `updatedAt`              | String   | The timestamp when the payout request was last updated.                           |
| `isFinal`                | Number   | Indicates if the transaction is final (`1` for completed, `0` for pending).       |
| `isDebited`              | Number   | Indicates if the payout amount has been debited from your merchant account.       |
| `customerName`           | String   | The name of the customer associated with the transaction (optional).              |
| `comments`               | String   | Any comments or notes provided by the merchant (optional).                        |
| {% endtab %}             |          |                                                                                   |
| {% endtabs %}            |          |                                                                                   |


# Internal Transfer

### Overview

Merchants on Tylt may have multiple wallets provisioned across different services and rails, such as:

* CPG Wallet (Crypto Payment Gateway)
* CrossRamp Wallets (e.g., BRL, INR, EUR flows)
* Network-specific wallets (TRON, ETH, BSC, etc.)

The Internal Transfer API enables merchants to move funds between their own wallets within the Tylt ecosystem.

{% hint style="info" %}
This is an **off-chain ledger transfer** and does not incur blockchain fees.
{% endhint %}

***

### Use Cases

* Move funds from CPG wallet → Payout wallet
* Rebalance liquidity across networks (e.g., TRON → ETH)
* Allocate funds for merchant-specific operations
* Consolidate balances into a primary settlement wallet


# Create an Internal Transfer Request

This endpoint allows a merchant to transfer funds between two wallets owned by the same merchant within the Tylt ecosystem.

Internal transfers are processed as ledger movements within Tylt and do not involve any on-chain blockchain transaction.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/transactions/merchant/transferMerchantBalance`

{% tabs %}
{% tab title="First Tab" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="204"></th><th width="121"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>fromUUID</code></td><td><code>string</code></td><td>Unique identifier of the source wallet (debited wallet)</td></tr><tr><td><code>toUUID</code></td><td><code>string</code></td><td>Unique identifier of the destination wallet (credited wallet)</td></tr><tr><td><code>settledAmount</code></td><td><code>string</code></td><td>Amount to be transferred between wallets</td></tr><tr><td><code>settledCurrency</code></td><td><code>string</code></td><td>Currency of transfer (e.g., USDT, USDC)</td></tr><tr><td><code>comments</code></td><td><code>string</code></td><td>Optional remarks or internal reference for reconciliation</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="JavaScript (Axios)" %}

```javascript
import axios from "axios";
import crypto from "crypto";

const apiKey = "your-api-key";
const apiSecret = "your-api-secret";

function createSignature(apiSecret, bodyString) {
    return crypto
        .createHmac("sha256", apiSecret)
        .update(bodyString)
        .digest("hex");
}

const transferMerchantBalanceData = {
    fromUUID: "ybht35h-2a33-11f0-b2d9-42010a28011c",
    toUUID: "bkhe4tt-33cc-11f0-b2d9-42010a28011c",
    settledAmount: 2,
    settledCurrency: "USDT",
    comments: "",
};

try {
    const signature = createSignature(
        apiSecret,
        JSON.stringify(transferMerchantBalanceData),
    );
    console.log("Generated signature: ", signature);

    const apiDomain = "https://api.tylt.money/transactions/merchant";
    const res1 = await axios.request({
        method: "POST",
        url: `${apiDomain}/transferMerchantBalance`,
        headers: {
            "Content-Type": "application/json",
            "X-TLP-APIKEY": apiKey,
            "X-TLP-SIGNATURE": signature,
        },
        data: transferMerchantBalanceData,
    });

    console.log(`Response: ${JSON.stringify(res1.data)}`);
} catch (error) {
    console.log(error);
}
```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "data": {
    "transactionOrderId": "hjbhj-546f-3ff3-cw4t4f3"
  },
  "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th width="236"></th><th width="96"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>orderId</td><td>string</td><td>The orderId associated with a successful internal transaction.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Get Merchant Wallet Details

This endpoint allows a merchant to retrieve a list of active and operable wallet provisioned under the Merchants Tylt account.

Merchant wallets may be mapped to different products, services, currencies, or settlement rails. This endpoint returns wallet-level information such as wallet identifier, wallet type, currency, status, and other associated metadata.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getMerchantDetails`

**Endpoint  Example**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getMerchantDetails`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update( JSON.stringify({}) )
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
axios.get(`https://api.tylt.money/transactions/merchant/getMerchantDetails`, { headers })
  .then(response => {
    console.log("Response:", response.data);
  })
  .catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
  "data": [
    {
      "merchantUUID": "byu536-72a7-11ef-8277-02d8461243e9",
      "merchantName": "Merchant 1",
      "accountCategory": "UPI Payin"
    },
    {
      "merchantUUID": "khb5h4-7676-11ef-8277-02d8461243e9",
      "merchantName": "Merchant 2",
      "accountCategory": "PIX Daily Payin"
    }
  ],
  "errorCode": 0,
  "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

| Field Name        | Type   | Description                                                                                                                                                                                          |
| ----------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `merchantUUID`    | String | Unique identifier of the merchant wallet. This value must be used as the reference (`fromWalletId` / `toWalletId`) when initiating internal transfers via the `POST /wallets/internal-transfer` API. |
| `merchantName`    | String | Human-readable name assigned to the wallet. This is typically used for display purposes in dashboards, reports, and reconciliation workflows.                                                        |
| `accountCategory` | Number | Describes the service or product context under which the wallet operates. This helps identify the functional purpose of the wallet within the Tylt ecosystem.                                        |
| {% endtab %}      |        |                                                                                                                                                                                                      |
| {% endtabs %}     |        |                                                                                                                                                                                                      |


# Supporting APIs


# Get Supported Crypto Currencies List

This endpoint allows you to retrieve a list of supported Curypto Currencies. This is useful in the following context:

* **Pay-In Requests**: When creating a Pay-In request, the currency used must be from the Supported Currencies List. For instance, if you’re selling an item priced at BTC 100, but your customer wishes to pay in USDT, or if the item is priced in USDT and the payment is made in USDT, both the `fromCurrency` and `toCurrency` fields must reflect valid cryptocurrencies from this list.
* **Pay-Out Requests**: Similarly, when processing a Pay-Out request, you can select the cryptocurrency being disbursed. This must also be a currency listed in the Supported Crypto Currencies List to ensure compliance and proper transaction execution.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getSupportedCryptoCurrenciesList`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create HMAC SHA-256 signature (no params for this request)
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update('{}') // No parameters to sign
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
axios.get("https://api.tylt.money/transactions/merchant/getSupportedCryptoCurrenciesList", { headers })
  .then(response => console.log(response.data))
  .catch(error => console.error(error));

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Create HMAC SHA-256 signature (no params for this request)
signature = hmac.new(api_secret.encode(), b'{}', hashlib.sha256).hexdigest()

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the GET request
response = requests.get("https://api.tylt.money/transactions/merchant/getSupportedCryptoCurrenciesList", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const fetch = require('node-fetch');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create HMAC SHA-256 signature (no params for this request)
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update('{}') // No parameters to sign
  .digest('hex');

// Define headers
const myHeaders = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
fetch("https://api.tylt.money/transactions/merchant/getSupportedCryptoCurrenciesList", { headers: myHeaders })
  .then(response => response.json())
  .then(result => console.log(result))
  .catch(error => console.error(error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "currencyName": "Dai",
            "currencySymbol": "DAI",
            "networks": [
                {
                    "standard": "BEP20",
                    "canDeposit": 1,
                    "canWithdraw": 1,
                    "networkFees": 0,
                    "networkName": "Binance Smart Chain",
                    "networkSymbol": "BSC",
                    "maximumDeposit": 100,
                    "minimumDeposit": 1,
                    "contractAddress": "0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3",
                    "maximumWithdrawal": 100,
                    "minimumWithdrawal": 0
                }
            ]
        },
        {
            "currencyName": "Tether",
            "currencySymbol": "USDT",
            "networks": [
                {
                    "standard": "BEP20",
                    "canDeposit": 1,
                    "canWithdraw": 1,
                    "networkFees": 0,
                    "networkName": "Binance Smart Chain",
                    "networkSymbol": "BSC",
                    "maximumDeposit": 100,
                    "minimumDeposit": 1,
                    "contractAddress": "0x55d398326f99059fF775485246999027B3197955",
                    "maximumWithdrawal": 100,
                    "minimumWithdrawal": 0
                },
                {
                    "standard": "ERC20",
                    "canDeposit": 1,
                    "canWithdraw": 1,
                    "networkFees": 0,
                    "networkName": "Ethereum",
                    "networkSymbol": "ETH",
                    "maximumDeposit": 100,
                    "minimumDeposit": 1,
                    "contractAddress": "0xdAC17F958D2ee523a2206206994597C13D831ec7",
                    "maximumWithdrawal": 100,
                    "minimumWithdrawal": 0
                }
            ]
        }
    ],
    "errorCode": 0,
    "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th></th><th width="101"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>currencyName</code></td><td>string</td><td>The name of the cryptocurrency (e.g., Dai, Tether).</td></tr><tr><td><code>currencySymbol</code></td><td>string</td><td>The symbol representing the cryptocurrency (e.g., DAI, USDT). <mark style="color:purple;">Use this as input in other API requests.</mark></td></tr><tr><td><code>networks</code></td><td>array</td><td>A list of networks where the cryptocurrency is supported.</td></tr><tr><td><code>networks[].standard</code></td><td>string</td><td>The token standard for the network (e.g., BEP20, ERC20).</td></tr><tr><td><code>networks[].canDeposit</code></td><td>number</td><td>Indicates if deposits are allowed on this network (1: Yes, 0: No).</td></tr><tr><td><code>networks[].canWithdraw</code></td><td>number</td><td>Indicates if withdrawals are allowed on this network (1: Yes, 0: No).</td></tr><tr><td><code>networks[].networkFees</code></td><td>number</td><td>The network fees for transactions on this network.</td></tr><tr><td><code>networks[].networkName</code></td><td>string</td><td>The name of the network (e.g., Binance Smart Chain, Ethereum).</td></tr><tr><td><code>networks[].networkSymbol</code></td><td>string</td><td>The symbol representing the network (e.g., BSC, ETH). <mark style="color:purple;">Use this as an input in other API requests.</mark></td></tr><tr><td><code>networks[].maximumDeposit</code></td><td>number</td><td>The maximum deposit amount allowed on this network.</td></tr><tr><td><code>networks[].minimumDeposit</code></td><td>number</td><td>The minimum deposit amount allowed on this network.</td></tr><tr><td><code>networks[].contractAddress</code></td><td>string</td><td>The contract address for the token on this network.</td></tr><tr><td><code>networks[].maximumWithdrawal</code></td><td>number</td><td>The maximum withdrawal amount allowed on this network.</td></tr><tr><td><code>networks[].minimumWithdrawal</code></td><td>number</td><td>The minimum withdrawal amount allowed on this network.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Get Supported Fiat Currencies

This endpoint allows you to retrieve a list of supported Fiat currencies, which is essential when creating a Pay-In request where the `fromCurrency` is denominated in Fiat. For example, if you’re selling a pair of shoes for USD 100 and your customer wishes to pay in Bitcoin or USDT, you would specify `fromCurrency` as USD and `toCurrency` as BTC or USDT. This endpoint provides a comprehensive list of supported Fiat currencies that can be utilied in the `fromCurrency` field.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getSupportedFiatCurrenciesList`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create query parameters (if any)
const queryParams = '{}';

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(queryParams)
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
axios.get("https://api.tylt.money/transactions/merchant/getSupportedFiatCurrenciesList", { headers })
  .then(response => {
    console.log("Response:", response.data);
  })
  .catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Create query parameters (if any)
query_params = {}

# Create the HMAC SHA-256 signature
signature = hmac.new(api_secret.encode(), b'', hashlib.sha256).hexdigest()

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the GET request
response = requests.get("https://api.tylt.money/transactions/merchant/getSupportedFiatCurrenciesList", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const fetch = require('node-fetch');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create query parameters (if any)
const queryParams = new URLSearchParams();

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(queryParams.toString())
  .digest('hex');

const myHeaders = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

const requestOptions = {
  method: 'GET',
  headers: myHeaders,
  redirect: 'follow'
};

fetch("https://api.tylt.money/transactions/merchant/getSupportedFiatCurrenciesList", requestOptions)
  .then(response => response.json())
  .then(result => console.log(result))
  .catch(error => console.error('Error:', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "currencyName": "United Arab Emirates dirham",
            "currencySymbol": "AED"
        },
        {
            "currencyName": "Afghan afghani",
            "currencySymbol": "AFN"
        },
        {
            "currencyName": "Albanian lek",
            "currencySymbol": "ALL"
        },
        {
            "currencyName": "Armenian dram",
            "currencySymbol": "AMD"
        },
        {
            "currencyName": "AREG",
            "currencySymbol": "ARE"
        },
        {
            "currencyName": "Argentine peso",
            "currencySymbol": "ARS"
        },
        {
            "currencyName": "Australian dollar",
            "currencySymbol": "AUD"
        },
        {
            "currencyName": "Australian nugget",
            "currencySymbol": "AUN"
        },
        {
            "currencyName": "Aruban florin",
            "currencySymbol": "AWG"
        },
        {
            "currencyName": "Bosnia and Herzegovina convertible mark",
            "currencySymbol": "BAM"
        },
        {
            "currencyName": "Barbados dollar",
            "currencySymbol": "BBD"
        },
        {
            "currencyName": "Bangladeshi taka",
            "currencySymbol": "BDT"
        },
        {
            "currencyName": "Bulgarian lev",
            "currencySymbol": "BGN"
        },
        {
            "currencyName": "Bahraini dinar",
            "currencySymbol": "BHD"
        },
        {
            "currencyName": "Burundian franc",
            "currencySymbol": "BIF"
        },
        {
            "currencyName": "Bermudian dollar",
            "currencySymbol": "BMD"
        },
        {
            "currencyName": "Brunei dollar",
            "currencySymbol": "BND"
        },
        {
            "currencyName": "Boliviano",
            "currencySymbol": "BOB"
        },
        {
            "currencyName": "Britannia",
            "currencySymbol": "BRI"
        },
        {
            "currencyName": "Brazilian real",
            "currencySymbol": "BRL"
        },
        {
            "currencyName": "Bahamian dollar",
            "currencySymbol": "BSD"
        },
        {
            "currencyName": "Bhutanese ngultrum",
            "currencySymbol": "BTN"
        },
        {
            "currencyName": "Botswana pula",
            "currencySymbol": "BWP"
        },
        {
            "currencyName": "Belarusian ruble",
            "currencySymbol": "BYR"
        },
        {
            "currencyName": "Belize dollar",
            "currencySymbol": "BZD"
        },
        {
            "currencyName": "Canadian dollar",
            "currencySymbol": "CAD"
        },
        {
            "currencyName": "Congolese franc",
            "currencySymbol": "CDF"
        },
        {
            "currencyName": "Swiss franc",
            "currencySymbol": "CHF"
        },
        {
            "currencyName": "Chilean peso",
            "currencySymbol": "CLP"
        },
        {
            "currencyName": "Chinese yuan",
            "currencySymbol": "CNH"
        },
        {
            "currencyName": "Chinese yuan",
            "currencySymbol": "CNY"
        },
        {
            "currencyName": "Colombian peso",
            "currencySymbol": "COP"
        },
        {
            "currencyName": "Costa Rican colon",
            "currencySymbol": "CRC"
        },
        {
            "currencyName": "Cuban peso",
            "currencySymbol": "CUP"
        },
        {
            "currencyName": "Cape Verde escudo",
            "currencySymbol": "CVE"
        },
        {
            "currencyName": "Cypriot pound",
            "currencySymbol": "CYP"
        },
        {
            "currencyName": "Czech koruna",
            "currencySymbol": "CZK"
        },
        {
            "currencyName": "Djiboutian franc",
            "currencySymbol": "DJF"
        },
        {
            "currencyName": "Danish krone",
            "currencySymbol": "DKK"
        },
        {
            "currencyName": "Double Eagle",
            "currencySymbol": "DOE"
        },
        {
            "currencyName": "Dominican peso",
            "currencySymbol": "DOP"
        },
        {
            "currencyName": "Algerian dinar",
            "currencySymbol": "DZD"
        },
        {
            "currencyName": "Egyptian pound",
            "currencySymbol": "EGP"
        },
        {
            "currencyName": "Ethiopian birr",
            "currencySymbol": "ETB"
        },
        {
            "currencyName": "Euro",
            "currencySymbol": "EUR"
        },
        {
            "currencyName": "Fiji dollar",
            "currencySymbol": "FJD"
        },
        {
            "currencyName": "French Napoleon",
            "currencySymbol": "FRN"
        },
        {
            "currencyName": "Pound sterling",
            "currencySymbol": "GBP"
        },
        {
            "currencyName": "Ghanaian cedi",
            "currencySymbol": "GHS"
        },
        {
            "currencyName": "Gambian dalasi",
            "currencySymbol": "GMD"
        },
        {
            "currencyName": "Guinean franc",
            "currencySymbol": "GNF"
        },
        {
            "currencyName": "Guatemalan quetzal",
            "currencySymbol": "GTQ"
        },
        {
            "currencyName": "Guyanese dollar",
            "currencySymbol": "GYD"
        },
        {
            "currencyName": "Hong Kong dollar",
            "currencySymbol": "HKD"
        },
        {
            "currencyName": "Honduran lempira",
            "currencySymbol": "HNL"
        },
        {
            "currencyName": "Croatian kuna",
            "currencySymbol": "HRK"
        },
        {
            "currencyName": "Haitian gourde",
            "currencySymbol": "HTG"
        },
        {
            "currencyName": "Hungarian forint",
            "currencySymbol": "HUF"
        },
        {
            "currencyName": "Indonesian rupiah",
            "currencySymbol": "IDR"
        },
        {
            "currencyName": "Israeli new shekel",
            "currencySymbol": "ILS"
        },
        {
            "currencyName": "Indian rupee",
            "currencySymbol": "INR"
        },
        {
            "currencyName": "Iraqi dinar",
            "currencySymbol": "IQD"
        },
        {
            "currencyName": "Icelandic króna",
            "currencySymbol": "ISK"
        },
        {
            "currencyName": "Jamaican dollar",
            "currencySymbol": "JMD"
        },
        {
            "currencyName": "Jordanian dinar",
            "currencySymbol": "JOD"
        },
        {
            "currencyName": "Japanese yen",
            "currencySymbol": "JPY"
        },
        {
            "currencyName": "Kenyan shilling",
            "currencySymbol": "KES"
        },
        {
            "currencyName": "Cambodian riel",
            "currencySymbol": "KHR"
        },
        {
            "currencyName": "Comoro franc",
            "currencySymbol": "KMF"
        },
        {
            "currencyName": "South African Krugerrand",
            "currencySymbol": "KRU"
        },
        {
            "currencyName": "South Korean won",
            "currencySymbol": "KRW"
        },
        {
            "currencyName": "Kuwaiti dinar",
            "currencySymbol": "KWD"
        },
        {
            "currencyName": "Cayman Islands dollar",
            "currencySymbol": "KYD"
        },
        {
            "currencyName": "Kazakhstani tenge",
            "currencySymbol": "KZT"
        },
        {
            "currencyName": "Lao kip",
            "currencySymbol": "LAK"
        },
        {
            "currencyName": "Lebanese pound",
            "currencySymbol": "LBP"
        },
        {
            "currencyName": "Sri Lankan rupee",
            "currencySymbol": "LKR"
        },
        {
            "currencyName": "Liberian dollar",
            "currencySymbol": "LRD"
        },
        {
            "currencyName": "Lesotho loti",
            "currencySymbol": "LSL"
        },
        {
            "currencyName": "Lithuanian litas",
            "currencySymbol": "LTL"
        },
        {
            "currencyName": "Libyan dinar",
            "currencySymbol": "LYD"
        },
        {
            "currencyName": "Mexican 50 peso",
            "currencySymbol": "M5P"
        },
        {
            "currencyName": "Moroccan dirham",
            "currencySymbol": "MAD"
        },
        {
            "currencyName": "Maple Leaf",
            "currencySymbol": "MAL"
        },
        {
            "currencyName": "Moldovan leu",
            "currencySymbol": "MDL"
        },
        {
            "currencyName": "Malagasy ariary",
            "currencySymbol": "MGA"
        },
        {
            "currencyName": "Macedonian denar",
            "currencySymbol": "MKD"
        },
        {
            "currencyName": "Myanma kyat",
            "currencySymbol": "MMK"
        },
        {
            "currencyName": "Macanese pataca",
            "currencySymbol": "MOP"
        },
        {
            "currencyName": "Mauritanian ouguiya",
            "currencySymbol": "MRO"
        },
        {
            "currencyName": "Mauritian rupee",
            "currencySymbol": "MUR"
        },
        {
            "currencyName": "Maldivian rufiyaa",
            "currencySymbol": "MVR"
        },
        {
            "currencyName": "Malawian kwacha",
            "currencySymbol": "MWK"
        },
        {
            "currencyName": "Mexican peso",
            "currencySymbol": "MXN"
        },
        {
            "currencyName": "Malaysian ringgit",
            "currencySymbol": "MYR"
        },
        {
            "currencyName": "Mozambican metical",
            "currencySymbol": "MZN"
        },
        {
            "currencyName": "Namibian dollar",
            "currencySymbol": "NAD"
        },
        {
            "currencyName": "Isle Of Man noble",
            "currencySymbol": "NBL"
        },
        {
            "currencyName": "Nigerian naira",
            "currencySymbol": "NGN"
        },
        {
            "currencyName": "Nicaraguan córdoba",
            "currencySymbol": "NIO"
        },
        {
            "currencyName": "Norwegian krone",
            "currencySymbol": "NOK"
        },
        {
            "currencyName": "Nepalese rupee",
            "currencySymbol": "NPR"
        },
        {
            "currencyName": "New Sovereign",
            "currencySymbol": "NSO"
        },
        {
            "currencyName": "New Zealand dollar",
            "currencySymbol": "NZD"
        },
        {
            "currencyName": "Omani rial",
            "currencySymbol": "OMR"
        },
        {
            "currencyName": "Old Sovereign",
            "currencySymbol": "OSO"
        },
        {
            "currencyName": "Panamanian balboa",
            "currencySymbol": "PAB"
        },
        {
            "currencyName": "Peruvian nuevo sol",
            "currencySymbol": "PEN"
        },
        {
            "currencyName": "Papua New Guinean kina",
            "currencySymbol": "PGK"
        },
        {
            "currencyName": "Philippine peso",
            "currencySymbol": "PHP"
        },
        {
            "currencyName": "Pakistani rupee",
            "currencySymbol": "PKR"
        },
        {
            "currencyName": "Polish złoty",
            "currencySymbol": "PLN"
        },
        {
            "currencyName": "Paraguayan guaraní",
            "currencySymbol": "PYG"
        },
        {
            "currencyName": "Qatari riyal",
            "currencySymbol": "QAR"
        },
        {
            "currencyName": "Romanian new leu",
            "currencySymbol": "RON"
        },
        {
            "currencyName": "Serbian dinar",
            "currencySymbol": "RSD"
        },
        {
            "currencyName": "Russian rouble",
            "currencySymbol": "RUB"
        },
        {
            "currencyName": "Rwandan franc",
            "currencySymbol": "RWF"
        },
        {
            "currencyName": "Saudi riyal",
            "currencySymbol": "SAR"
        },
        {
            "currencyName": "Seychelles rupee",
            "currencySymbol": "SCR"
        },
        {
            "currencyName": "Sudanese dinar",
            "currencySymbol": "SDD"
        },
        {
            "currencyName": "Sudanese pound",
            "currencySymbol": "SDG"
        },
        {
            "currencyName": "Swedish krona",
            "currencySymbol": "SEK"
        },
        {
            "currencyName": "Singapore dollar",
            "currencySymbol": "SGD"
        },
        {
            "currencyName": "Saint Helena pound",
            "currencySymbol": "SHP"
        },
        {
            "currencyName": "Slovak koruna",
            "currencySymbol": "SKK"
        },
        {
            "currencyName": "Sierra Leonean leone",
            "currencySymbol": "SLL"
        },
        {
            "currencyName": "Somali shilling",
            "currencySymbol": "SOS"
        },
        {
            "currencyName": "São Tomé and Príncipe",
            "currencySymbol": "STD"
        },
        {
            "currencyName": "Salvadoran colón",
            "currencySymbol": "SVC"
        },
        {
            "currencyName": "Swazi lilangeni",
            "currencySymbol": "SZL"
        },
        {
            "currencyName": "Thai baht",
            "currencySymbol": "THB"
        },
        {
            "currencyName": "Tajikistani somoni",
            "currencySymbol": "TJS"
        },
        {
            "currencyName": "Turkmenistani manat",
            "currencySymbol": "TMT"
        },
        {
            "currencyName": "Tunisian dinar",
            "currencySymbol": "TND"
        },
        {
            "currencyName": "Turkish lira",
            "currencySymbol": "TRY"
        },
        {
            "currencyName": "Trinidad and Tobago dollar",
            "currencySymbol": "TTD"
        },
        {
            "currencyName": "New Taiwan dollar",
            "currencySymbol": "TWD"
        },
        {
            "currencyName": "Tanzanian shilling",
            "currencySymbol": "TZS"
        },
        {
            "currencyName": "Ukrainian hryvnia",
            "currencySymbol": "UAH"
        },
        {
            "currencyName": "Ugandan shilling",
            "currencySymbol": "UGX"
        },
        {
            "currencyName": "United States Dollar",
            "currencySymbol": "USD"
        },
        {
            "currencyName": "Uruguayan peso",
            "currencySymbol": "UYU"
        },
        {
            "currencyName": "Uzbekistan som",
            "currencySymbol": "UZS"
        },
        {
            "currencyName": "Venezuelan bolí",
            "currencySymbol": "VEF"
        },
        {
            "currencyName": "Vietnamese dong",
            "currencySymbol": "VND"
        },
        {
            "currencyName": "Vreneli 10F.",
            "currencySymbol": "VRL"
        },
        {
            "currencyName": "Vreneli 20F",
            "currencySymbol": "VRN"
        },
        {
            "currencyName": "Silver (one troy ounce)",
            "currencySymbol": "XAG"
        },
        {
            "currencyName": "Silver (kg)",
            "currencySymbol": "XAGK"
        },
        {
            "currencyName": "Gold (one troy ounce)",
            "currencySymbol": "XAU"
        },
        {
            "currencyName": "Gold (kg)",
            "currencySymbol": "XAUK"
        },
        {
            "currencyName": "East Caribbean dollar",
            "currencySymbol": "XCD"
        },
        {
            "currencyName": "Special drawing rights",
            "currencySymbol": "XDR"
        },
        {
            "currencyName": "Palladium (one troy ounce)",
            "currencySymbol": "XPD"
        },
        {
            "currencyName": "Palladium (kg)",
            "currencySymbol": "XPDK"
        },
        {
            "currencyName": "CFP franc",
            "currencySymbol": "XPF"
        },
        {
            "currencyName": "Platinum (one troy ounce)",
            "currencySymbol": "XPT"
        },
        {
            "currencyName": "Platinum (kg)",
            "currencySymbol": "XPTK"
        },
        {
            "currencyName": "Yemeni rial",
            "currencySymbol": "YER"
        },
        {
            "currencyName": "South African rand",
            "currencySymbol": "ZAR"
        },
        {
            "currencyName": "Zambian Kwacha",
            "currencySymbol": "ZMK"
        },
        {
            "currencyName": "Zambian kwacha",
            "currencySymbol": "ZMW"
        }
    ],
    "errorCode": 0,
    "msg": ""
}
```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th>Field Name</th><th width="101">Type</th><th>Description</th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>currencyName</code></td><td>string</td><td>The name of the cryptocurrency (e.g., Dai, Tether).</td></tr><tr><td><code>currencySymbol</code></td><td>string</td><td>The symbol representing the cryptocurrency (e.g., DAI, USDT). <mark style="color:purple;">Use this as input in other API requests.</mark></td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Get Account Balance / Holdings

This endpoint allows you to retrieve the  account balance/ holdings for your merchant account. It provides essential information regarding the quantity of crypto tokens available, which can be critical for managing transactions and ensuring you have sufficient balance for processing payments.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getAccountBalance`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create query parameters (if any)
const queryParams = '{}';

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(queryParams)
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
axios.get("https://api.tylt.money/transactions/merchant/getAccountBalance", { headers })
  .then(response => {
    console.log("Response:", response.data);
  })
  .catch(error => {
    console.error('Error:', error.response ? error.response.data : error.message);
  });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import json
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Create query parameters (if any)
query_params = {}

# Create the HMAC SHA-256 signature
signature = hmac.new(api_secret.encode(), query_params.encode(), hashlib.sha256).hexdigest()

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the GET request
response = requests.get("https://api.tylt.money/transactions/merchant/getAccountBalance", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Create query parameters (if any)
const queryParams = '{}';

// Create the HMAC SHA-256 signature
const signature = crypto
  .createHmac('sha256', apiSecret)
  .update(queryParams)
  .digest('hex');

// Define headers
const headers = {
  "X-TLP-APIKEY": apiKey,
  "X-TLP-SIGNATURE": signature
};

// Send the GET request
fetch("https://api.tylt.money/transactions/merchant/getAccountBalance", { headers })
  .then(response => response.json())
  .then(data => console.log("Response:", data))
  .catch(error => console.error('Error:', error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "currencySymbol": "USDT",
            "balance": 12.0579
        },
        {
            "currencySymbol": "DAI",
            "balance": 0.99
        }
    ],
    "errorCode": 0,
    "msg": ""
}

```

{% endtab %}

{% tab title="Response Fields" %}

<table data-header-hidden><thead><tr><th>Field Name</th><th width="101">Type</th><th>Description</th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>balance</code></td><td>number</td><td>The token balance</td></tr><tr><td><code>currencySymbol</code></td><td>string</td><td>The symbol representing the cryptocurrency (e.g., DAI, USDT). <mark style="color:purple;">Use this as input in other API requests.</mark></td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Get Supported Crypto Networks

This endpoint allows you to retrieve a list of supported cryptocurrency networks.

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/getSupportedCryptoNetworksList`

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const crypto = require('crypto');
const axios = require('axios');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Function to generate the signature for GET requests
function generateSignature(params) {
    return crypto.createHmac('sha256', apiSecret).update(JSON.stringify(params)).digest('hex');
}

// Parameters (if any)
const params = {};

// Create signature
const signature = generateSignature(params);

// Set up headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send GET request using Axios
axios.get("https://api.tylt.money/transactions/merchant/getSupportedCryptoNetworksList", { headers: headers })
    .then(response => {
        console.log("Response:", response.data);
    })
    .catch(error => {
        console.error("Error:", error.response ? error.response.data : error.message);
    });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import json
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to generate the signature for GET requests
def generate_signature(params):
    payload = json.dumps(params, separators=(',', ':'))
    return hmac.new(api_secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

# Parameters (if any)
params = {}

# Create signature
signature = generate_signature(params)

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send GET request
response = requests.get("https://api.tylt.money/transactions/merchant/getSupportedCryptoNetworksList", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const fetch = require('node-fetch');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Function to generate the signature for GET requests
function generateSignature(params) {
    return crypto.createHmac('sha256', apiSecret).update(JSON.stringify(params)).digest('hex');
}

// Parameters (if any)
const params = {};

// Create signature
const signature = generateSignature(params);

// Set up headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send GET request
fetch(`https://api.tylt.money/transactions/merchant/getSupportedCryptoNetworksList`, { method: 'GET', headers: headers })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "msg": "",
    "data": [
        {
            "networkName": "Binance Smart Chain",
            "networkSymbol": "BSC"
        },
        {
            "networkName": "Ethereum",
            "networkSymbol": "ETH"
        }
    ]
}
```

{% endtab %}

{% tab title="400" %}

<table data-header-hidden><thead><tr><th></th><th width="105"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><code>networkName</code></td><td>string</td><td>The name of the network (e.g., Binance Smart Chain, Ethereum).</td></tr><tr><td><code>networkSymbol</code></td><td>string</td><td>The symbol representing the network (e.g., BSC, ETH). <mark style="color:purple;">Used as an input in other API's</mark></td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Supported Base Currency List

This endpoint allows you to retrieve a list of supported Base Currencies

**Endpoint**

<mark style="color:green;">**`GET`**</mark>`https://api.tylt.money/transactions/merchant/`getSupportedBaseCurrenciesList

**Request Headers**

{% tabs %}
{% tab title="Headers" %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const crypto = require('crypto');
const axios = require('axios');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Function to generate the signature for GET requests
function generateSignature(params) {
    return crypto.createHmac('sha256', apiSecret).update(JSON.stringify(params)).digest('hex');
}

// Parameters (if any)
const params = {};

// Create signature
const signature = generateSignature(params);

// Set up headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send GET request using Axios
axios.get("https://api.tylt.money/transactions/merchant/getSupportedBaseCurrenciesList", { headers: headers })
    .then(response => {
        console.log("Response:", response.data);
    })
    .catch(error => {
        console.error("Error:", error.response ? error.response.data : error.message);
    });

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import json
import hmac
import hashlib

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Function to generate the signature for GET requests
def generate_signature(params):
    payload = json.dumps(params, separators=(',', ':'))
    return hmac.new(api_secret.encode(), payload.encode(), hashlib.sha256).hexdigest()

# Parameters (if any)
params = {}

# Create signature
signature = generate_signature(params)

# Define headers
headers = {
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send GET request
response = requests.get("https://api.tylt.money/transactions/merchant/getSupportedBaseCurrenciesList", headers=headers)

# Print the response
if response.status_code == 200:
    print("Response:", response.json())
else:
    print(f"Failed with status code {response.status_code}: {response.text}")

```

{% endtab %}

{% tab title="JavaScript" %}

```javascript
const crypto = require('crypto');
const fetch = require('node-fetch');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Function to generate the signature for GET requests
function generateSignature(params) {
    return crypto.createHmac('sha256', apiSecret).update(JSON.stringify(params)).digest('hex');
}

// Parameters (if any)
const params = {};

// Create signature
const signature = generateSignature(params);

// Set up headers
const headers = {
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Send GET request
fetch(`https://api.tylt.money/transactions/merchant/getSupportedBaseCurrenciesList`, { method: 'GET', headers: headers })
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": [
        {
            "currencyName": "1inch",
            "currencySymbol": "1INCH",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Aave",
            "currencySymbol": "AAVE",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Arcblock",
            "currencySymbol": "ABT",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Alchemy Pay",
            "currencySymbol": "ACH",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Cardano",
            "currencySymbol": "ADA",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "United Arab Emirates dirham",
            "currencySymbol": "AED",
            "currencyType": "FIAT"
        },
        {
            "currencyName": "Aergo",
            "currencySymbol": "AERGO",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Afghan afghani",
            "currencySymbol": "AFN",
            "currencyType": "FIAT"
        },
        {
            "currencyName": "AIOZ Network",
            "currencySymbol": "AIOZ",
            "currencyType": "CRYPTO"
        },
        {
            "currencyName": "Akash Network",
            "currencySymbol": "AKT",
            "currencyType": "CRYPTO"
        },
        ...
    ]
}

  

```

{% endtab %}

{% tab title="400" %}

<table data-header-hidden><thead><tr><th></th><th width="105"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td><pre><code>currencyName
</code></pre></td><td>string</td><td>The name of the base currency (e.g., US Tether, US Dollar, Euro, Singapore Dollar).</td></tr><tr><td><pre><code>currencySymbol
</code></pre></td><td>string</td><td>The symbol representing the currency (e.g., USDT, BTC). <mark style="color:purple;">Used as an input in other API's</mark></td></tr><tr><td><pre><code>currencyType
</code></pre></td><td>string</td><td>The type of the Base Currency  either FIAT or CRYPTO</td></tr></tbody></table>
{% endtab %}
{% endtabs %}


# Webhook

#### Overview

Tylt provides a webhook mechanism for merchants to receive real-time updates on the status of their transactions, whether for pay-ins. Merchants can specify a `callBackUrl` in their API requests, and Tylt will send notifications to this URL whenever there is a status change in the transaction.

#### Setting Up the Webhook

1. **Implement a Callback Endpoint:** Merchants must set up an HTTP POST endpoint that can receive JSON payloads. This endpoint should be capable of processing the incoming webhook data and verifying its authenticity using HMAC-SHA256 signature validation.
2. **Insert the Callback URL:** During a pay-in request, insert your endpoint URL in the `callBackUrl` field. Tylt will send updates to this URL whenever the transaction status changes.
3. **Status Updates:** When a transaction status changes to `Pending`, `Completed`, `Under Payment`, `Over Payment`, or `Expired` Tylt will send a JSON payload with the updated status.
4. **Callback Validation:** To ensure the integrity and authenticity of the callback, Tylt signs each callback payload using HMAC-SHA256 with the merchant’s API secret key. This signature is sent in the HTTP header `X-TLP-SIGNATURE`.
5. **Acknowledge the Callback:** Upon receiving the callback, merchants must respond with an HTTP 200 status code and the text `"ok"` in the response body. This acknowledges the successful receipt of the callback. If the acknowledgment is not received, the webhook will not be retried automatically. Merchants can manually resend webhooks from their Tylt dashboard.

#### Validating Callbacks

Merchants should validate the HMAC signature included in the `X-TLP-SIGNATURE` header to ensure the callback is from Tylt and has not been tampered with. The HMAC signature is generated using the raw POST data and the `MERCHANT_API_SECRET` as the shared key.

#### Example Web-hook Handling Code

{% tabs %}
{% tab title="JavaScript" %}

```javascript
const express = require('express');
const crypto = require('crypto');

const app = express();
const PORT = 3000;
const apiSecretKey = 'YOUR_TLP_API_SECRET_KEY'; // Replace with your actual API secret key

// Middleware to parse incoming JSON requests
app.use(express.json());

// Callback endpoint
app.post('/callback', (req, res) => {
    const data = req.body;

    // Calculate HMAC signature
    const tlpSignature = req.headers['x-tlp-signature'];
    const calculatedHmac = crypto
        .createHmac('sha256', apiSecretKey)
        .update(JSON.stringify(data)) // Use raw body string for HMAC calculation
        .digest('hex');

    if (calculatedHmac === tlpSignature) {
        // Signature is valid
        if (data.type === 'pay-in') {
            console.log('Received pay-in callback:', data);
            // Process pay-in data here
        } 
        // Return HTTP Response 200 with content "ok"
        res.status(200).send('ok');
    } else {
        // Invalid HMAC signature
        res.status(400).send('Invalid HMAC signature');
    }
});

// Start the server
app.listen(PORT, () => {
    console.log(`Server listening on port ${PORT}`);
});

```

{% endtab %}

{% tab title="Python" %}

```python
from flask import Flask, request, jsonify
import hmac
import hashlib
import json

app = Flask(__name__)

# Your TL Pay API Secret Key
TLP_API_SECRET_KEY = 'YOUR_TLP_API_SECRET_KEY'  # Replace with your actual API secret key

@app.route('/callback', methods=['POST'])
def callback():
    # Get the raw request data for HMAC calculation
    raw_data = json.dumps(request.get_json(), separators=(',', ':'), ensure_ascii=False)

    # Parse JSON data from the request
    data = request.get_json()
    
    # Retrieve the signature from the request headers
    tlp_signature = request.headers.get('X-TLP-SIGNATURE')

    # Calculate the HMAC SHA-256 signature
    calculated_hmac = hmac.new(
        key=TLP_API_SECRET_KEY.encode(),
        msg=raw_data,
        digestmod=hashlib.sha256
    ).hexdigest()

    # Compare the calculated HMAC signature with the one in the request header
    if hmac.compare_digest(calculated_hmac, tlp_signature):
        # Signature is valid
        if data['type'] == 'pay-in':
            print('Received pay-in callback:', data)
            # Process pay-in data here
            
        # Return HTTP Response 200 with content "ok"
        return jsonify({"message": "ok"}), 200
    else:
        # Invalid HMAC signature
        return jsonify({"error": "Invalid HMAC signature"}), 400

if __name__ == '__main__':
    app.run(port=3000, debug=True)

```

{% endtab %}
{% endtabs %}

Again, please note that these code snippets serve as examples and may require modifications based on your specific implementation and framework.

**Example of Web-hook Responses**

{% tabs %}
{% tab title="Pay-In: Success" %}

```json
{
  "data": {
    "orderId": "sample-id-1", // an id like ajdng-adgh-1433-adad
    "merchantOrderId": "sample-id-2", // an id like ajdng-adgh-1433-adad
    "baseAmount": 10,
    "baseCurrency": "USDT",
    "baseAmountReceived": 10,
    "settledCurrency": "USDT",
    "settledAmountRequested": 10,
    "settledAmountReceived": 10,
    "settledAmountCredited": 9.9,
    "commission": 0.1,
    "network": "BSC",
    "depositAddress": "address", // a crypto wallet address
    "status": "Completed",
    "paymentURL": "https://app.tylt.money/pscreen/sample-id-1", // sample-id-1 is the orderId above
    "callBackURL": "https://www.domain.com/your_callback_url", // your url where this callback data is sent
    "transactions": [
      {
        "fromAddress": "address", // a crypto wallet address
        "transactionHash": "txn_hash", // a crypto transaction hash
        "amount": 10,
        "confirmationStatus": 1,
        "createdAt": "2024-11-06T19:00:29Z",
        "updatedAt": "2024-11-06T19:01:21Z"
      }
    ],
    "createdAt": "2024-11-06T18:54:44Z",
    "expiresAt": "2024-11-06T19:54:44Z",
    "updatedAt": "2024-11-06T19:01:21Z",
    "isFinal": 1,
    "isCredited": 1,
    "customerName": "",
    "comments": "",
    "accounts" : {
      "rate": 90, // for transaction where a fiat equivalent crypto is required
      "cryptoReceived": 10,
      "equivalentFiat": 900// for transaction where a fiat equivalent crypto is required
    }
  },
  "type": "pay-in"
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}

{% tab title="Pay-Out: Success" %}

```json
{
  "data": {
    "orderId": "sample-id-1", // an id like ajdng-adgh-1433-adad
    "merchantOrderId": "sample-id-2", // an id like ajdng-adgh-1433-adad
    "settledCurrency": "USDT",
    "settledAmountRequested": 10,
    "settledAmountDebited": 10,
    "settledAmountSent": 9.9,
    "commission": 0.1,
    "network": "BSC",
    "toAddress": "address", // a crypto wallet address
    "status": "Completed",
    "insufficientBalance": 0,
    "paymentURL": "", // sample-id-1 is the orderId above
    "callBackURL": "", // your url where this callback data is sent
    "transactions": [
      {
        "fromAddress": "address", // a crypto wallet address
        "transactionHash": "txn_hash", // a crypto transaction hash
        "amount": 10,
        "confirmationStatus": 1,
        "createdAt": "2024-11-06T19:00:29Z",
        "updatedAt": "2024-11-06T19:01:21Z"
      }
    ],
    "createdAt": "2024-11-06T18:54:44Z",
    "expiresAt": "2024-11-06T19:54:44Z",
    "updatedAt": "2024-11-06T19:01:21Z",
    "isFinal": 1,
    "isDebited": 1,
    "customerName": "",
    "comments": "",
    "accounts" : {
      "rate": 90, // for transaction where a fiat equivalent crypto is required
      "cryptoSent": 10,
      "equivalentFiat": 900// for transaction where a fiat equivalent crypto is required
    }
  },
  "type": "pay-out"
}
```

Again, please note that these response snippets serve as examples and may require modifications based on your specific implementation and framework.
{% endtab %}
{% endtabs %}

### Understanding and Handling Transactions Based on Status

The response field **`status`** represents the current state of a transaction. Applications should interpret and handle transactions according to the following possible states:

| Status        | Description                                                                                                                                                  |
| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Pending       | The transaction is awaiting payment or confirmation.                                                                                                         |
| Completed     | The transaction is successfully completed and settled. The customer has paid **exactly** the `settledAmountRequested`.                                       |
| Under Payment | **Applicable to Pay-in:** The transaction is completed and settled, but the customer paid **less** than the `settledAmountRequested`.                        |
| Over Payment  | **Applicable to Pay-in:** The transaction is completed and settled, but the customer paid **more** than the `settledAmountRequested`.                        |
| Expired       | **Applicable to Pay-in:** The transaction expired without any payment being received from the customer.                                                      |
| Cancelled     | **Applicable to Pay-out:** The transaction was cancelled without any payment being made to the payee and without a debit being made to the merchant account. |

## Understanding and Handling Over-Payment and Under-Payment

How a merchant handles over-payments and under-payments depends on their **business model**, **use case**, and **internal policies**. Broadly, practices differ between industries that **accept deposits** and those that **sell goods or services**.

***

### 1. Industries Accepting Deposits

*(e.g., iGaming, Trading, Forex, Wallet Services, Insurance)*

In these industries, payments are treated as **deposits into a user account/wallet**. The user’s balance is updated based on either:

* **baseCurrencyReceived** → The fiat or local equivalent value at the time of receipt (e.g., BRL, AED).
* **settledCurrencyReceived** → The actual crypto amount received in the settlement currency (e.g., USDT).

#### Under-Payment

* Merchant may accept the partial payment and **credit proportionally**.
* Merchant may choose to **refund the entire amount**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

#### Over-Payment

* Merchant may **refund the excess**.
* Merchant may accept the full amount and **credit the total received**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

***

**Example A: Deposit Requested in Crypto (USDT)**

* **Requested**: 100 USDT
* **Received**: 95 USDT (under-payment) → Merchant credits **95 USDT** to user wallet.
* **Received**: 105 USDT (over-payment) → Merchant credits **105 USDT** to user wallet.

Since both the **baseCurrency** and **settledCurrency** are the same (USDT), the merchant may use either `baseCurrencyReceived` or `settledCurrencyReceived` to handle the business logic.

***

**Example B: Deposit Requested in Fiat (FX-Denominated)**

* **Requested**: 500 BRL equivalent

1. **Received**: 95 USDT → At settlement, worth **475 BRL**.
   * Merchant may credit:
     * **475 BRL** (using `baseCurrencyReceived`), OR
     * **95 USDT** (using `settledCurrencyReceived`).
2. **Received**: 105 USDT → At settlement, worth **525 BRL**.
   * Merchant may credit:
     * **525 BRL** (using `baseCurrencyReceived`), OR
     * **105 USDT** (using `settledCurrencyReceived`).

{% hint style="warning" %}
**Response Records:**

* `baseCurrencyReceived = 475 BRL / 525 BRL`
* `settledCurrencyReceived = 95 USDT / 105 USDT`

This **dual recording** ensures flexibility: deposits can be credited in either **fiat terms** or **crypto terms**, depending on merchant policy.
{% endhint %}

***

### 2. Industries Accepting Payments for Sale of Merchandise

*(e.g., Retail, eCommerce, SaaS, Subscriptions)*

Here, payments correspond to a **specific invoice** for goods or services. Merchants may settle either in **fiat equivalent value** or in the **crypto amount received**.

#### Under-Payment

* Merchant may **hold the order** until the missing balance is paid.&#x20;
* Merchant may **accept partial payment** and adjust/store credit accordingly.

#### Over-Payment

* Merchant may **refund the excess amount**.
* Merchant may **apply the excess as store credit**.

{% hint style="warning" %}
**Refund can be initiated by using the** [**Creating a Payout Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request)
{% endhint %}

***

#### 📌 Example A: Invoice Requested in Crypto (USDT)

* **Invoice**: 100 USDT

1. **Received = 95 USDT (under-payment)**

   * (a) Hold order until extra 5 USDT is received.
   * (b) Accept 95 USDT and adjust/store credit.

   **Response Records:**

   * `baseCurrencyReceived = 95 USDT`
   * `settledCurrencyReceived = 95 USDT`
2. **Received = 105 USDT (over-payment)**

   * (a) Ship order and refund 5 USDT.
   * (b) Apply 5 USDT as store credit.

   **Response Records:**

   * `baseCurrencyReceived = 105 USDT`
   * `settledCurrencyReceived = 105 USDT`

***

#### 📌 Example B: Invoice Requested in Fiat (AED)

* **Invoice**: 1,000 AED

1. **Received = 95 USDT → 950 AED (under-payment)**

   * (a) Hold order until missing 50 AED is received.
   * (b) Process order for 950 AED value.
   * (c) Refund the entire amount.

   **Response Records:**

   * `baseCurrencyReceived = 950 AED`
   * `settledCurrencyReceived = 95 USDT`
2. **Received = 105 USDT → 1,050 AED (over-payment)**

   * (a) Ship order for 1,000 AED and refund 50 AED.
   * (b) Apply 50 AED as store credit.
   * (c) Refund the entire 1,050 AED.

   **Response Records:**

   * `baseCurrencyReceived = 1,050 AED`
   * `settledCurrencyReceived = 105 USDT`

{% hint style="warning" %}
**Response Records:**

* `baseCurrencyReceived = 1,050 AED / 950 AED`
* `settledCurrencyReceived = 95 USDT / 105 USDT`

This **dual recording** ensures flexibility: deposits can be credited in either **fiat terms** or **crypto terms**, depending on merchant policy.
{% endhint %}


# Creating a Payout Request

This resource allows users to submit cryptocurrency payouts to active recipients. It caters to various use cases such as offering cryptocurrency withdrawals to clients, facilitating payouts for marketplaces or affiliate networks, or managing payroll by creating multiple payouts at a time.

**Endpoint**

<mark style="color:green;">**`POST`**</mark>`https://api.tylt.money/transactions/merchant/createPayoutRequest`

**Request Headers**

{% tabs %}
{% tab %}

<table data-full-width="true"><thead><tr><th width="133">Name</th><th width="79">Type</th><th width="167">Example</th><th>Description</th></tr></thead><tbody><tr><td>X-TLP-APIKEY</td><td>string</td><td>93ee3c5e133697251b5362bcf9cc8532476785t8768075616f58d88</td><td>Your Tylt API Key, used to identify your account in API requests.</td></tr><tr><td>X-TLP-SIGNATURE</td><td>string</td><td>d0afef3853dfc8489c8b9affa5825171fdd7y7685675e4966a05f66ed2b3eaf9462b3c9c0</td><td>HMAC SHA-256 signature generated using the API Secret Key to secure the request.</td></tr></tbody></table>
{% endtab %}
{% endtabs %}

{% hint style="info" %}
When using the API, ensure to include your API Key and generate the signature for the request payload using your API Secret. The tables provided above contain example values for illustration purposes only. Please refer to the code snippets for detailed instructions on how to sign the request and generate the signature properly.
{% endhint %}

**Request Body**

{% tabs %}
{% tab title="Body" %}

<table data-header-hidden><thead><tr><th width="172"></th><th width="136"></th><th></th></tr></thead><tbody><tr><td><strong>Field Name</strong></td><td><strong>Type</strong></td><td><strong>Description</strong></td></tr><tr><td>baseAmount</td><td>number</td><td>The amount of currency to be sent.</td></tr><tr><td>baseCurrency</td><td>string</td><td><strong>Optional:</strong> To be used if the amount into crypto to be sent is expressed as FIAT. The baseCurrency symbol must be of the FIAT currency. Check supporting baseCurrency API for more details.</td></tr><tr><td>address</td><td>string</td><td>The recipient's address for the payout.</td></tr><tr><td>settledCurrency</td><td>string</td><td>The currency in which the payout will be made (symbol).</td></tr><tr><td>networkSymbol</td><td>string</td><td>The network to be used for the payout (e.g., BSC).</td></tr><tr><td>customerName</td><td>string</td><td>Optional: Customer's name for the transaction.</td></tr><tr><td>comments</td><td>string</td><td>Optional: Comments for additional context.</td></tr><tr><td>callBackUrl</td><td>string</td><td>Optional: URL for the callback after transaction completion.</td></tr><tr><td>redirectUrl</td><td>string</td><td>Optional: URL for the redirection after transaction completion.</td></tr><tr><td></td><td></td><td></td></tr></tbody></table>
{% endtab %}
{% endtabs %}

**Code Snippet**

{% tabs %}
{% tab title="Node JS" %}

```javascript
const axios = require('axios');
const crypto = require('crypto');

// Replace with your API Key and Secret
const apiKey = 'your-api-key';
const apiSecret = 'your-api-secret';

// Request body
// In this example we are sending USDT worth INR 10000 to the web3 address
const requestBody = {
    baseAmount: 10000,
    baseCurrency: "INR"
    address: "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
    settledCurrency: "USDT",
    networkSymbol: "BSC",
    callBackUrl:"www.callback.com",
    redirectUrl:"www.redirect.com"
};

// Convert request body to JSON
const raw = JSON.stringify(requestBody);

// Function to create HMAC SHA-256 signature
const createSignature = (secret, data) => {
    return crypto.createHmac('sha256', secret)
                 .update(data)
                 .digest('hex');
};

// Generate signature
const signature = createSignature(apiSecret, raw);

// Define headers
const headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": apiKey,
    "X-TLP-SIGNATURE": signature
};

// Function to send the request
const sendRequest = async (url, headers, body) => {
    const response = await axios.post(url, body, { headers: headers });
    return response.data;
};

// Send the request
sendRequest("https://api.tylt.money/transactions/merchant/createPayoutRequest", headers, raw)
    .then(result => console.log("Success:", result))
    .catch(error => console.error("Error:", error));

```

{% endtab %}

{% tab title="Python" %}

```python
import requests
import hmac
import hashlib
import json

# Replace with your API Key and Secret
api_key = 'your-api-key'
api_secret = 'your-api-secret'

# Request body
request_body = {
    "baseAmount": 10000,
    "baseCurrency": "INR"
    "address": "0xd2AF4B117EfE474B66Fc79E6A8E1938D41a60F4c",
    "settledCurrency": "USDT",
    "networkSymbol": "BSC",
    "callBackUrl":"www.callback.com",
    "redirectUrl":"www.redirect.com"
}

# Convert request body to JSON
raw = json.dumps(request_body, separators=(',', ':'), ensure_ascii=False)

# Function to create HMAC SHA-256 signature
def create_signature(secret, data):
    return hmac.new(secret.encode(), data.encode(), hashlib.sha256).hexdigest()

# Generate signature
signature = create_signature(api_secret, raw)

# Define headers
headers = {
    "Content-Type": "application/json",
    "X-TLP-APIKEY": api_key,
    "X-TLP-SIGNATURE": signature
}

# Send the request
response = requests.post("https://api.tylt.money/transactions/merchant/createPayoutRequest", headers=headers, data=raw)

# Print the response
print("Success:", response.json())

```

{% endtab %}
{% endtabs %}

**Response**

{% tabs %}
{% tab title="200" %}

```json
{
    "data": {
        "orderId": "1deecabb-79b8-11ef-8277-02d8461243e9",
        "merchantOrderId": "1deecabb-79b8-11ef-8277-02d8461243e9",
        "settledCurrency": "USDT",
        "settledAmountRequested": 0.1,
        "settledAmountDebited": 0,
        "settledAmountSent": 0,
        "commission": 0,
        "network": "BSC",
        "toAddress": "0xh22kbbq3hbth4bjwh433adgda",
        "status": "Pending",
        "insufficientBalance": 0,
        "paymentURL": "",
        "callBackURL": "",
        "transactions": [],
        "createdAt": "2024-09-23T14:28:35Z",
        "expiresAt": "2024-09-23T14:28:35Z",
        "updatedAt": "2024-09-23T14:28:35Z",
        "isFinal": 0,
        "isDebited": 0,
        "customerName": "",
        "comments": ""
    },
    "msg": "Withdrawal request accepted"
}
```

{% endtab %}

{% tab title="Response Fields" %}

| **Field Name**           | **Type** | **Description**                                                                   |
| ------------------------ | -------- | --------------------------------------------------------------------------------- |
| `orderId`                | String   | The order ID generated by TL Pay, used as a global identifier.                    |
| `merchantOrderId`        | String   | The merchant's local order ID for reference (optional).                           |
| `settledCurrency`        | String   | The cryptocurrency or token used for payout.                                      |
| `settledAmountRequested` | Number   | The amount of cryptocurrency or token requested to be paid out.                   |
| `settledAmountDebited`   | Number   | The amount of cryptocurrency debited from your merchant balance.                  |
| `settledAmountSent`      | Number   | The total amount of cryptocurrency sent to the recipient.                         |
| `commission`             | Number   | The commission deducted from the payout transaction.                              |
| `network`                | String   | The blockchain network over which the payout is made (e.g., "BSC").               |
| `toAddress`              | String   | The recipient's wallet address where the payout will be sent.                     |
| `status`                 | String   | The status of the payout (e.g., "Pending", "Completed", "Failed").                |
| `insufficientBalance`    | Number   | Indicates if there is insufficient balance for the transaction (1 = Yes, 0 = No). |
| `paymentURL`             | String   | The URL where the customer can make the payment (if applicable).                  |
| `callBackURL`            | String   | The callback URL specified by the merchant (optional).                            |
| `transactions`           | Array    | Details of any individual transactions linked to this payout (if applicable).     |
| `createdAt`              | String   | The timestamp when the payout request was created.                                |
| `expiresAt`              | String   | The timestamp when the payout request will expire.                                |
| `updatedAt`              | String   | The timestamp when the payout request was last updated.                           |
| `isFinal`                | Number   | Indicates if the transaction is final (`1` for completed, `0` for pending).       |
| `isDebited`              | Number   | Indicates if the payout amount has been debited from your merchant account.       |
| `customerName`           | String   | The name of the customer associated with the transaction (optional).              |
| `comments`               | String   | Any comments or notes provided by the merchant (optional).                        |
| {% endtab %}             |          |                                                                                   |
| {% endtabs %}            |          |                                                                                   |


# Use Cases


# E-commerce Flow

In an e-commerce scenario, merchants can leverage Tylt's cryptocurrency payment gateway to offer customers the option to make purchases using various cryptocurrencies. The flow for this use case is as follows:

1. The customer selects items for purchase, determining the total sum.
2. The customer selects the preferred payment currency ( Eg. USDT, DAI, USDC etc.)
3. The merchant generates a payment link using Tylt's [**Create Pay-In Request**](/tylt-cpg-crypto-gateway/api-reference/accept-crypto-assets/creating-a-pay-in-request) API. This allows the merchant to create a payment link with all the necessary details, such as payment amount, currency, and optional parameters.
4. Tylt generates a unique payment link for the customer with the payment details such as the payment crypto currency, the wallet address to which the customer needs to make the payment, the validity of the link and the time left before expiration.
5. The customer receives the payment link and clicks to proceed with payment. Alternatively, the merchant can display the link on the website or send it via email. The merchant can also display the link contents using a web-view or iframe equivalent solution.
6. Upon clicking the link, the customer is redirected to Tylt's payment gateway to complete the payment.
7. Once the customer initiates the payment by sending the required cryptocurrency to the specified address, the transaction details tracked and displayed to the customer on a real-time basis. Upon receiving the necessary confirmations, the payment is made complete.&#x20;
8. The customer can click on the "Return to Website" button to redirect to the merchant's specified return URL (if provided).
9. The merchant's system receives a callback from Tylt with payment information, such as transaction status, currency, amount, and fees.
10. The merchant updates the order status and processes the purchase, allowing the customer to access their goods or services.
11. The merchant can access detailed payment-related information in their Tylt account for easy management, they can also query the transaction details using the [Get Pay-In Transaction Information](/tylt-cpg-crypto-gateway/api-reference/accept-crypto-assets/get-pay-in-transaction-information) API


# Withdrawal Flow

For platforms enabling withdrawals, Tylt streamlines the management of user funds, providing merchants with a reliable and efficient payout mechanism. Below are common industries where this flow is essential:

#### **Customer Balance Withdrawals**

* **iGaming**: Instant withdrawals are a game-changer in the fast-growing online gaming industry, where 55% of players are likely to switch platforms offering instant access to winnings. This feature helps retain players and boosts deposits.
* **Trading & Investing**: With nearly 50% of investors willing to switch to platforms offering instant withdrawals, providing fast payouts is crucial. Platforms offering real-time fund access are more likely to attract and retain users, especially Millennials, who expect seamless experiences.

**Payouts & Refunds**

* **Retail**: Fast refunds have become essential, with 81% of shoppers expecting refunds within a week. Quick refunds directly influence purchase decisions, especially for higher-ticket items, helping brands build loyalty.
* **Insurance**: Instant payouts give insurers a competitive edge, reducing manual reconciliation and enhancing customer satisfaction. Automating payouts minimizes errors and delivers faster settlements, improving client retention.

**Example Flow:**

1. **Customer Request**: A customer on the merchants platform requests to withdraw funds from their account.
2. **Merchant Action**: The merchant, who holds the customer's crypto funds in their Tylt account, initiates the payout using the [**Create Pay-Out Request API**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/creating-a-payout-request). The merchant provides the customer's withdrawal address and the amount to be sent.
3. **Payment Processing**: Tylt processes the payout by sending the specified amount of cryptocurrency to the customer's withdrawal address.
4. **Notification**: Once the payout is processed, Tylt sends a callback to the merchant’s system, providing key details such as the transaction status, currency, amount, and any applicable fees.
5. **Merchant Update**: Upon receiving the callback, the merchant updates the customer’s account balance, reflecting the withdrawn amount.
6. **Tracking**: The merchant can track and manage all payout-related information, including transaction details and account balances, via their Tylt account or through the [**Get Pay-Out Transaction Information AP**](/tylt-cpg-crypto-gateway/api-reference/transfer-crypto-assets/get-pay-out-transaction-information)**I**.




---

[Next Page](/llms-full.txt/1)

