> ## Documentation Index
> Fetch the complete documentation index at: https://docs.dollarpe.xyz/llms.txt
> Use this file to discover all available pages before exploring further.

# Payout Integration Guide

<Highlight># Payout Integration Guide</Highlight>

## What Are Payouts and Why They Matter

Payouts enable your application to seamlessly transfer funds to your customers' bank accounts, using cryptocurrency as the funding source. Whether you're a developer or a business owner, this guide will help you integrate DollarPe's Payout system.

<Note>
  **Prerequisites:**

  * Ensure you have completed the [authentication setup](/guides/development-and-testing/authentication)
  * Configure your [webhook endpoint](/guides/development-and-testing/webhooks) for real-time updates
  * Review the following guides to ensure compatibility:
    * **[supported geographies](/guides/support/geographies)**
    * **[supported stablecoins and blockchains](/guides/support/stablecoins_and_blockchains)**
    * **[supported fiat methods](/guides/support/fiatMethods)**
    * Verify your users have completed KYC and have at least one verified bank account
</Note>

<Warning>
  **Warning**: Initiate the payout before the quotation expiry time.
</Warning>

## Integration at a Glance

The Payout integration flow for centralized exchanges involves the following key steps:

1. **Fetch Configurations** - Retrieve the basic configuration to understand supported assets, networks, and limits.
2. **Validate user requirements** – Ensure the customer has completed KYC verification and has at least one verified bank account added.
3. **Fetch payout limits** – Retrieve payout limits to check daily limits, available limits, and whether Enhanced Due Diligence (EDD) is required.
4. **Fetch exchange rates** – Retrieve the latest cryptocurrency exchange rates.
5. **Create a quotation** – Generate a quote for the desired payout amount.
6. **Initiate the payout** – Start the payout using the exchange order ID.
7. **Link exchange transfer ID** – Link the exchange transfer ID with the payout.
8. **Monitor transaction status** – Track the progress of the transaction.
9. **Handle completion** – Finalize the payout once the transaction is confirmed.

## Visual Integration Flow

### Process Flow Diagram

```mermaid theme={null}
%%{init: {'themeVariables': { 'fontSize': '18px', 'nodeWidth': '300', 'nodeHeight': '60' }}}%%
flowchart TD
    Start([Start Process]) --> CheckKYC["Check KYC & Bank Status"]
    CheckKYC -->|YES| CheckEDD["Is EDD Required?"]
    CheckKYC -->|NO| AddKYC["Complete KYC & Bank Verification"]

    AddKYC -->|API Call| KycAPI[/"API: /kyc/add-kyc-data/"/]
    KycAPI --> CheckKYC

    CheckEDD -->|YES| CompleteEDD["Complete EDD"]
    CheckEDD -->|NO| CreateQuote[Create Quotation]
    CompleteEDD -->|API Call| EDDAPI[/"API: /kyc/edd/"/]
    EDDAPI --> CreateQuote

    CreateQuote -->|API Call| QuoteAPI[/"API: /payout/quotation/"/]
    QuoteAPI --> InitiatePayout["Create Payout"]

    InitiatePayout -->|API Call| PayoutAPI[/"API: /payout/initiate/"/]
    PayoutAPI --> LinkTransfer["Link Exchange TransferId"]

    LinkTransfer -->|API Call| LinkAPI[/"API: /update-transfer-id/"/]
    LinkAPI --> WebhookNotification["Webhook Notification"]
    LinkAPI --> PollStatus["Order Polling"]

    WebhookNotification --> PayoutStatus{"Check Payout Status"}
    PollStatus --> PayoutStatus

    PayoutStatus -->|SUCCESS| PayoutDone["Payout Done"]
    PayoutStatus -->|FAILED| HandleFail["Handle Failure"]
    PayoutStatus -->|PROCESSING| WaitRetry["Recheck Later"]

    HandleFail --> ContactSupport[Contact Support]
    PayoutDone --> End([End Process])

    classDef startEndNode fill:#dcedc8,stroke:#558b2f,stroke-width:2px,color:#000
    classDef mainNode fill:#e3f2fd,stroke:#1976d2,stroke-width:2px,color:#000
    classDef apiNode fill:#f3e5f5,stroke:#8e24aa,stroke-width:2px,color:#000
    classDef stateNode fill:#e8f5e9,stroke:#2e7d32,stroke-width:2px,color:#000
    classDef failureNode fill:#ffebee,stroke:#c62828,stroke-width:2px,color:#000
    classDef waitNode fill:#fff8e1,stroke:#ff8f00,stroke-width:2px,color:#000

    class Start,End startEndNode
    class CheckKYC,AddKYC,CheckEDD,CompleteEDD,CreateQuote,InitiatePayout,LinkTransfer,HandleFail,ContactSupport,WaitRetry mainNode
    class KycAPI,EDDAPI,QuoteAPI,PayoutAPI,LinkAPI apiNode
    class WebhookNotification,PollStatus waitNode
    class PayoutDone stateNode
    class PayoutStatus decision
```

