Processing Deposits
This guide covers the recommended workflow for receiving crypto deposits — from address generation to balance confirmation.
Overview
The deposit flow:
- Generate a deposit address for the customer or purpose
- Subscribe to webhooks to receive real-time deposit notifications
- Track confirmations until the deposit is final
- Update your internal ledger based on confirmed balance changes
Address Strategy
Per-Customer Addresses
For payment processing and exchanges, generate a unique address per customer to simplify deposit attribution:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"accountId": "pQ3rS5tU7vW9xY1zAbCdEf",
"network": "ethereum-mainnet",
"name": "customer-12345"
}' \
https://api.carabaas.com/api/v1/addresses
Universal EVM Addresses
Use @eth-like to generate one address that works across all EVM-compatible chains — Ethereum, Polygon, BSC, Arbitrum, Optimism, and more:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"accountId": "pQ3rS5tU7vW9xY1zAbCdEf",
"network": "@eth-like",
"name": "customer-12345-evm"
}' \
https://api.carabaas.com/api/v1/addresses
Memo-Based Deposits
For networks like Cosmos, Stellar, and Ripple, use memos to identify deposits at a shared address:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"addressId": "hN8qR2tVwX4yZ6aBcDeF3g",
"memo": "customer-12345"
}' \
https://api.carabaas.com/api/v1/memos
Pre-Generate Addresses
For high-volume operations, pre-generate a pool of addresses so you can assign them instantly when a customer registers — avoiding real-time API calls during user-facing flows.
Webhook Setup
Subscribe to the incoming stream to get notified about deposits:
curl -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/deposits",
"streams": ["incoming"]
}' \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}
Configure Confirmations
Set the number of blockchain confirmations required before considering a deposit final:
curl -X PUT \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"confirmations": {
"bitcoin-mainnet": 3,
"ethereum-mainnet": 12,
"polygon-mainnet": 30
}
}' \
https://api.carabaas.com/api/v1/subscriptions/{vaultId}/confirmations
Incoming Webhook Payload
Each incoming deposit triggers a confirmation event with full context — you can identify the customer directly from the payload:
{
"stream": "incoming",
"type": "confirmation",
"network": "ethereum-sepolia",
"blockchainHash": "0xc2cc27bdcee3e369a05fe740da898de8b8ace653...",
"vaultId": "cai3GvhueQApTaCcUtjai9",
"transactionId": "d6ZktNHf45cVdHTufyrwU2",
"orderId": "29270015-c058-40be-9303-003502234cf8",
"accountId": "eFjwUQXB8CMnrTHSgYzaL6",
"addressId": "gMP71sR5sNUnGdKFTsNzp6",
"metadata": {
"asn": "0",
"gas": "21000",
"gasUsed": "21000",
"gasPrice": "1200015",
"isContractCall": false
},
"balanceChanges": [
{
"asset": "c1",
"amount": "49999974799685000",
"amountFormatted": {
"asset": {
"name": "ETH Sepolia",
"decimals": 18,
"type": "native",
"network": "ethereum-sepolia"
},
"value": "0.049999974799685"
},
"address": {
"id": "gMP71sR5sNUnGdKFTsNzp6",
"networkAddress": "0xF3fC7B157615c5eD88f87d05f24C4C8E0c8D6A42",
"network": "@eth-like",
"hdpath": "m/44/60/0/0/1",
"name": "customer-12345",
"data": { "mid": "cust-12345" }
},
"account": {
"id": "eFjwUQXB8CMnrTHSgYzaL6",
"name": "deposits",
"data": {}
}
}
],
"confirmations": 1
}
Key fields for deposit attribution:
| Field | Use |
|---|---|
address.name | Match to customer by address name |
address.data | Custom metadata you set on the address |
address.memo | Memo value (for Stellar, Ripple, Cosmos) |
account.name | Account the address belongs to |
balanceChanges[].asset | Which asset was deposited |
amountFormatted.value | Human-readable deposit amount |
confirmations | Current confirmation count |
blockchainHash | On-chain transaction reference |
Balance Validation
After receiving a deposit notification, validate the balance before crediting the customer:
curl -H "Authorization: Bearer $TOKEN" \
https://api.carabaas.com/api/v1/addresses/{addressId}
Always validate balances against the blockchain state before crediting users. Do not rely solely on webhook notifications — use them as triggers, then verify via the API.
Internal Ledger
Maintain an internal ledger that records:
- Deposit event — customer ID, address, amount, asset, network, blockchain hash
- Confirmation count — track until your threshold is met
- Credit event — when the customer's balance is updated in your system
The platform provides the data; your application maintains the ledger.
Vault Structure for Deposits
| Pattern | Description |
|---|---|
| Single deposit vault | One vault with accounts per customer segment |
| Per-customer accounts | One account per customer inside a shared vault |
| Per-customer addresses | Multiple addresses per customer inside their account |