Initiating a Withdrawal

This guide explains how to initiate stablecoins withdrawals from a customer's DDA to external wallets.

Overview

Withdrawal transactions enable customers to:

  • Send stablecoins to personal wallets
  • Send stablecoins to other known wallets

On Omnia's end, the withdrawal process includes:

  • Balance verification
  • Compliance screening
  • Transaction limit checks
  • Fraud monitoring
  • Blockchain transaction creation

Prerequisites

  • Active blockchain account with sufficient balance in the customer's bank acount
  • Registered destination counterparty (recommended for higher limits)
  • Valid api key

Step 1: Register Destination

You must first set up the counterparty before sending funds. If this step has already been completed, you do not need to repeat it.

POST /counterparties
Authorization: Bearer {your-api-key}
Content-Type: application/json

{
  "address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
  "network": "solana"
}

See Registering and Linking a Verified 1st Party Wallet for complete verification steps.

Step 2: Initiate the Withdrawal

POST /blockchain-accounts/{blockchain-account-id}/withdrawals
Authorization: Bearer {your-token-key}
Content-Type: application/json

{
  "amount": "500.00",
  "currency": {
    "type": "stablecoin-currency",
    "symbol": "USDC",
    "network": "solana"
  },
  "destinationId": "CPT_01BX5ZZKBKACTAV9WEVGEMMVS1"
}

Request Parameters

ParameterTypeRequiredDescription
amountstringYesAmount to withdraw (decimal string)
currencyobjectYesCurrency to withdraw (stablecoin or deposit token)
destinationIdstringYesID of the destination counterparty

Currency Options

Stablecoin Withdrawal

{
  "type": "stablecoin-currency",
  "symbol": "USDC",
  "network": "solana"
}

Deposit Token Withdrawal

{
  "type": "deposit-token-currency",
  "id": "DPT_01BX5ZZKBKACTAV9WEVGEMMVS1"
}

Example Response

{
  "type": "withdrawal-transaction",
  "id": "TXN_01BX5ZZKBKACTAV9WEVGEMMVS1",
  "created": "2024-03-15T14:30:00Z",
  "updated": "2024-03-15T14:30:00Z",
  "amount": "500.00",
  "currency": {
    "type": "stablecoin-currency",
    "symbol": "USDC",
    "network": "solana"
  },
  "status": "pending",
  "source": {
    "type": "blockchain-account",
    "id": "BCA_01BX5ZZKBKACTAV9WEVGEMMVS1"
  },
  "destination": {
    "type": "verified-counterparty-1P",
    "id": "CPT_01BX5ZZKBKACTAV9WEVGEMMVS1",
    "address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM"
  }
}

Transaction Status Flow

  1. pending - Withdrawal is being processed and verified
  2. completed - Withdrawal successful, funds sent to destination
  3. failed - Withdrawal failed due to compliance, limits, or technical issues

Step 4: Monitor Transaction Progress

Track your withdrawal status:

GET /transactions/{transaction-id}
Authorization: Bearer {your-api-key}

Transaction Limits

Withdrawals are subject to configured limits based on:

Counterparty Type

Verified 1P Wallets (Highest Limits)

{
  "type": "withdrawal-transaction-limit",
  "interval": "daily",
  "amount": "100000.00",
  "currency": {
    "type": "stablecoin-currency",
    "symbol": "USDC",
    "network": "solana"
  },
  "allowedDestinations": ["verified_1p_wallets"]
}

Exchange Wallets (2P)

{
  "type": "withdrawal-transaction-limit",
  "interval": "daily",
  "amount": "50000.00",
  "currency": {
    "type": "stablecoin-currency",
    "symbol": "USDC",
    "network": "solana"
  },
  "allowedDestinations": ["exchange_wallets"]
}

Unknown Wallets (Lower Limits)

{
  "type": "withdrawal-transaction-limit",
  "interval": "single-transaction",
  "amount": "1000.00",
  "currency": {
    "type": "stablecoin-currency",
    "symbol": "USDC",
    "network": "solana"
  }
}

