Sign in
Payments and Payouts/Static Wallets

Static Wallets

Permanent deposit addresses tied to a specific order or user, perfect for recurring and long-term payments.

Static wallets are permanent addresses for receiving cryptocurrency payments. They are linked to a specific order_id and are unique by the combination of project_id + order_id + currency + network.

Use static wallets for:

  • Recurring deposits from the same user
  • Long-term payment addresses displayed on a user profile
  • High-volume deposit flows where you want a stable address per user

Create static wallet

POST/v1/static-wallet

Request parameters

FieldTypeRequiredDescription
currencystringyesCryptocurrency (USDT, BTC, ETH, etc.)
networkstringyesNetwork code
order_idstringyesYour order/user ID (up to 255 chars)
labelstringnoWallet label (up to 255 chars)
url_callbackstringyesURL for webhook notifications
invite_codestringnoReferrer code

Request example

JSON
{
  "currency": "USDT",
  "network": "TRX-TRC20",
  "order_id": "USER-123",
  "label": "User deposit #123",
  "url_callback": "https://your-site.com/webhook/static"
}

Response example

JSON
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "label": "User deposit #123",
    "order_id": "USER-123",
    "status": "active",
    "url": "https://go.2328.io/static/019b2265-34d8-7001-a230-8f97de90d481",
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}

Wallet info

Get static wallet information by uuid or address.

POST/v1/static-wallet/info

Request parameters

FieldTypeRequiredDescription
uuidstringyes*Static wallet UUID
addressstringyes*Blockchain wallet address

At least one of uuid or address is required.

Response example

JSON
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "address": "TXYZabc123...",
    "currency": "USDT",
    "network": "TRX-TRC20",
    "status": "active",
    "total_received": "1250.50",
    "transactions_count": 3,
    "created_at": "2026-01-20T12:00:00Z",
    "qr": "data:image/png;base64,iVBORw0..."
  }
}
  • total_received — sum of all deposits received by this wallet, in currency.
  • transactions_count — number of deposits received so far.
  • qr — Base64-encoded QR data URI of the deposit address (always present for static wallets, the address is assigned at creation).

Wallet list

POST/v1/static-wallet/list

Request parameters

FieldTypeRequiredDescription
statusstringnoFilter by status (active, inactive)
currencystringnoFilter by currency
networkstringnoFilter by network
order_idstringnoFilter by order_id
pageintnoPage number (default: 1)
per_pageintnoItems per page (default: 20, max: 100)

Response example

JSON
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "019b2265-...",
        "address": "TXYZabc123...",
        "currency": "USDT",
        "network": "TRX-TRC20",
        "status": "active",
        "total_received": "1250.50",
        "transactions_count": 3
      }
    ],
    "paginate": {
      "count": 1,
      "current_page": 1,
      "per_page": 20,
      "total": 1,
      "total_pages": 1,
      "has_more": false
    }
  }
}

Enable / disable wallet

Toggle whether a static wallet accepts new payments.

POST/v1/static-wallet/disable
POST/v1/static-wallet/enable

Request

Both endpoints take a single parameter:

JSON
{
  "uuid": "019b2265-34d8-7001-a230-8f97de90d481"
}

Response example

JSON
{
  "state": 0,
  "result": {
    "uuid": "019b2265-34d8-7001-a230-8f97de90d481",
    "status": "inactive",
    "message": "Static wallet disabled successfully"
  }
}

For enable, status is "active" and message reads "Static wallet enabled successfully".

Wallet transactions

Get a list of all deposits received by a static wallet.

POST/v1/static-wallet/transactions

Request parameters

FieldTypeRequiredDescription
uuidstringyesStatic wallet UUID
date_fromdatenoStart date (YYYY-MM-DD)
date_todatenoEnd date (YYYY-MM-DD)
pageintnoPage number (default: 1)
per_pageintnoItems per page (default: 15, max: 5000)

Response example

JSON
{
  "state": 0,
  "result": {
    "items": [
      {
        "uuid": "abc123-def456-...",
        "order_id": "USER-123",
        "amount": "100.00",
        "currency": "USDT",
        "payment_status": "paid",
        "txid": "0xabc123def456...",
        "fee_amount": "3.00",
        "net_amount": "97.00",
        "created_at": "2026-01-20T15:30:00Z"
      }
    ],
    "paginate": {
      "count": 1,
      "hasPages": true,
      "perPage": 15,
      "page": 1
    }
  }
}
  • fee_amount — platform fee deducted from this deposit, in currency.
  • net_amount — amount credited to the merchant balance after the fee.

Static wallet webhooks

When a payment is received on a static wallet, the system sends a webhook to url_callback.

The webhook format for static wallets differs from regular payment webhooks. Notably, static wallet webhooks include a merchant_amount field which you should use for crediting.

Webhook payload

