Skip to main content

State Diagram

Transaction States

StatusDescriptionNext States
deposit_pendingWaiting for depositdeposit_detected, cancelled, expired
deposit_detectedDeposit seen on-chaindeposit_confirmed
deposit_confirmedRequired confirmations metpayout_processing
payout_processingBank transfer in progresscompleted, payout_failed
completedPayout successful-
payout_failedBank transfer failedpayout_processing, manual_review
cancelledTransaction cancelled-
expiredQuote expired-

Webhooks by State

Each state transition triggers a webhook:
// deposit_pending → deposit_detected
{
  "event": "transaction.deposit_detected",
  "data": {
    "transactionId": "txn_xyz",
    "deposit": {
      "txHash": "0x...",
      "amount": "100",
      "confirmations": 1
    }
  }
}

// deposit_detected → deposit_confirmed
{
  "event": "transaction.deposit_confirmed",
  "data": {
    "transactionId": "txn_xyz",
    "deposit": {
      "confirmations": 30
    }
  }
}

// payout_processing → completed
{
  "event": "transaction.payout_completed",
  "data": {
    "transactionId": "txn_xyz",
    "payout": {
      "amount": "8407.75",
      "utr": "123456789012"
    }
  }
}

Confirmation Requirements

NetworkConfirmationsTypical Time
Polygon30~1 minute
Ethereum12~3 minutes
Arbitrum20~30 seconds
Base20~30 seconds
SolanaFinalized~15 seconds

Payout Requirements

Before a payout can be initiated, the system verifies:
RequirementCheck
KYC StatusMust be verified
KYC LevelMust be basic or enhanced
Bank AccountMust exist and be verified
KYC is checked both at transaction creation AND at payout time. This ensures payouts only go to fully verified users.

Payout Retries

If a payout fails:
  1. Auto-retry: System retries up to 3 times with exponential backoff
  2. Manual review: After 3 failures, transaction goes to manual review
  3. Resolution: Support team investigates and processes manually
Common payout failures:
  • KYC not verified (KYC_NOT_VERIFIED)
  • KYC level insufficient (KYC_LEVEL_INSUFFICIENT)
  • Invalid bank account (BANK_ACCOUNT_INVALID)
  • Bank maintenance window
  • Account frozen/closed

Quote Expiration

Transactions must receive deposits within 24 hours:
  • After 24h, quote expires and transaction moves to expired
  • User must create a new transaction for a fresh quote
  • Exchange rate may differ from original quote

Polling vs Webhooks

We recommend webhooks for real-time updates, but you can also poll:
# Poll transaction status
curl https://api.stablepay.global/v2/transactions/{transactionId} \
  -H "Authorization: Bearer YOUR_API_KEY"
Rate limit: 100 requests/minute. Use webhooks for high-volume integrations.