Docs/Wallets
View Markdown

Customer deposit wallets

Customer wallets give a known customer a reusable deposit address. Relay associates confirmed deposits with your userId, calculates the configured fee, and queues the merchant amount for settlement to the saved organization destination.

Use this model for account funding and repeated deposits. Use a payment intent when each order needs its own amount and lifecycle.

Get or create a wallet#

POST /customer-wallets

The operation is get-or-create for the organization, case-sensitive userId, network, and pinned chain identity. Calling it again returns the existing address, enrolls the requested token if needed, refreshes its saved settlement destination, and renews a two-hour fast-detection window.

Request fields#

FieldTypeRequiredDescription
userIdstringyesYour stable, organization-scoped customer ID. Case-sensitive; 1–128 characters.
networkstringyestron or solana.
tokenstringyesUSDT or USDC, subject to active configuration.
bash
curl --request POST \
  --url https://bridge.relayfinance.io/customer-wallets \
  --header 'Content-Type: application/json' \
  --header 'accesskey: YOUR_ORGANIZATION_API_KEY' \
  --data '{
    "userId": "customer_28491",
    "network": "solana",
    "token": "USDC"
  }'
json
{
  "success": true,
  "data": {
    "id": "cwallet_example",
    "assetId": "cwasset_example",
    "userId": "customer_28491",
    "network": "solana",
    "chainIdentity": "5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp",
    "address": "HkYExampleOwnerAddress",
    "token": "USDC",
    "tokenContract": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
    "tokenAccount": "3pExampleAssociatedTokenAccount",
    "watchUntil": "2026-09-20T14:00:00.000Z",
    "retainedFees": "0.000000",
    "nextFeeSweepAt": "2026-10-01T00:00:00.000Z"
  },
  "meta": {
    "requestId": "7944aed7-cef2-4d8f-b942-3d8e4974f57f"
  }
}

Response fields#

FieldTypeDescription
idstringWallet ID used by the read and history endpoints.
assetIdstringEnrollment ID for this wallet/token pair.
userIdstringExact customer ID supplied by your system.
networkstringWallet network.
chainIdentitystringPinned chain identity used for evidence validation.
addressstringOwner/deposit address.
tokenstringEnrolled token.
tokenContractstringPinned token contract or mint.
tokenAccountstring or nullSolana associated token account; null on TRON.
watchUntilstringEnd of the renewed fast-detection window.
retainedFeesdecimal stringConfirmed, unreserved Relay fees waiting for the scheduled fee sweep.
nextFeeSweepAtstringNext scheduled fee collection date.

Wallet creation requires an active asset, token contract, configured customer-wallet fee policy, and saved settlement destination for the organization. The saved destination cannot be the customer deposit address.

Get a wallet#

GET /customer-wallets/{id}

Returns the wallet and every token enrollment currently attached to it.

json
{
  "success": true,
  "data": {
    "id": "cwallet_example",
    "userId": "customer_28491",
    "network": "solana",
    "address": "HkYExampleOwnerAddress",
    "assets": [
      {
        "assetId": "cwasset_example",
        "token": "USDC",
        "tokenAccount": "3pExampleAssociatedTokenAccount",
        "retainedFees": "0.000000"
      }
    ]
  },
  "meta": {
    "requestId": "946b12aa-7b1f-48b0-8653-ed71936617f6"
  }
}

List deposits#

GET /customer-wallets/{id}/deposits?limit=20&offset=0

Query fieldTypeDefaultLimits
limitinteger201–100
offsetinteger00–1,000,000

The endpoint returns an array in data and pagination details in meta.pagination.

json
{
  "success": true,
  "data": [
    {
      "id": "deposit_example",
      "assetId": "cwasset_example",
      "transactionHash": "5TfExampleSignature",
      "blockTimestamp": "2026-09-20T11:51:04.000Z",
      "amount": "100.000000",
      "fee": "1.000000",
      "merchantAmount": "99.000000",
      "status": "confirmed",
      "createdAt": "2026-09-20T11:51:10.000Z",
      "updatedAt": "2026-09-20T11:51:10.000Z"
    }
  ],
  "meta": {
    "requestId": "57738670-36ad-46ed-8fb2-624ca1d39183",
    "pagination": {
      "total": 1,
      "limit": 20,
      "offset": 0,
      "hasMore": false
    }
  }
}

Deposit status starts as confirmed when it is eligible for settlement, or review_required when Relay cannot safely apply a fee and payout. After the linked merchant transfer is verified, the deposit becomes settled; an uncertain transfer can also move it to review_required.

List transfers#

GET /customer-wallets/{id}/transfers?limit=20&offset=0

Transfer records describe outgoing merchant payouts and periodic Relay fee collections.

FieldTypeDescription
kindstringmerchant or fee.
depositIdstring or nullSource deposit for a merchant transfer.
destinationstringDestination captured when the transfer was queued.
amountdecimal stringExact outgoing amount.
statusstringqueued, submitted, settled, or review_required.
transactionHashstring or nullOn-chain hash after submission.
lastErrorstring or nullSafe operational status for deferred or reviewed work.
nextAttemptAtstringNext scheduled processing or verification time.

One outgoing operation runs at a time per wallet across all enrolled tokens. A review_required transfer blocks later outgoing work until Relay reconciles it; do not attempt to replace or resend the transfer yourself.

Webhook events#

Subscribe to the wallet_event action in the dashboard. Customer-wallet event types are:

  • customer_wallet.deposit_confirmed
  • customer_wallet.deposit_review_required
  • customer_wallet.merchant_settled
  • customer_wallet.merchant_review_required
  • customer_wallet.fee_settled
  • customer_wallet.fee_review_required
  • customer_wallet.transfer_review_required

deposit_confirmed means the incoming funds were credited and a payout was queued. Only merchant_settled proves the outgoing merchant payout was verified on-chain.

Common errors#

HTTPMessageCause
400Asset is unavailableInactive asset, missing contract, or unsupported configuration
400Customer wallet fees are not configured for this assetNo applicable fee policy
400saved settlement errorNo approved settlement destination for the network/token
400Wallet asset contract changed; reconciliation requiredExisting wallet enrollment is pinned to another contract
404Customer wallet not foundThe ID is absent or belongs to another organization
Relay Finance APIServer-to-server financial infrastructure.