### Sequence Diagram: Detailed Process Flow

```mermaid theme={null}
sequenceDiagram
    participant Exchange as Centralized Exchange
    participant API as DollarPe API
    participant Bank as Banking System
    participant Webhook as Webhook System

    Exchange->>API: Check KYC & Bank Status
    API->>Exchange: Return KYC & Bank Status

    alt KYC & Bank Verified
        Exchange->>API: Is EDD Required?
        API->>Exchange: Return EDD Status

        alt EDD Required
            Exchange->>API: Complete EDD
            API->>Exchange: EDD Completed
        end

        Exchange->>API: Create Quotation
        API->>Exchange: Return Quotation

        Exchange->>API: Initiate Payout with OrderId
        API->>Exchange: Payout Created with payout_id

        Exchange->>API: Link Exchange TransferId
        API->>Exchange: TransferId Linked Successfully

        alt Successful Transaction
            API->>Bank: Initiate Bank Transfer
            Bank->>API: Transfer Successful

            API->>Webhook: Send Status Update (COMPLETED)
            Webhook->>Exchange: Webhook Notification (COMPLETED)

            Exchange->>API: Poll for Status Updates (optional)
            API->>Exchange: Status: COMPLETED
        else Failed Transaction
            API->>Bank: Transfer Failed

            API->>Webhook: Send Status Update (FAILED)
            Webhook->>Exchange: Webhook Notification (FAILED)

            Exchange->>API: Poll for Status Updates (optional)
            API->>Exchange: Status: FAILED
            Exchange->>Exchange: Handle Error & Notify User
        end
    else KYC & Bank Not Verified
        API->>Exchange: KYC/Bank Verification Required
        Exchange->>Exchange: Complete KYC & Bank Verification
    end
```

## Step-by-Step Integration Guide

### Step 1: Fetch Configurations

Before starting the integration, fetch the basic configuration to understand supported assets, networks, and limits:

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    GET /payout/configuration
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
    "status": true,
    "message": "Success",
    "data": {
      "inr": {
        "supported_assets": [
          "usdt",
          "usdc"
        ],
        "coin_limits": {
          "usdt": {
            "imps": {
              "min": 28,
              "max": 5563
            },
            "upi": {
              "min": 28,
              "max": 1113
            }
          },
          "usdc": {
            "imps": {
              "min": 28,
              "max": 5563
            },
            "upi": {
              "min": 28,
              "max": 1113
            }
          }
        },
        "required_risk_parameters": [
          "ip_address",
          "device_id",
          "suspicious_activity_report",
          "law_enforcement_agency_report"
        ]
      }
    }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `supported_fiats`: List of supported fiat currencies
* `supported_assets`: List of supported cryptocurrencies
* `supported_networks`: List of supported blockchain networks
* `coin_limits`: Minimum and maximum limits for each supported cryptocurrency

<Tip>
  If you are storing these configurations in your application to validate user
  inputs and display appropriate options, make sure to update this data
  periodically.
