Payout Integration

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.

Prerequisites:

Warning: Send funds and initiate the payout before the quotation expiry time.

Integration at a Glance

The Payout integration flow involves the following key steps:

  • Validate user requirements – Ensure the customer has completed KYC verification and has at least one verified bank account added
  • Fetch Payout Configuration - Retrieve the basic payout configuration to understand the supported assets, networks, payment methods and their thresholds. It may also include required risk parameters to generate quotation.
  • Fetch exchange rates – Retrieve the latest cryptocurrency exchange rates
  • Fetch Payout Limits - Retrive payout limits to check daily limits, available limits, when will the limit reset. It also includes a flag to indicate if Enhanced Due Diligence (EDD) is required before initiating a Payout.
  • Create a quotation – Generate a quote for the desired payout amount
  • Initiate the payout – Initiate the payout order
  • Send crypto assets – Transfer crypto to the provided wallet address
  • Link Transaction Hash - Link your transaction hash generated with the payout order
  • Monitor transaction status – Track the progress of the transaction
  • Handle completion – Finalize the payout once the transaction is confirmed

Visual Integration Flow

Process Flow Diagram

Sequence Diagram: Detailed Process Flow

Step-by-Step Integration Guide

Step 1: Validate user requirements

Validate if the customer is fully ready to make their first transaction by following the KYC Integration Guide.

Step 2: Fetch Payout Configuration

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

GET /payout/configuration
{
"status": true,
"message": "Success",
"data": {
  "supported_fiats": [
    "aud"
  ],
  "supported_assets": [
    "usdt",
    "usdc"
  ],
  "supported_networks": {
    "usdt": ["polygon", "eth", "bsc", "sepolia", "solana", "tron", "arbitrum"],
    "usdc": ["polygon", "eth", "bsc", "sepolia", "solana", "tron", "arbitrum"]
  },
  "coin_limits": {
    "{asset}": {
      "{network}": {
        "osko": {
          "min": 28,
          "max": 5563
        },
        "payId": {
          "min": 28,
          "max": 1113
        }
      }
    }
  },
  "required_risk_parameters": []
}
}

Key Fields:

  • supported_fiats: List of supported fiat currencies
  • supported_assets: List of supported assets
  • supported_networks: List of supported blockchain networks
  • coin_limits: Minimum and maximum limits for each supported payment methods for asset-network pairs
  • required_risk_parameters: Mandatory risk parameters to be send while creating payout quotation.

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

Step 3: Fetch exchange rates

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

GET /payout/fetch-rate
{
  "asset": "usdt",
  "fiat": "aud",
  "network": "polygon",
}
{
  "status": true,
  "message": "Success",
  "data": {
    "asset": "USDT",
    "network": "POLYGON",
    "fiat": "AUD",
    "rate": 1.48
  }
}

Key Fields:

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

Step 4: Fetch Payout Limits

GET /payout/limits/{customer_id}
{
  "status": true,
  "message": "Success",
  "data": {
    "daily_limit": 100000,
    "available_limit": 35000,
    "full_limit_reset_timestamp": "2024-03-13T10:00:00Z",
    "is_edd_required": false,
    "is_limit_increase_available": false
  }
}

Key Fields:

  • daily_limit – Customer’s daily FIAT limit
  • available_limit – Available FIAT limit remaining
  • full_limit_reset_timestamp – Timestamp when full daily limit resets
  • is_edd_required – Does the customer need to complete EDD for the next transaction?
  • is_limit_increase_available – Can the customer request a limit increase via EDD?

Step 5: Create a Quotation

After getting the current rate, create a quotation to lock in the rate and receive the wallet address for sending funds.

CRITICAL SECURITY NOTICE:

  • You MUST whitelist the wallet address provided in the quotation response
  • You MUST send funds ONLY through this whitelisted wallet address
  • Funds sent from non-whitelisted addresses or to incorrect addresses WILL BE PERMANENTLY LOST
  • Only use supported asset and network combinations
  • Double-check all details before proceeding
POST /payout/quotation
{
  "asset": "usdt",
  "fiat": "aud",
  "network": "polygon",
  "sending_amount": "100",
  "customer_id": "def8b740-99f9-4cba-bc9e-99de57e927b4",
  "bank_id": "4e6f1b20-a73c-11ec-b909-0242ac120002",
  "risk_parameters": {}
}
{
    "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",
        "network": "POLYGON",
        "fiat": "AUD",
        "sending_amount": 100.00,
        "rate": 1.48,
        "receiving_amount": 148.00,
        "fees": {
          "client_fee": "0.00",
          "client_fee_usdt": "0.00",
          "dollarpe_fee": "0.00",
          "pg_fee": "0.00",
          "gross_exchange_rate": ""
        },
        "wallet_address": "0x2EAf174Bf1CD624eD63e3C8c74Dd66B66e5cb273",
        "created_at": "2025-03-21T13:29:07.828029Z",
        "expiry_time": "2025-03-21T13:39:07.828029Z"
    }
}

