Skip to main content

Webhook Event: virtualaccount.completed (USD)

This webhook is sent when a USD virtual account has been successfully credited. This webhook provides details about the funding transaction, including fee breakdown and settlement information.

Payload Example

{
  "event": "virtualaccount.completed",
  "data": {
    "id": "8947fe83-3374-4bbd-a7f6-465481cb4baa",
    "referenceNumber": "AJE318KMPAAJB",
    "amount": "1000",
    "type": "FUNDING",
    "state": "COMPLETED",
    "destination": "USD wallet",
    "narration": "narration",
    "country": "US",
    "currency": "USD",
    "fee": {
      "vat": "10.00",
      "stampDuty": "100.00",
      "base": "10.00"
    },
    "settlementAmount": "880.00",
    "source": {
      "bankName": "Best bank",
      "accountName": "John Sam",
      "accountNumber": "3124458172"
    },
    "customer": {
      "email": "[email protected]",
      "reference": "REF_SXDMSDA13J32",
      "account": {
        "name": "Preston Berge",
        "bankName": "DBS Bank Limited",
        "number": "656633887809",
        "sortCode": "MOOLAHGO"
      }
    },
    "created": "2025-12-02T12:34:46.755211501Z",
    "processed": "2025-12-02T12:34:46.755211501Z"
  }
}
NOTE: For virtualaccount.failed, the state will be "FAILED".

Response Breakdown

Core Transaction Fields

FieldTypeDescription
eventstringThe name of the event that occurred (virtualaccount.completed).
data.idstringUnique identifier for the funding transaction.
data.referenceNumberstringUnique reference number assigned to the transaction.
data.amountstringThe total gross amount of the transaction in USD.
data.typestringThe type of transaction (FUNDING).
data.statestringThe final state of the transaction (COMPLETED or FAILED).
data.destinationstringThe destination wallet where funds are settled (e.g., USD wallet).
data.narrationstringAdditional narration or description for the transaction.
data.countrystringThe country code for the transaction (US).
data.currencystringThe currency of the transaction (USD).

Fee Breakdown

FieldTypeDescription
data.fee.vatstringThe Value Added Tax portion of the fee.
data.fee.stampDutystringThe stamp duty portion of the fee.
data.fee.basestringThe base processing fee for the transaction.
data.settlementAmountstringThe final amount settled after all fees are deducted.
The fee object and settlementAmount are included for transactions with instant settlement enabled.

Source Account (Sender)

FieldTypeDescription
data.source.bankNamestringThe name of the bank that sent the funds.
data.source.accountNamestringThe name on the source bank account.
data.source.accountNumberstringThe account number of the source.

Customer (Virtual Account Holder)

FieldTypeDescription
data.customer.emailstringThe customer’s email address.
data.customer.referencestringThe unique reference for the customer’s virtual account.
data.customer.account.namestringThe name on the virtual account.
data.customer.account.bankNamestringThe partner bank issuing the virtual account.
data.customer.account.numberstringThe virtual account number that was funded.
data.customer.account.sortCodestringThe routing code or SWIFT/BIC code for the virtual account.

Timestamps

FieldTypeDescription
data.createdstringISO 8601 timestamp of when the transaction was created.
data.processedstringISO 8601 timestamp of when the transaction was processed.

Key Differences from NGN Webhook

The USD virtual account webhook includes additional fields:
FieldDescription
destinationSpecifies which wallet receives the settled funds.
narrationContains the payment narration or memo from the sender.
customer.account.sortCodeFor USD accounts, this contains the routing code (e.g., MOOLAHGO).

Handling the Webhook

When you receive this webhook, you should:
  1. Verify the signature – Ensure the webhook is authentic using your webhook secret.
  2. Check the state – Confirm data.state is COMPLETED before crediting the customer.
  3. Match the reference – Use data.customer.reference to identify the virtual account in your system.
  4. Record the transaction – Store the data.id and data.referenceNumber for reconciliation.
  5. Update your records – Credit the expected balance based on data.settlementAmount (net of fees).
For webhook signature verification, see the Webhook Signature Verification guide.