Skip to main content

Overview

Throwaway Auto-Withdraw onramps create short-lived NGN virtual accounts (25-minute TTL) that automatically convert deposits to USDC/USDT and send them to a specified on-chain address.
This is the recommended type for one-time transactions with guaranteed exchange rates.

Use Cases

One-time Purchases

User wants to buy a specific amount of USDC/USDT once

Rate Certainty

User needs a guaranteed exchange rate before transferring

Direct Wallet Payment

User wants funds sent directly to their wallet, not merchant balance

Time-sensitive Transactions

Transactions with strict timing requirements

Characteristics

PropertyValueDescription
TTL25 minutesVirtual account expires after 25 minutes
FX RateLocked to rate_idGuaranteed rate within validity window
VA ReuseNoVA number not reused for 365 days
Rate GuaranteeYesFirm quote honored
SettlementAUTO_WITHDRAWAutomatically sent to specified address
DestinationPer-onrampCan differ for each onramp

FX Behavior

The onramp locks to a specific rate_id at creation:
Deposits arriving after the 25-minute window are flagged and require manual operations review. They do NOT automatically execute at the locked rate.

Settlement Configuration

Requires destination address and chain:
{
  "settlement": {
    "mode": "AUTO_WITHDRAW",
    "asset": "USDC",
    "chain": "BASE",
    "destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
  }
}
Supported chains:
ChainNetworkAsset Support
BASEBase mainnetUSDC, USDT
ETHEthereum mainnetUSDC, USDT
POLYGONPolygon mainnetUSDC, USDT
The destination address is not permanently bound to the VA. Each new onramp can specify a different address, even for the same user.

Creating a Throwaway Auto-Withdraw Onramp

Step 1: Get Rate

curl --request GET \
  --url 'https://api.daya.xyz/v1/rates?from=NGN&to=USDC' \
  --header 'Authorization: Bearer YOUR_API_KEY'
Response:
{
  "rate_id": "rate_8x7k2mq9p",
  "from": "NGN",
  "to": "USDC",
  "rate": 1545.50,
  "expires_at": "2026-01-14T15:35:00Z"
}

Step 2: Create Onramp

curl --request POST \
  --url https://api.daya.xyz/v1/onramp \
  --header 'Authorization: Bearer YOUR_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "type": "THROWAWAY",
    "user": {
      "email": "[email protected]"
    },
    "rate_id": "rate_8x7k2mq9p",
    "settlement": {
      "mode": "AUTO_WITHDRAW",
      "asset": "USDC",
      "chain": "BASE",
      "destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
    }
  }'
Response:
{
  "onramp_id": "onramp_3j5k8n2q",
  "type": "THROWAWAY",
  "status": "ACTIVE",
  "rate_id": "rate_8x7k2mq9p",
  "payment_reference": "DAYA-3J5K8N2Q",
  "virtual_account": {
    "account_number": "9876543210",
    "account_name": "Daya - [email protected]",
    "bank_name": "Wema Bank",
    "bank_code": "035"
  },
  "expires_at": "2026-01-14T15:30:00Z",
  "settlement": {
    "mode": "AUTO_WITHDRAW",
    "asset": "USDC",
    "chain": "BASE",
    "destination_address": "0x742d35Cc6634C0532925a3b844Bc9e7595f0bEb"
  },
  "created_at": "2026-01-14T15:05:12Z"
}

User Experience

Display to users:

Complete Your Payment

Guaranteed rate: 1 USDC = 1545.50 NGN

Transfer NGN to:

Bank:Wema Bank
Account Number:9876543210
Account Name:Daya - [email protected]
Reference:DAYA-3J5K8N2Q

⏰ Complete within 25 minutes

Expires at: 15:30:00

USDC will be sent to: 0x742d…5f0bEb

Show a countdown timer to create urgency. Users must transfer within 25 minutes.

Lifecycle

State changes:
  • ACTIVE: Can receive deposits (within 25-minute window)
  • EXPIRED: TTL elapsed, deposits are flagged
  • DISABLED: Manually disabled before expiry
  • FLAGGED: Risk or compliance issue

Late Deposit Handling

Deposits arriving after expiry are flagged:
ScenarioOutcomeStatusReason
Deposit at 15:20 (before expiry)✅ SuccessSETTLEDWithin validity
Deposit at 15:35 (after expiry)❌ FlaggedFLAGGED"Deposit after onramp expiry"
Deposit at 15:40 (rate expired)❌ FlaggedFLAGGED"Deposit after rate expiry"
Late deposits do not execute at the locked rate. They require manual operations review.

Deposit Flow

Happy path:
1

User transfers NGN

User sends NGN to virtual account within 25 minutes
2

Deposit detected

Status: PENDING_FXWebhook: deposit.created
3

FX executed

NGN converted to USDC at locked rateStatus: PENDING_WITHDRAWAL
4

Risk check

Risk engine evaluates withdrawal (address screening, limits)
5

On-chain broadcast

USDC transaction broadcast to specified chain (e.g., BASE)
6

Settlement

Transaction confirms on-chainStatus: SETTLEDWebhook: deposit.settled
Duration: Typically 2-5 minutes from NGN receipt to on-chain confirmation.

When to Use

  • User needs guaranteed exchange rate
  • One-time transaction
  • User wants funds directly in their wallet
  • Transaction has tight timing
  • Minimal on-chain settlement delay acceptable

Comparison with Other Types

FeatureB1: Auto-WithdrawB2: Merchant BalanceA: Permanent
Expiry25 minutes25 minutesNever
FX RateLockedLockedCurrent rate
SettlementOn-chainMerchant balanceOn-chain
DestinationPer-onrampN/AFixed
Best forOne-time, direct paymentAggregationRecurring

Best Practices

Display remaining time prominently. Users must understand the urgency.
function getTimeRemaining(expiresAt) {
  const total = Date.parse(expiresAt) - Date.parse(new Date());
  const minutes = Math.floor((total / 1000 / 60) % 60);
  const seconds = Math.floor((total / 1000) % 60);
  return { total, minutes, seconds };
}
Verify the address is valid for the specified chain before creating the onramp.
Don’t reuse old rate_id values. Request a new rate immediately before onramp creation.
If user returns after expiry, create a new onramp with a fresh rate.
Display the on-chain transaction hash so users can track their funds on block explorers.

Limits

Subject to standard limits:
  • Per-onramp: Max $1,000 per deposit
  • Per-merchant daily: Max $10,000
  • System-wide daily: Max $100,000
See Limits & Risk for details.

Error Scenarios

Error:
{
  "error": {
    "code": "rate_expired",
    "message": "The specified rate_id has expired"
  }
}
Fix: Request a fresh rate via GET /v1/rates and retry.

Next Steps