</Tip>

### Step 2: Check Customer KYC and Bank Account status

Before initiating any payout, ensure the customer is KYC-verified and has a verified bank account.

<Tabs>
  <Tab title="Fetch Customer Info">
    ```javascript theme={null}
    GET /customer/{customer_id}
    Response:
    {
        "status": true,
        "message": "Success",
        "data": {
            "id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
            "client_reference_id": "client_id_1",
            "full_name": "John Doe",
            "email": "john@example.com",
            "phone": "+911234123412",
            "country": "IND",
            "type": "INDIVIDUAL",
            "status": "UNVERIFIED",
            "failure_reason": null
        }
    }
    ```
  </Tab>

  <Tab title="Fetch Bank Account Info">
    ```javascript theme={null}
    GET /bank/list/{customer_id}
    {
      "status": true,
      "message": "Success",
      "data": {
        "count": 1,
        "next": null,
        "previous": "<url>",
        "results": [
          {
            "id": "4e6f1b20-a73c-11ec-b909-0242ac120002",
            "customer_id": "550e8400-e29b-41d4-a716-446655440000",
            "account_number": "123456789012",
            "ifsc_code": "ABC123456",
            "vpa": "testing@upi",
            "bank_account_type": "ACCOUNT_DETAILS",
            "bank_account_status": "VERIFIED"
          }
        ]
      }
    }
    ```
  </Tab>
</Tabs>

### Step 3: Check if EDD is Required

Before proceeding with the payout, check if Enhanced Due Diligence (EDD) is required for the customer. This step also returns current daily/available payout limits.

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    GET /edd/fetch?customer_id=520e8400-e29b-41d4-a716-446655440000
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "status": true,
      "message": "Success",
      "data": {
        "daily_limit": 500000,
        "available_limit": 100000,
        "payment_method_limits": {
            "per_transaction_limit": {
                "UPI": 100000,
                "IMPS": 100000
            },
            "total_available_limit": {
                "UPI": 100000,
                "IMPS": 100000
            }
        },
        "full_limit_reset_timestamp": "2024-03-13T10:00:00Z",
        "is_edd_required": false,
        "is_limit_increase_available": true
      }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `daily_limit`: Maximum daily payout limit for the asset
* `available_limit`: Remaining available payout limit for the current day
* `limit_reset_timestamp`: Unix timestamp when the daily limit will reset
* `is_edd_required`: Whether Enhanced Due Diligence (EDD) is required (true or false)
* `is_limit_increase_available`: Whether the customer can apply for a higher daily limit

<Tip>
  If `is_edd_required` is `true`, you must complete the EDD process for this customer before proceeding with the payout.
</Tip>

### Step 4: Fetch Exchange Rate

Get the real-time exchange rate for a given crypto asset.

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    GET /payout/fetch-rate
    {
      "asset": "usdt",
      "fiat": "inr",
    }
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "status": true,
      "message": "Success",
      "data": {
        "asset": "USDT",
        "fiat": "INR",
        "rate": 87.2
      }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `asset`: Cryptocurrency to be used (e.g., "USDT", "USDC")
* `amount`: Amount in cryptocurrency
* `rate`: Current exchange rate (amount of fiat per 1 unit of crypto)

<Tip>
  Rates fluctuate constantly based on market conditions. We recommend fetching a
  new rate before each transaction to ensure accuracy.
</Tip>

### Step 5: Create a Quotation

