Webhooks
Introduction
Bitnob emits real-time webhook events that inform your system of all important activities and lifecycle events related to your virtual cards.
Each webhook provides structured data about:
Transaction outcomes (approved, failed, reversed, refunded),
Card lifecycle changes (created, terminated, frozen),
Operational risk events (failed authorizations, fraud flags, cross-border activity).
Webhooks are delivered to your registered callback URL via HTTPS POST requests.
Webhook Structure
All webhook payloads follow the same top-level format:
Webhook Categories
Category | Description |
---|---|
Card Lifecycle | When a card is created, fails to create, or is terminated |
Top-Ups & Withdrawals | When a card is loaded or funds are withdrawn |
Transaction Activity | Purchases, refunds, declines, reversals, authorization failures |
Risk Events | Automated freezes, terminations, MCC restrictions, cross-border use |
Refunds on Terminated Cards | Handling of funds after a card is closed |
Card Lifecycle Webhooks
virtualcard.created.success
Fired when a virtual card is successfully created.
virtualcard.created.failed
Fired when card creation fails.
Card Funding Webhooks
virtualcard.topup.success
Card top-up (load funds) succeeded.
virtualcard.topup.failed
Top-up failed (e.g. insufficient balance, card status invalid).
Card Withdrawal Webhooks
virtualcard.withdrawal.success
A successful withdrawal was made (if enabled).
virtualcard.withdrawal.failed
Withdrawal attempt failed (e.g. below minimum balance, card status invalid).
Transaction Webhooks
virtualcard.transaction.debit
Successful spend or purchase transaction.
virtualcard.transaction.reversed
An authorized transaction was reversed (merchant canceled before settlement).
virtualcard.transaction.refund
Merchant refund after settlement.
Charge related to cross-border transaction applied to the card.
virtualcard.transaction.authorization.failed
Authorization attempt failed due to insufficient funds or card configuration.
Declines & Risk Event Webhooks
virtualcard.transaction.declined
A purchase attempt was declined.
virtualcard.transaction.declined.frozen
Transaction declined due to card being frozen, usually from a fraud rule.
virtualcard.transaction.declined.terminated
Card was auto-terminated after repeated failed attempts (see risk rules in status management).
Refunds After Termination
virtualcard.transaction.terminated.refund
Refund processed for a card that was already terminated. Funds returned to the float or master account.
Best Practices for Handling Webhooks
Practice | Why It Matters |
---|---|
Acknowledge with HTTP 200 | Prevent retries and duplication |
Log and verify every event | Enables reconciliation and debugging |
Use event type (event ) to route logic | Cleanly separate card creation, spend, and risk events |
Secure your webhook endpoint | Use HMAC signature verification (Bitnob will provide guide) |
Make it idempotent | Replaying the same webhook shouldn’t create duplicate logic |
Virtual Card Webhooks – Reference Table
Event Name | Category | Description |
---|---|---|
virtualcard.created.success | Card Lifecycle | Card was successfully created and is now active. |
virtualcard.created.failed | Card Lifecycle | Card creation failed. Check reason in payload. |
virtualcard.topup.success | Top-Up | Card was funded successfully from float/wallet. |
virtualcard.topup.failed | Top-Up | Card funding attempt failed. |
virtualcard.withdrawal.success | Withdrawal | Cash withdrawal from card succeeded (if supported). |
virtualcard.withdrawal.failed | Withdrawal | Withdrawal failed (e.g. limit, balance, status). |
virtualcard.transaction.debit | Transaction | A purchase or spend was successful. |
virtualcard.transaction.reversed | Transaction | An authorized transaction was canceled by the merchant. |
virtualcard.transaction.refund | Transaction | Merchant refunded a completed transaction. |
virtualcard.transaction.crossborder | Fee/Charge | Cross-border charge occurred during international use. |
virtualcard.transaction.authorization.failed | Transaction | Authorization request failed (e.g. insufficient funds). |
virtualcard.transaction.declined | Decline | Transaction declined (generic failure reason provided). |
virtualcard.transaction.declined.frozen | Risk | Card was frozen due to flagged activity (fraud rule). |
virtualcard.transaction.declined.terminated | Risk | Card was auto-terminated due to multiple failed attempts. |
virtualcard.transaction.terminated.refund | Refund | A terminated card received a refund. Funds returned to float. |
Next Steps
You can test webhook delivery via the Bitnob API or by manually triggering test events from your dashboard.
Subscribe to sandbox events first to validate your implementation.
For production use, make sure to log all failed deliveries and monitor retry queues.