ChapaChapa Docs

Deduct from Virtual Account

Debit money from a virtual account to pay for orders, services, or fees.

A Deduction debits money from a Virtual Account, reducing its available balance.

Use deductions to:

  • Pay for orders or services from a wallet balance
  • Move funds into escrow or settlement flows (depending on your product design)
  • Charge fees or subscriptions from stored value
  • Reverse previously credited amounts (if supported by your business logic)

After a successful deduction:

  • The virtual account balance decreases
  • A debit record appears in the account's debit history

Endpoint

POST /v2/virtual-accounts/{virtual_account_id}/deduct
Host: api.chapa.co

Authentication

Headers

NameRequiredDescription
AuthorizationYesBearer <PRIVATE_API_KEY>
Content-TypeYesapplication/json
Idempotency-KeyNoPrevent duplicate deductions on retries

Path Parameter

ParameterRequiredDescription
virtual_account_idYesUnique virtual account identifier

Request Body

Required Fields

FieldTypeDescription
amountnumberAmount to deduct
currencystringCurrency (must match the virtual account currency)

Optional Fields

FieldTypeDescription
merchant_referencestringMerchant-generated reference for the deduction
reasonstringDescription of why the deduction happened
metaobjectCustom metadata (e.g. order_id, customer_id)

Example Request

POST https://api.chapa.co/v2/virtual-accounts/VA_ABC123456/deduct
Authorization: Bearer CHAPA_TEST_xxxxxxxxxxxxx
Content-Type: application/json
{
  "amount": 3000,
  "currency": "ETB",
  "merchant_reference": "DEB_001",
  "reason": "Payment for order ORD_99887",
  "meta": {
    "customer_id": "CUST_12345",
    "order_id": "ORD_99887"
  }
}

Example Response

{
  "status": "success",
  "message": "Deduction completed successfully",
  "data": {
    "virtual_account_id": "VA_ABC123456",
    "debit_reference": "DEB_TRX_123456",
    "amount": 3000,
    "currency": "ETB",
    "balance_before": 12500,
    "balance_after": 9500,
    "created_at": "2025-11-07T13:20:00Z"
  }
}

Response Fields

FieldDescription
virtual_account_idVirtual account debited
debit_referenceUnique debit transaction reference
amountAmount deducted
currencyCurrency deducted
balance_beforeBalance before deduction
balance_afterBalance after deduction
created_atDeduction timestamp

Validation Rules

  • currency must match the virtual account currency
  • amount must be a positive number
  • Account must have sufficient funds
  • merchant_reference should be unique (recommended)

Insufficient Balance Handling

If the account does not have enough balance:

  • Return a clear user-facing message (e.g. "Insufficient wallet balance")
  • Avoid retry loops
  • Optionally suggest topping up (deposit)

Best Practices

  • Use idempotency keys on retries
  • Store debit references for reconciliation
  • Log balance_before / balance_after for auditing
  • Use merchant_reference to prevent duplicate charges
  • Optionally validate balance before calling deduct (still handle race conditions)

Common Errors

HTTPError CodeMeaning
400INVALID_VALUEAmount invalid or currency mismatch
400INSUFFICIENT_BALANCENot enough funds in account
404NOT_FOUNDVirtual account not found
409INVALID_STATEDuplicate reference or idempotency conflict
500PROCESSING_FAILEDDeduction failed due to system error

Next Steps

On this page