After getting the current rate, create a quotation to lock in the rate.

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    POST /payout/quotation
    {
      "asset": "usdt",
      "fiat": "inr",
      "sending_amount": "51",
      "customer_id": "def8b740-99f9-4cba-bc9e-99de57e927b4",
      "bank_id": "4e6f1b20-a73c-11ec-b909-0242ac120002",
      "risk_parameters": {
        "ip_address": "127.0.0.1",
        "device_id": "<string>",
        "suspicious_activity_report": false,
        "law_enforcement_agency_report": false
      }
    }
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
        "status": true,
        "message": "Success",
        "data": {
            "id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
            "customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
            "bank_id": "c863b696-7fbd-4b16-b3a7-134aefffb2fe",
            "asset": "USDT",
            "fiat": "INR",
            "sending_amount": 10,
            "rate": 87.2,
            "receiving_amount": 858.96,
            "fees": {
                "client_fee_fiat": "",
                "client_fee_crypto": "",
                "dollarpe_fee": "",
                "pg_fee": "",
                "client_gst_fiat": "",
                "client_gst_crypto": "",
                "dollarpe_gst": "",
                "pg_gst": "",
                "tds": "",
                "gross_exchange_rate": ""
            },
            "created_at": "2025-03-21T13:29:07.828029Z",
            "expiry_time": "2025-03-21T13:39:07.828029Z"
        }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `asset`: Cryptocurrency to be used
* `fiat`: Fiat currency to receive (e.g., "INR" for Indian Rupee)
* `sending_amount`: Amount in cryptocurrency
* `customer_id`: ID of the KYC-verified customer
* `expiry_time`: Time until the quotation expires

<Note>You must complete your transaction before this time expires.</Note>

### Step 6: Initiate the Payout

Create a payout request with the exchange order ID:

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    POST /payout/initiate
    {
      "quotation_id": "2e104290-07c8-49f1-a5ca-0d27f0078f8a",
      "customer_id": "def8b740-99f9-4cba-bc9e-99de57e927b4",
      "client_reference_id": "testUser123",
      "exchange_order_id": "898990982672892"
    }
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "status": true,
      "message": "Success",
      "data": {
          "id": "ac7c5360-0b57-4fb7-88f2-df1c371930ee",
          "quotation_id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
          "customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
          "client_reference_id": "payout_first_test",
          "bank_id": "c863b696-7fbd-4b16-b3a7-134aefffb2fe",
          "asset": "USDT",
          "fiat": "INR",
          "rate": 87.2,
          "sending_amount": 10,
          "receiving_amount": 858.96,
          "fees": {
              "client_fee_fiat": "",
              "client_fee_crypto": "",
              "dollarpe_fee": "",
              "pg_fee": "",
              "client_gst_fiat": "",
              "client_gst_crypto": "",
              "dollarpe_gst": "",
              "pg_gst": "",
              "tds": "",
              "gross_exchange_rate": ""
          },
          "exchange_order_id": "898990982672892",
          "created_at": "2025-03-21T13:37:53.208137Z",
          "status": "PROCESSING"
      }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `quotation_id`: ID received from Step 3
* `customer_id`: ID of the KYC-verified customer
* `client_reference_id`: Your internal reference ID for tracking (optional)
* `bank_id`: ID of the verified bank account
* `exchange_order_id`: ID of the order placed at the centralized exchange
* `status`: Current status of the payout

<Note>
  Most payouts are processed within 30-60 minutes, but can take up to 24 hours
  during high volume periods or in case of bank processing delays.
</Note>

### Step 7: Monitor Transaction Status

After linking the exchange transfer ID, you need to track the payout status. There are two ways to monitor this status:

#### Option A: Webhook Integration (Recommended)

Webhooks provide real-time updates about payout status changes. Configure your webhook endpoint to receive these notifications:

```javascript theme={null}
// Sample webhook payload for payout status updates
{
  "type": "PAYOUT",
  "id": "ac7c5360-0b57-4fb7-88f2-df1c371930ee",
  "event": "COMPLETED", // or "FAILED", "PROCESSING"
  "failure_reason": null, // Contains failure reason if status is "FAILED"
  "timestamp": "2025-03-21T13:37:53.208137Z",
  "data": {
    "utr": "123456789012", // Bank reference number (only for COMPLETED status)
    "fiat": "INR",
    "exchange_order_id": "order_123456789"
  }
}
```

<Tip>
  If using webhooks, ensure your server acknowledges receipt with a 200 OK
  response to prevent duplicate notifications.
</Tip>