Key Fields:

  • asset: Cryptocurrency to be used
  • network: Blockchain network for the transaction
  • fiat: Fiat currency to receive (e.g., "AUD" for Australian Dollar)
  • sending_amount: Amount in cryptocurrency
  • customer_id: ID of the KYC-verified customer
  • wallet_address: Address to send funds to (MUST be whitelisted)
  • expiry_time: Time until the quotation expires

You must complete your transaction before the expiry_time.

Step 6: Send Crypto Assets

Once the order is created, send the crypto assets to the wallet_address returned in the order.

IMPORTANT SAFEGUARDS:

  • You MUST whitelist and use ONLY the wallet address provided in the quotation
  • Send EXACTLY the amount specified in the quotation
  • Ensure you select the CORRECT blockchain network
  • Failure to follow these guidelines will result in PERMANENT LOSS OF FUNDS
  • DO NOT send main-net crypto assets in Sandbox environment. STRICTLY use sepolia test-net for Sandbox testing.

This step happens outside our API, using your preferred cryptocurrency wallet or exchange. Ensure that you:

  1. Double-check that the network matches with what you specified in the quotation
  2. Send the exact amount specified in the sending_amount field of the quotation
  3. Obtain the transaction_hash (txid) after transferring the crypto assets
  4. Verify the transaction is confirmed on the blockchain
  5. Map transaction_hash with the Payout order ID using /payout/update-transaction-hash endpoint

Step 7: Initiate the Payout

After sending the funds, create a payout request with the transaction details:

POST /payout/initiate
{
  "quotation_id": "2e104290-07c8-49f1-a5ca-0d27f0078f8a",
  "customer_id": "def8b740-99f9-4cba-bc9e-99de57e927b4",
  "client_reference_id": "testOrder123",
  "transaction_hash": "0x9b34a0e4897cd834847d8bbb8814eba72149f914785c406884d14f8108bc"
}
{
  "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",
      "network": "POLYGON",
      "fiat": "AUD",
      "rate": 1.48,
      "sending_amount": 100.00,
      "receiving_amount": 148.00,
      "fees": {
          "client_fee": "0.00",
          "client_fee_usdt": "0.00",
          "dollarpe_fee": "0.00",
          "pg_fee": "0.00",
          "gross_exchange_rate": ""
      },
      "wallet_address": "0x2EAf174Bf1CD624eD63e3C8c74Dd66B66e5cb273",
      "transaction_hash": "0x6050598a3a47e74732be49614bafc37fe6babc6aa52bdd1c59455f9285a94e70",
      "cancel_allowed_till": "2025-03-21T13:52:53.208137Z",
      "created_at": "2025-03-21T13:37:53.208137Z",
      "status": "PROCESSING"
  }
}

Key Fields:

  • quotation_id: ID received from Step 2
  • customer_id: ID of the KYC-verified customer
  • client_reference_id: Your internal reference ID for tracking (optional) (e.g. Your order ID)
  • bank_id: ID of the verified bank account
  • transaction_hash: The blockchain transaction ID/hash from Step 3
  • status: Current status of the payout

Passing transaction_hash is optional during this step for some organizations. Kindly contact our team at partnerships@dollarpe.xyz for more details.

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

Step 8: Monitor Transaction Status

After initiating the payout, you need to track its status. There are two ways to monitor this status:

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

// 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",
  "metadata": {}
}

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

Option B: Status Polling

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

GET /payout/{payout_id}
{
  "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",
      "network": "POLYGON",
      "fiat": "AUD",
      "sending_amount": "100.00",
      "rate": "1.48",
      "receiving_amount": "148.00",
      "fees": {
          "client_fee": "0.00",
          "client_fee_usdt": "0.00",
          "dollarpe_fee": "0.00",
          "pg_fee": "0.00",
          "gross_exchange_rate": ""
      },
      "transaction_hash": "0x6050598a3a47e74732be49614bafc37fe6babc6aa52bdd1c59455f9285a94e71",
      "wallet_address": "0x2EAf174Bf1CD624eD63e3C8c74Dd66B66e5cb273",
      "status": "PROCESSING",
      "utr": null,
      "failure_reason": "",
      "cancel_allowed_till": "2025-03-21T13:52:53.208137Z",
      "created_at": "2025-03-21T13:37:53.208137Z",
      "updated_at": "2025-03-21T13:37:53.208142Z"
  }
}

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

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
  • CANCELLED: Payout order has been cancelled

Step 9: Handle completion

Successful Transactions

When a payout is completed successfully:

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

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

Testing Your Integration

Sandbox Environment

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

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

In the sandbox environment, you can simulate different failure scenarios by using specific test values. Refer to our Sandbox Testing Guide for details.

Getting Help

If you encounter any issues with your payout integration:

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.