Learn how to issue virtual and physical cards for your customers using Zentra’s card issuing API. Enable spending, set limits, and manage card lifecycle.
This guide now follows the reviewed public gateway contract. Older SDK examples and older internal docs may still refer to freeze, unfreeze, terminate, or updateLimits. In the reviewed public HTTP contract, those controls map to lock, unlock, and security settings instead.
Sensitive card details are card-program specific. Do not assume PAN/CVV retrieval is part of the default reviewed public gateway unless your approved card program explicitly exposes it.
Geofencing is optional and card-scoped (geofence_enabled: true). When enabled, authorization can auto-decline physical-channel transactions if merchant location and device location are too far apart.
async function fundCard(cardId, amountMinor, source) { // Verify the funding balance in your own app or ledger projection const wallet = await db.wallets.getOrCreate(source.userId); if (wallet.balance_minor < amountMinor) { throw new Error('Insufficient wallet balance'); } // Fund the card const funding = await client.cards.fund({ card_id: cardId, amountMinor, source: 'wallet', transaction_reference: `card_fund_${cardId}_${Date.now()}`, idempotency_key: `FUND_${cardId}_${Date.now()}` }); return funding;}
Use a stable transaction_reference for client retries and reconciliation; keep it unique per logical funding action.
Legacy reference is still accepted for backward compatibility, but it is deprecated for card funding and should be migrated.
The reviewed public gateway does not currently expose a dedicated card termination endpoint. Use lock plus security controls for public contract flows, and coordinate permanent closure through your approved operational path if your card program requires it.
try { const card = await client.cards.create(cardData); return card;} catch (error) { switch (error.code) { case 'insufficient_funds': throw new Error('Not enough balance to fund card'); case 'kyc_required': throw new Error('Customer KYC verification required'); case 'card_limit_reached': throw new Error('Maximum cards per customer reached'); case 'invalid_currency': throw new Error('Currency not supported for card issuing'); default: throw new Error('Card creation failed'); }}