Compliance and Security

Automated Checks

The system performs several verification steps:

AML Screening

  • Sanctions list verification
  • PEP (Politically Exposed Person) checks
  • High-risk jurisdiction screening
  • Transaction pattern analysis

Fraud Detection

  • Velocity checks (unusual withdrawal patterns)
  • Behavioral analytics

Risk Scoring

  • Counterparty risk assessment
  • Transaction amount evaluation
  • Timing pattern analysis
  • Account history review

Manual Review Triggers

Withdrawals may require manual review for:

  • First-time large withdrawals
  • Transactions to high-risk jurisdictions
  • Unusual velocity patterns
  • Suspicious counterparty addresses
  • Amounts exceeding automated limits

Error Handling

Insufficient Balance (400)

{
  "error": "INSUFFICIENT_BALANCE",
  "message": "Account balance insufficient for withdrawal",
  "details": {
    "available": "250.00",
    "requested": "500.00",
    "currency": "USDC"
  }
}

Limit Exceeded (400)

{
  "error": "WITHDRAWAL_LIMIT_EXCEEDED",
  "message": "Daily withdrawal limit exceeded",
  "details": {
    "dailyLimit": "10000.00",
    "alreadyWithdrawn": "8000.00",
    "requestedAmount": "3000.00",
    "availableToday": "2000.00"
  }
}

Compliance Hold (400)

{
  "error": "COMPLIANCE_HOLD",
  "message": "Withdrawal held for compliance review",
  "details": {
    "holdReason": "AML_SCREENING",
    "estimatedReviewTime": "24-48 hours",
    "referenceNumber": "CR_123456"
  }
}

Unknown Destination (400)

{
  "error": "UNKNOWN_DESTINATION",
  "message": "Destination counterparty not found",
  "details": {
    "destinationId": "CP_unknown",
    "suggestion": "Register counterparty first or verify address"
  }
}

Best Practices

Security

  1. Verify addresses - Double-check destination addresses
  2. Enable 2FA - Add extra security when available

Integration Examples

React Component

const WithdrawForm = () => {
  const [amount, setAmount] = useState('');
  const [destinationId, setDestinationId] = useState('');

  const handleWithdraw = async () => {
    try {
      const response = await fetch(`/blockchain-accounts/${accountId}/withdrawals`, {
        method: 'POST',
        headers: {
          'Authorization': `Bearer ${token}`,
          'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          amount,
          currency: {
            type: 'stablecoin-currency',
            symbol: 'USDC',
            network: 'solana',
          },
          destinationId,
        }),
      });

      const withdrawal = await response.json();
      console.log('Withdrawal initiated:', withdrawal.id);
    } catch (error) {
      console.error('Withdrawal failed:', error);
    }
  };

  return (
    <form onSubmit={handleWithdraw}>
      <input
        value={amount}
        onChange={(e) => setAmount(e.target.value)}
        placeholder="Amount to withdraw"
      />
      <select value={destinationId} onChange={(e) => setDestinationId(e.target.value)}>
        <option value="">Select destination...</option>
        {verifiedWallets.map((wallet) => (
          <option key={wallet.id} value={wallet.id}>
            {wallet.address}
          </option>
        ))}
      </select>
      <button type="submit">Withdraw</button>
    </form>
  );
};

API Reference

  • Initiate Withdrawal: POST /blockchain-accounts/{id}/withdrawals
  • Check Status: GET /transactions/{id}
  • List Withdrawals: GET /transactions?type=WithdrawalTransaction
  • Get Limits: GET /blockchain-accounts/{id}/transaction-limits
  • Verify Counterparty: POST /blockchain-accounts/{id}/counterparties

Next Steps

After successful withdrawals:

  1. Monitor settlement on the destination blockchain
  2. Review limits and adjust as needed for operational efficiency

Did this page help you?