Virtual Card Integration Guide (End-to-End)
Introduction
This guide walks you through the entire lifecycle of a virtual card: from 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:
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)
Create a Virtual Card
Issue a card for a customer. For full details, see the Create Card API Reference.
Request
Response
Store the card id — you’ll use it for funding and spend tracking.
Top Up the Card
Fund the card so it can be used. For full details, see the Fund Card API Reference.
Request
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:
Unfreeze:
Terminate:
Card cannot be recovered after termination.
Webhook Summary Card Lifecycle
event | description |
|---|---|
virtualcard.created.complete | Card issued successfully |
virtualcard.created.failed | Card creation failed |
virtualcard.terminated.refund | Remaining balance refunded after card termination |
virtualcard.regularized | Card regularized after compliance or balance adjustment |
virtualcard.expiration | Card has expired |
Top-Up
event | description |
|---|---|
virtualcard.topup.complete | Top-up confirmed |
virtualcard.topup.failed | Top-up failed |
Withdrawal
event | description |
|---|---|
virtualcard.withdrawal.complete | Withdrawal from card completed |
virtualcard.withdrawal.failed | Withdrawal from card failed |
Transactions
event | description |
|---|---|
virtualcard.transaction.debit | Spend confirmed (merchant charge settled) |
virtualcard.transaction.credit | Credit applied to the card |
virtualcard.transaction.authorization | Authorization hold placed by merchant |
virtualcard.transaction.settlement | Merchant settled a previously authorized transaction |
virtualcard.transaction.verification | Zero-amount authorization to verify card is active |
virtualcard.transaction.pre-auth.approved | Pre-authorization approved by the card network |
virtualcard.transaction.reversed | Merchant canceled a pending transaction |
virtualcard.transaction.refund | Refund received from merchant |
virtualcard.transaction.crossborder | Cross-border charge during international use |
virtualcard.transaction.contactless | Contactless (NFC/tap) payment processed |
virtualcard.transaction.terminated.refund | Refund to a terminated card, credited to float |
Declines
event | description |
|---|---|
virtualcard.transaction.declined | Transaction declined |
virtualcard.transaction.declined.charge | Decline rule violation fee charged |
virtualcard.transaction.declined.frozen | Transaction declined because card is frozen |
virtualcard.transaction.declined.terminated | Transaction declined because card is terminated |
virtualcard.transaction.authorization.failed | Authorization attempt failed |
virtualcard.transaction.issuerexpiration | Transaction declined due to issuer expiration |
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