Module 5: Funding Virtual Cards

🧠 Learning Objectives

By the end of this module, you’ll be able to:

Understand how prepaid virtual card funding works

Know what assets can be used to fund cards

Learn how to combine card registration, issuance, and funding into one clean flow

Handle common edge cases (errors, fees, FX behavior)


What Does “Funding a Virtual Card” Mean?

Funding is the act of preloading money onto a virtual card. Since virtual cards are prepaid by design, they must be funded before use.

Think of it like putting money into a secure digital envelope that only works on the internet.

The money typically comes from:

A fiat wallet (NGN, GHS, ZAR, etc.)

A stablecoin balance (e.g. USDT)

A treasury float controlled by your platform


How Funding Works (Conceptually)

Here’s the typical flow:

Funding Flow

Supported Funding Assets

asset type
examples
auto-converted to
Stablecoins
USDT (TRC20 /ERC20 ), USDC
USD
Bitcoin
BTC
USD

Most virtual card systems (including Bitnob) handle automatic FX conversion. You don’t need to fund cards in native USD — it’s abstracted behind the scenes.


Top-Up Rules and Limits

rule
value (example)
Minimum top-up
$3
Maximum per top-up
$2,500
Maximum card balance
$50,000
Flat top-up fee
$1 (per up to $100)
FX markup (if applicable)
Varies per platform

These limits help control risk and fraud. They’re also adjustable based on business model.


Full Flow: Register → Issue → Fund

Let’s now walk through the combined MVP flow:

Step 1: Register the Card User

Endpoint
Request Body

➡ Store the returned card_user_id.

Step 2: Create a Card for the User

Endpoint
Request Body

➡ You’ll receive card metadata (card ID, masked PAN, expiry, etc.) ➡ Store cardId securely.

🔹 Step 3: Fund the Card

Endpoint
Request Body

➡ Response includes status, exchange rate, new card balance.


What to Show the User

step
ux element
Register
No UI shown — background action
Create
Show virtual card details (one time only)
Fund
Show balance immediately, with success banner
Failed Top-Up
Display failure reason (e.g. insufficient wallet balance) and retry CTA

Common Funding Errors

error
reason
insufficient_funds
Wallet doesn’t have enough to cover top-up + fees
card_not_active
You tried funding a frozen or terminated card
invalid_card_id
The cardId doesn’t exist or doesn’t belong to your account
rate_expired
Market price changed; retry with a fresh quote (if rate locking used)

Funding Use Cases

use case
pattern
User-triggered top-up
Let users tap “Add Funds” manually in UI
Auto-fund after payout
When user receives crypto or fiat payment, auto-top-up a card
Budgeted card issuance
Top-up the card with $200 monthly allowance
Pay-as-you-spend
Top-up in real time based on transaction attempt (advanced)

Best Practices

practice
why
Show current card balance in UI
Helps users understand availability before spending
Validate card status before funding
Prevent wasteful operations and stuck funds
Show fee breakdown and FX conversion
Builds transparency and trust
Always log top-up reference IDs
Helps with reconciliation and dispute handling
Use webhooks to confirm top-up success
Never assume success from just a `200` response

Recap Exercise

You're building an app that gives each new user a $50 shopping card after KYC.

Sketch out your backend flow in pseudocode or sequence:

1

Register user

2

Issue card

3

Fund with $50 from marketing wallet

4

Display card

5

Listen to virtualcard.topup.success webhook

This is your basic card distribution engine.


Key Takeaways

Virtual cards must be funded before use, they’re not credit-based

Most systems support funding from crypto, fiat, or wallet balances

You can combine registration, issuance, and top-up into a smooth experience

Design your UI and backend to show status clearly, handle errors, and listen to webhooks


Share on
Share on FacebookShare on XShare on LinkedIn
Did you find this page useful?