JSON
{
  "uuid": "a28b293f-5c76-4053-8062-ae9ca4ab784b",
  "order_id": "USER-7666308594",
  "amount": "10.00000000",
  "currency": "USDT",
  "amount_usd": "10.00000000",
  "exchange_rate": "1.00000000",
  "payer_currency": "USDT",
  "payer_amount": "10.00000000",
  "network": "TRX-TRC20",
  "address": "TMU9Tgpchvgbywkbj5SdC8KJS73t5m3M7G",
  "payment_status": "paid",
  "txid": "8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "tx_explorer_url": "https://tronscan.org/#/transaction/8369ede26a0da05b1bae154b4bb4072eb2453db30ba86b21831902670929454f",
  "payment_amount": "10.00000000",
  "merchant_amount": "9.920000000000000000",
  "created_at": "2026-05-09T16:13:04+03:00",
  "sign": "dd958d1405febce670a9a196e9141784b9f2a5f39cd6d1832d6f3f68d0de1e10"
}

Static wallet webhooks do not include url or expires_at (since the address is permanent, not a session). They do include exchange_rate and created_at.

Field reference

FieldTypeDescription
uuidstringTransaction (invoice) UUID for this deposit
order_idstringYour static wallet order_id
amountdecimal (8 dp)Crypto amount received
currencystringCrypto received (matches the wallet's currency)
amount_usddecimal (8 dp)USD value at the time of receipt
exchange_ratedecimalCrypto / USD rate used
payer_currencystringSame as currency for static wallets
payer_amountdecimal (8 dp)Same as amount for static wallets
networkstringBlockchain network
addressstringStatic wallet address
payment_statusstringCurrent deposit status. Normally paid; AML processing can produce aml_lock, which must not be credited automatically.
txidstringBlockchain transaction hash
tx_explorer_urlstring | nullBlockchain explorer transaction URL. null when txid is absent or the transfer is internal P2P.
payment_amountdecimal (8 dp)Same as amount
merchant_amountdecimal (18 dp)Amount after fee deduction — use this for crediting
created_atstring (ISO 8601)When the deposit was received
signstring (hex)HMAC-SHA256 signature of the payload

Best practices

  • Unique order_id — Use a unique order_id for each user or order
  • Idempotency — Check txid before processing to avoid duplicate credits
  • Verify signatures — ALWAYS verify the sign signature before crediting funds
  • Use merchant_amount — Credit users based on merchant_amount, not payment_amount

Lifecycle and idempotency

A static wallet is a reusable deposit identity, not an invoice. It has no expected amount and no expiry. One address can produce any number of deposit transactions over its lifetime.

Creation is idempotent for the same merchant project, order_id, currency, and network: the existing wallet is returned. Keep that tuple stable and persist the returned wallet uuid; do not use a new order_id every time the same customer opens the deposit screen.

Deposit idempotency is different from wallet idempotency:

  • order_id identifies the reusable wallet/customer mapping;
  • wallet uuid identifies the permanent wallet record;
  • webhook uuid identifies one detected deposit transaction;
  • txid identifies the on-chain transfer and is the primary deduplication key for crediting.

Use a database uniqueness constraint for the processed chain/network/txid identity and claim it in the same transaction that credits the customer's internal balance.

Enable and disable semantics

Disabling a wallet prevents the application from processing it as an active deposit target; it does not erase the address or its history and cannot stop a blockchain transfer already sent by a user.

Never tell users that funds sent to an inactive address are automatically returned. Blockchain transfers are irreversible. Disable only after removing the address from your UI, and keep an operational recovery procedure for late deposits.

Re-enabling preserves the same wallet identity and address. Do not create a replacement merely to change the label; labels are not settlement identifiers.

Static wallet edge cases

SituationCorrect handling
Duplicate creation requestAccept the returned existing wallet and verify its persisted tuple instead of expecting a new address.
Multiple deposits to one addressCreate a separate local deposit row for every transaction uuid/txid; never mark the wallet itself as “paid.”
Duplicate webhookReturn HTTP 200 after finding the already committed txid; never credit again.
Confirmation delay or chain re-observationKeep processing idempotent and reconcile from /v1/static-wallet/transactions.
Deposit below an auto-convert minimumExpect source-currency credit with no completed convert block.
Auto-convert succeedsStore source payment values and the target convert result separately.
Wrong token or wrong networkDo not fabricate a credit. Record evidence and escalate to support/recovery because recoverability is chain-specific.
Memo/tag-based chainDisplay and validate every destination field returned by the platform; an address alone may be insufficient when a memo is required.
AML lockDo not credit the end user until the authoritative status is released through the compliance process.
Wallet disabled after address displayRemove it from the UI immediately, but continue monitoring operational alerts for late transfers.

Reconciliation model

Run a periodic job that pages through /v1/static-wallet/transactions, upserts deposits by txid, and compares their merchant_amount, status, and optional conversion result with your internal ledger. Webhook delivery should make reconciliation fast, but reconciliation must make it complete.