Virtual Card Integration Guide (End-to-End)
Introduction
This guide walks you through the entire lifecycle of a virtual card: from user registration to card issuance, funding, spending, and handling webhook events.
It’s designed to help developers build a working card implementation quickly, using only essential endpoints and best practices.
What You’ll Build
A complete card experience:
Register a user
Create a virtual card
Top up the card
Handle a transaction
Process a refund or reversal
Freeze, unfreeze, or terminate the card
Listen for real-time webhooks
Prerequisites
Your API key
Webhook endpoint set up and reachable
Understanding of your wallet or funding flow (e.g., float, stablecoin)
Register the Card User
All cards must be tied to a registered card user.
Request
Response
➡️ Store card_user_id
— you’ll need it to create cards and fetch transactions.
Create a Virtual Card
Now issue a card for the user.
Request
Response
➡️ Store cardId
— you’ll use it for top-ups and spend tracking.
Top Up the Card
Fund the card so it can be used.
Response
At this point, the card is ready for use.
Handle Card Spend
Once the user uses the card (e.g., Netflix, Spotify), you’ll get a webhook.
Webhook: virtualcard.transaction.debit
➡️ Use this to update user transaction history and deduct from UI balance.
Handle Refunds and Reversals
Sometimes merchants reverse or refund charges.
Webhook: virtualcard.transaction.refund
Webhook: virtualcard.transaction.reversed
Freeze, Unfreeze, or Terminate the Card
Freeze:
POST /api/v1/virtualcards/freeze
Unfreeze:
POST /api/v1/virtualcards/unfreeze
Terminate:
POST /api/v1/virtualcards/terminate
➡️ Card cannot be recovered after termination.
Webhook Summary
Event | Use |
---|---|
virtualcard.created.success | Card issued |
virtualcard.topup.success | Top-up confirmed |
virtualcard.transaction.debit | Spend confirmed |
virtualcard.transaction.refund | Refund received |
virtualcard.transaction.reversed | Pre-auth or silent transaction reversed |
virtualcard.transaction.declined | Spend failed |
virtualcard.transaction.declined.terminated | Card terminated after too many fails |
virtualcard.transaction.terminated.refund | Refund to closed card, credited to float |
Developer Notes
Use idempotency keys for top-ups and card creation
Always verify webhook signatures (see webhook doc)
Track card status in your database (active, frozen, terminated)
Do not store CVV post-creation
Display maskedPan only after user authentication