#### Option B: Status Polling

If webhooks aren't feasible, you can periodically check the status using the payout endpoint:

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    GET /payout/{payout_id}
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
      {
      "status": true,
      "message": "Success",
      "data": {
        "id": "ac7c5360-0b57-4fb7-88f2-df1c371930ee",
        "quotation_id": "c9f343b5-ff56-4d52-93af-0962f75242b7",
        "customer_id": "8da49e5e-33d1-48b2-b107-eb34f851b2fd",
        "client_reference_id": "payout_first_test",
        "bank_id": "c863b696-7fbd-4b16-b3a7-134aefffb2fe",
        "asset": "USDT",
        "fiat": "INR",
        "sending_amount": "10.00000000",
        "rate": "87.20000000",
        "receiving_amount": "858.96000000",
        "fees": {
          "client_fee": "",
          "dollarpe_fee": "",
          "pg_fee": "",
          "client_gst": "",
          "dollarpe_gst": "",
          "pg_gst": "",
          "tds": "",
          "gross_exchange_rate": ""
        },
        "exchange_order_id": "",
        "exchange_transfer_id": "",
        "status": "PROCESSING",
        "utr": null,
        "failure_reason": "",
        "created_at": "2025-03-21T13:37:53.208137Z",
        "updated_at": "2025-03-21T13:37:53.208142Z"
      }
    }
    ```
  </Tab>
</Tabs>

<Tip>
  If using the polling approach, we recommend checking no more frequently than
  once every 60 seconds to avoid API rate limits.
</Tip>

**Possible Status Values:**

* `PROCESSING`: Initial state, waiting for crypto confirmation
* `SUCCESS`: Payout has been successfully completed and UTR is generated
* `FAILED`: Payout has failed and failure\_reason is updated

### Step 8: Handle Transaction Completion

#### Successful Transactions

When a payout is completed successfully:

1. Update your internal records with the transaction details
2. Notify your user that the funds have been sent to their bank account
3. Provide the bank reference number for their records (if available)
4. Store the transaction details for future reference and customer support

<Warning>
  If your transaction fails due to sending funds to the wrong address or
  network, recovery may not be possible. Always double-check these details
  before sending.
</Warning>

### Step 9: Link Exchange Order ID with Exchange Transfer ID

After the payout is successful, you must link the exchange transfer ID related to the crypto sent with the exchange order ID:

<Tabs>
  <Tab title="API Request">
    ```javascript theme={null}
    PATCH /payout/update-transfer-id
    {
      "exchange_order_id": "92823910232129090",
      "exchange_transfer_id": "9282391023212"
    }
    ```
  </Tab>

  <Tab title="Response">
    ```json theme={null}
    {
      "status": true,
      "message": "Success",
      "data": {
        "exchange_order_id": "92823910232129090",
        "exchange_transfer_id": "9282391023212"
      }
    }
    ```
  </Tab>
</Tabs>

**Key Fields:**

* `exchange_order_id`: The order ID from your centralized exchange
* `exchange_transfer_id`: The transfer ID associated with the crypto transaction

## Testing Your Integration

### Sandbox Environment

Before going live, test your integration thoroughly in our sandbox environment:

1. Use the base URL: `https://sandbox-api.dollarpe.xyz`
2. Follow the same steps as production
3. Test both successful and failed transaction scenarios

<Tip>
  In the sandbox environment, you can simulate different failure scenarios by
  using specific test values. Refer to our [Sandbox Testing
  Guide](/guides/sandbox-testing) for details.
</Tip>

## Getting Help

If you encounter any issues with your payout integration:

* Check our [API documentation](/api-reference-exchange/overview/introduction) for detailed endpoint information
* Visit the [Troubleshooting Guide](/guides/faq) for common solutions
* Contact our [support team](mailto:support@dollarpe.xyz) with your customer\_id and transaction logs

<Note>
  Our support team is available 24/7 to help with integration issues. For urgent
  matters, use the in-app chat or call our technical support hotline.
</Note>
