Deposit to Virtual Account
Credit money into a virtual account to increase its available balance.
A Deposit credits money into a Virtual Account, increasing its available balance.
Use deposits to:
- Fund customer wallets
- Top up balances
- Load escrow accounts
- Record offline or online funding events (depending on your product flow)
After a successful deposit:
- The virtual account balance increases
- A credit record appears in the account's credit history
Endpoint
POST /v2/virtual-accounts/{virtual_account_id}/deposit
Host: api.chapa.coAuthentication
Headers
| Name | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <PRIVATE_API_KEY> |
Content-Type | Yes | application/json |
Idempotency-Key | No | Prevents duplicate deposits on retries |
Path Parameter
| Parameter | Required | Description |
|---|---|---|
virtual_account_id | Yes | Unique virtual account identifier |
Request Body
Required Fields
| Field | Type | Description |
|---|---|---|
amount | number | Amount to deposit |
currency | string | Currency (must match the virtual account currency) |
Optional Fields
| Field | Type | Description |
|---|---|---|
merchant_reference | string | Merchant-generated reference for the deposit |
reason | string | Description of why the deposit happened |
meta | object | Custom metadata (order_id, customer_id, etc.) |
Example Request
Example Request
JSON
{
"amount": 5000,
"currency": "ETB",
"merchant_reference": "DEP_001",
"reason": "Wallet top-up",
"meta": {
"customer_id": "CUST_12345",
"order_id": "ORD_99887"
}
}cURL
curl -X POST https://api.chapa.co/v2/virtual-accounts/VA_ABC123456/deposit \
-H "Authorization: Bearer CHAPA_TEST_xxxxxxxxxxxxx"
-H "Content-Type: application/json" \
-d '{
"amount": 5000,
"currency": "ETB",
"merchant_reference": "DEP_001",
"reason": "Wallet top-up",
"meta": {
"customer_id": "CUST_12345",
"order_id": "ORD_99887"
}
}'JavaScript
const response = await fetch("https://api.chapa.co/v2/virtual-accounts/VA_ABC123456/deposit", {
method: "POST",
headers: {
"Authorization": "Bearer CHAPA_TEST_xxxxxxxxxxxxx",
"Content-Type": "application/json"
},
body: JSON.stringify({
"amount": 5000,
"currency": "ETB",
"merchant_reference": "DEP_001",
"reason": "Wallet top-up",
"meta": {
"customer_id": "CUST_12345",
"order_id": "ORD_99887"
}
})
});
const data = await response.json();
console.log(data);Example Response
{
"status": "success",
"message": "Deposit completed successfully",
"data": {
"virtual_account_id": "VA_ABC123456",
"deposit_reference": "DEP_TRX_987654",
"amount": 5000,
"currency": "ETB",
"balance_before": 7500,
"balance_after": 12500,
"created_at": "2025-11-07T13:10:00Z"
}
}Response Fields
| Field | Type | Description |
|---|---|---|
virtual_account_id | string | Virtual account credited |
deposit_reference | string | Unique deposit transaction reference |
amount | number | Amount deposited |
currency | string | Currency deposited |
balance_before | number | Balance before deposit |
balance_after | number | Balance after deposit |
created_at | string | Deposit timestamp |
Validation Rules
currencymust match the virtual account's currencyamountmust be positivemerchant_referenceshould be unique (recommended)
Best Practices
- Use an
Idempotency-Keyon retries - Store
deposit_referencefor reconciliation - Store
balance_beforeandbalance_afterfor audit trails - Use
metato link deposits to internal records (order_id,customer_id)
Common Errors
| HTTP | Error Code | Description |
|---|---|---|
| 400 | INVALID_VALUE | Amount must be positive |
| 400 | INVALID_VALUE | Currency mismatch |
| 404 | NOT_FOUND | Virtual account not found |
| 409 | DUPLICATE_REQUEST | Duplicate idempotency key |
| 500 | PROCESSING_FAILED | Failed to process deposit |
Next Steps
- Get Virtual Account - Check account balance
- Deduct from Virtual Account - Withdraw funds
- Credit History - View deposit history