Card Issuing Made Easy: Launch a Virtual Card Programme with ON5
A practical walkthrough of launching a branded virtual card programme on the ON5 Card Network, from first deposit to first issued card, with the API calls involved.
In short
Launching a card programme on ON5 is four decisions and about a dozen API calls: fund the account, pick a card product, set your brand, and issue. This walks through each one, including the parts that are easy to get wrong.
Most guides to "launching a card programme" are really guides to procurement — how to choose a BIN sponsor, what to put in an RFP, how long due diligence takes. This is not that. On ON5 the programme already exists; what follows is how to get your first real card into someone's hands, and which decisions along the way are worth thinking about.
Before you start
Two things need to be true. Your ON5 card account must be activated — a one-time $5,000 in KNCH on the Kaanch Network — and you need a stablecoin balance to load cards from. Once activation is done, start with less than you think you need: $50 issues several test cards at the $5 minimum, which is plenty to see the whole flow work before you commit volume to it.
Step 1: Fund the account
Open the Deposit page and copy your address. It is a single EVM address that works across Ethereum, BNB Smart Chain, Base and Kaanch Network, so the same string is valid whichever chain you send on.
Send USDT or USDC. The network detects the transfer within a scan cycle and emails you; it credits your balance once the transfer reaches the confirmation depth for that chain. Base requires 30 confirmations, BNB Smart Chain 20, Ethereum and Kaanch 12.
Step 2: Choose a card product
A card product decides two things: the network the card runs on — Visa or Mastercard — and the fee charged to issue on it. Products are synced from the card network and priced by ON5, and only priced products appear to you. A product that has not been priced cannot be issued against, which is deliberate: it is better for a product to be invisible than for a card to be issued at an undefined cost.
From the API:
curl https://api-auth.on5.com/api/v1/card-products \
-H "Authorization: Bearer $ON5_API_KEY"
The id you get back is what you pass when creating a card. Omit it and the account default is used — fine for a single-product programme, wrong the moment you offer a choice.
Step 3: Set your brand
This is the step most people skip and then redo. Your brand details are what the cardholder sees, and they are baked into the welcome email at the moment the card is issued.
- Brand name — appears on the card face and as the sender identity in emails.
- Logo — a PNG between 64×64 and 512×512, under 256KB. A transparent background works best against the dark email template.
- Website, support email, WhatsApp — these appear in the email footer. A cardholder with a problem contacts you, not ON5.
Set this before you issue anything real. The welcome email is sent once, at issue, and it carries whatever branding existed at that moment.
Step 4: Issue the card
The call itself is short:
curl -X POST https://api-auth.on5.com/api/v1/cards \
-H "Authorization: Bearer $ON5_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"initialAmount": "50.00",
"cardholderName": "Sam Rivera",
"cardholderEmail": "[email protected]",
"cardProductId": "9a71…",
"cardDesign": "aurora",
"nameOnCard": "SAM RIVERA"
}'
Four things about this request are worth understanding rather than copying.
The idempotency key is not optional
Creating a card moves money. If the connection drops after the request arrives but before the response reaches you, you cannot know whether it succeeded. Retrying with the same Idempotency-Key returns the original result instead of issuing a second card. Generate one key per logical operation — not per attempt — and store it alongside whatever record made you issue the card.
The cardholder email is permanent
cardholderEmail is where this card's welcome message and its 3-D Secure codes are sent, and it is fixed at creation. It deliberately does not follow a later change to the account email, because a card's step-up codes must not be redirectable by editing a profile. Get it right at issue; a wrong address means a card whose purchase verification goes to the wrong inbox.
The card is not ACTIVE yet
The response returns the card in PENDING or CREATING. The network is still provisioning it and there is no card number yet. It becomes ACTIVE shortly after, at which point the details are readable and the cardholder gets their welcome email. Build for this: poll GET /cards, or simply treat "issued" and "usable" as two states in your own model, because they genuinely are.
The design is a real choice
There are 20 designs, and the one you pick is rendered onto the card in the cardholder's welcome email. It costs nothing and it is the only visual your customer gets before the card exists in their wallet app. Pick one that matches your brand rather than taking the default.
Step 5: Top up and manage
A card's balance is topped up from your account balance:
curl -X POST https://api-auth.on5.com/api/v1/cards/CARD_ID/topup \
-H "Authorization: Bearer $ON5_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{"amount": "25.00"}'
Freezing and unfreezing are single calls with no body. Freezing blocks further authorisations and is reversible, which makes it the right response to a suspected problem — you can always unfreeze, and you cannot un-terminate.
What to build on your side
Three things separate a programme that survives contact with users from one that does not.
- Store the ON5 card id against your own user. Everything else — top-ups, freezes, support queries — needs it.
- Record the fee at issue. ON5 snapshots it, but reconciling your books against ON5's is much easier when you kept your own copy.
- Handle the not-yet-active window. A card that is issued but still provisioning is normal, not an error. Showing a user "your card is ready" before it has a number is the most common avoidable support ticket in a new programme.
Rate limits
Reads are limited to 120 requests per minute and card operations to 60, counted per account rather than per key. Adding keys does not add capacity. If you are issuing in bulk, queue the work rather than firing it in parallel — a queue with a modest concurrency is both faster in practice and far easier to reason about when something fails partway.
A realistic timeline
A developer who has read this can get from a funded account to a first issued card in well under an hour. A production integration — with your own ledger entries, retry handling, a support view and the not-yet-active state handled properly — is a few days of work, not a quarter. The long pole in launching a card programme has never been the code; it is the procurement and compliance work that ON5 has already done.
Frequently asked questions
How long does it take to issue a first card on ON5?
From a funded account, a first card can be issued in minutes. A production-quality integration including your own ledger entries and retry handling is typically a few days of engineering work.
Why is my new card not ACTIVE immediately?
The card network provisions the card after accepting the request. It is returned in PENDING or CREATING with no card number yet, and becomes ACTIVE once the network confirms it. The cardholder welcome email is sent at that point, not before.
Do I need an idempotency key to create a card?
Yes. Creating a card and topping one up both require an Idempotency-Key header of 8 to 128 characters. Retrying with the same key returns the original result instead of charging twice.
Can I change the cardholder email after issuing?
No. It is fixed at creation, deliberately, so that a card's 3-D Secure codes cannot be redirected by editing a profile later.
What are the ON5 API rate limits?
Reads are limited to 120 requests per minute and card operations to 60 per minute, counted per account rather than per key.
Issue your first card on ON5
Fund an account with USDT or USDC and issue a branded Visa or Mastercard virtual card. The minimum is $5.
Open the dashboard