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 TypeExamplesAuto-Converted to
StablecoinsUSDT (TRC20/ERC20), USDCUSD
BitcoinBTCUSD

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

RuleValue (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

POST /virtualcards/registercarduser

Request Body

➡ Store the returned card_user_id.

Step 2: Create a Card for the User

POST /virtualcards/createcard

Request Body

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

🔹 Step 3: Fund the Card

POST /virtualcards/topup

Request Body

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

What to Show the User

StepUX Element
RegisterNo UI shown — background action
CreateShow virtual card details (one time only)
FundShow balance immediately, with success banner
Failed Top-UpDisplay failure reason (e.g. insufficient wallet balance) and retry CTA

Common Funding Errors

ErrorReason
insufficient_fundsWallet doesn’t have enough to cover top-up + fees
card_not_activeYou tried funding a frozen or terminated card
invalid_card_idThe cardId doesn’t exist or doesn’t belong to your account
rate_expiredMarket price changed; retry with a fresh quote (if rate locking used)

Funding Use Cases

Use CasePattern
User-triggered top-upLet users tap “Add Funds” manually in UI
Auto-fund after payoutWhen user receives crypto or fiat payment, auto-top-up a card
Budgeted card issuanceTop-up the card with $200 monthly allowance
Pay-as-you-spendTop-up in real time based on transaction attempt (advanced)

Best Practices

PracticeWhy
Show current card balance in UIHelps users understand availability before spending
Validate card status before fundingPrevent wasteful operations and stuck funds
Show fee breakdown and FX conversionBuilds transparency and trust
Always log top-up reference IDsHelps with reconciliation and dispute handling
Use webhooks to confirm top-up successNever 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