virtual_account.funded event directly to the Vouch backend. Vouch validates the signature, reconciles the payment, and advances the escrow state machine automatically — no polling or manual confirmation needed from your integration.
How It Works
Signature Verification
Every incoming Nomba request is signed with HMAC-SHA256 over the raw request body, delivered in thenomba-signature header. Vouch verifies this before processing any event — requests with a missing or mismatched signature are rejected with 401.
The signature is computed over the raw request bytes. The Vouch backend applies
express.raw() middleware to this route to prevent JSON parsing from modifying the body before the signature check.Supported Event Types
Partial Payments
If a buyer sends multiple transfers that collectively equal the agreed amount, Vouch handles it automatically. Eachvirtual_account.funded event increments the running amountReceived total:
Your integration only needs to watch for
FUNDED before allowing work to begin. You do not need to track individual transfers.
Overpayment Handling
When the accumulatedamountReceived exceeds totalAmount by more than 1%, Vouch:
- Sets the agreement to
OVERFUNDED - Calculates
excess = amountReceived - totalAmount - Reads the sender’s bank details from the webhook payload
- Immediately calls the Nomba transfer API to refund the excess to the original sender
- Logs the outcome in your developer audit log as
OVERPAYMENT_FLAGGED
Automatic refunds require the sender’s account number and bank code to be present in the Nomba webhook payload. If these details are missing, the refund is skipped and logged with a reason — you can handle it manually from the developer dashboard.
Idempotency
Every Nomba event carries a uniquerequestId. Vouch stores this as nombaReference on the transfer record, which has a database-level unique constraint. If Nomba retries a delivery (common in production), the duplicate is detected and silently dropped — the agreement is never double-credited.
Developer Audit Log Events
Every reconciliation writes a structured entry to your developer log, visible in the dashboard:Polling as a Fallback
If you need to check agreement status from your frontend or in a background job, usevouch.escrow.status() at any time: