Development of a Crypto Card Management System
Note: when a user wants to pay with cryptocurrency at a regular store, a complex chain unfolds: conversion, authorization, settlement—all within 1–2 seconds. We have built more than one such system and know every pitfall: from choosing a card issuing provider to building a real-time webhook handler. This article details the architecture that works in production.
A crypto card is a bridge between on-chain assets and traditional payment infrastructure. The user holds USDC, pays at a regular store—the system converts and deducts in the background. Building this is harder than it seems: it intersects card issuing, real-time conversion, compliance, and blockchain infrastructure. We have implemented such systems for neobank startups and crypto-native platforms, encountering nuances of batch settlement, oracle force majeure, and legal requirements in EU and US jurisdictions. Below are details that saved months of development. If you need such a system, contact us for a consultation.
Card Issuing: Which Provider to Work With
Obtaining a sponsor BIN and issuing cards independently is lengthy and expensive: a partnership with Visa/Mastercard requires a significant deposit and takes 12–18 months. The realistic path is to work through card issuing platforms:
- Marqeta — market leader, programmable cards via Just-in-Time (JIT) Funding. Key feature: with each authorization, Marqeta sends a webhook to your server, you decide to approve or decline, and instantly fund the transaction. Ideal for crypto cards.
- Lithic (formerly Privacy) — similar to Marqeta, often preferred by startups for simpler onboarding.
- Moorwand / Railsr (Europe) — for European cards with IBAN.
- Monavate / Paymentology — alternatives with more flexible terms for crypto-native companies.
All these providers offer REST APIs for issuing cards, managing limits, and retrieving transactions.
The JIT Funding Mechanism
Just-in-Time Funding means the card balance is always zero, and funds appear only at the moment of authorization. For a crypto card, this means: the user authorizes a purchase → the card processor calls your webhook → you convert crypto to fiat → confirm the transaction—all within 1–2 seconds.
Marqeta documentation: "Just-in-Time Funding allows issuers to control each authorization in real time."
Here is a step-by-step processing sequence:
- The card processor (Marqeta, Lithic) sends an HTTP request to your webhook with authorization details.
- The service identifies the user by card_token and checks the available USDC balance via local cache or fast blockchain query.
- If sufficient funds (including a slippage buffer), the system reserves the amount (soft lock) and returns an APPROVE decision.
- After settlement (minutes to hours later), a real conversion of USDC to fiat is triggered via an off-ramp provider.
- The user's balance is updated, and a push notification is sent.
The webhook must respond within 1–2 seconds. Timeout means automatic transaction decline. This strict requirement defines the entire architecture: no synchronous blockchain operations in this path. In one of our projects, we optimized the handler to respond in under 0.8 seconds by introducing a local cache for user balances and using asynchronous reservation cleanup.
interface AuthorizationWebhook {
type: "authorization";
token: string;
card_token: string;
amount: number; // in cents
currency: string; // ISO 4217
merchant: {
descriptor: string;
mcc: string;
country: string;
};
created: string;
}
async function handleAuthorization(
webhook: AuthorizationWebhook
): Promise<AuthorizationResponse> {
// 1. Find user and their crypto balance
const user = await getUserByCardToken(webhook.card_token);
const requiredUsd = webhook.amount / 100;
// 2. Check available USDC balance
const usdcBalance = await getUsdcBalance(user.walletAddress);
if (usdcBalance < requiredUsd * 1.01) { // 1% buffer for slippage
return { decision: "DECLINE", reason: "INSUFFICIENT_FUNDS" };
}
// 3. Reserve funds (soft lock)
const reservation = await reserveFunds(user.id, requiredUsd, webhook.token);
// 4. Confirm authorization
return {
decision: "APPROVE",
amount: webhook.amount,
reservation_id: reservation.id,
};
}
Settlement and Actual Deduction
After authorization comes settlement—the actual movement of funds. This can happen minutes or hours after authorization. Here the real crypto conversion takes place.
async function settleTransaction(settlementData: SettlementEvent): Promise<void> {
const reservation = await getReservation(settlementData.authorization_token);
// For USDC — simply transfer to fiat account via USDC → USD off-ramp
// (Circle, Stripe Crypto, Bridge.xyz)
const offRampResult = await circleOffRamp({
amount: reservation.usdAmount,
destinationBankAccount: OPERATIONAL_ACCOUNT,
});
// Update user balance
await deductUserBalance(reservation.userId, reservation.usdcAmount);
// Send push notification
await sendTransactionNotification(reservation.userId, {
amount: reservation.usdAmount,
merchant: settlementData.merchant.descriptor,
txId: offRampResult.id,
});
}
Conversion: USDC vs Volatile Assets
USDC/USDT is the simplest case. Conversion is trivial due to stablecoin pegging. Most first-generation crypto cards work only with stablecoins.
ETH/BTC and others require a real-time price feed and price risk management. Options:
- Convert to USDC upon card top-up—the user explicitly exchanges ETH → USDC, then everything is as above. The simplest approach.
- Convert at the moment of transaction—higher risk of slippage (typically 0.5–1%) and price gap between authorization and settlement. Requires a hedging strategy.
- Virtual balance + periodic settlement—aggregate transactions, convert in batches. Reduces transaction costs but complicates accounting.
Why the Right Card Issuing Provider Matters
The success of a crypto card directly depends on the provider's ability to handle millions of JIT Funding requests with minimal latency. Marqeta is better for JIT Funding due to more detailed webhook configurations, but Lithic is faster to integrate for startups. For the European market, Moorwand or Railsr with SEPA Instant support. A mistake at this stage leads to transaction declines and loss of user trust.
Ensuring Compliance in Crypto Card Issuance
A crypto card with real usage is a financial product, regulated at least as electronic money. Mandatory components:
- KYC/AML — providers: Sumsub, Persona, Onfido. Integration via REST API + webhook for verification events. Minimum tier: document + selfie. For high limits—Enhanced Due Diligence (EDD). Learn more about KYC and AML.
- Transaction monitoring — analysis of on-chain history of user addresses. Chainalysis API or Elliptic to check: whether funds come from sanctioned addresses, mixers, darknet markets.
- Default limits — until KYC is passed: e.g., as per PSD2 exemption. After verification—standard limits. This is a card scheme requirement, not your invention.
Work Process and Evaluation
We follow a structured process to ensure high-quality delivery:
- Data collection — gather your business requirements, target jurisdictions, and user scenarios.
- Audit and analysis — review existing infrastructure and compliance needs.
- Design — architectural design including provider selection, component diagram, and data flow.
- Estimation — provide a detailed effort and cost estimate based on the design.
- Development — implement the system in iterative sprints.
- Testing — unit, integration, and end-to-end testing, including settlement scenarios.
- Launch — deploy to production with monitoring and support.
Development Timeline
| Stage | MVP | Full Product |
|---|---|---|
| Architecture and stack selection | 2 weeks | 1 month |
| Card issuing integration | 2–3 weeks | 1–2 months |
| Backend (webhook + core) | 2 months | 5–7 months |
| Off-ramp and conversion | 3 weeks | 2–3 months |
| KYC/AML module | 1 month | 2–3 months |
| Testing and audit | 2 weeks | 1–2 months |
| Legal agreements | parallel | 3–6 months |
What's Included in Development
- Architecture design and stack selection tailored to your business model (B2C or B2B).
- Integration with a card issuing provider, JIT Funding setup.
- Backend in Go or Node.js handling webhooks (latency < 1 sec).
- Off-ramp integration (Circle, Bridge.xyz) for USDC → fiat conversion.
- KYC/AML module with Sumsub or Persona support.
- Transaction monitoring, limits, and locking mechanisms.
- API documentation and operations manual.
- Technical support during launch and the first 2 months after release.
We guarantee compliance with card scheme and regulatory requirements. Our experience: 5+ years in crypto service development, from wallets to full neobank solutions.
Typical Mistakes When Integrating JIT Funding
- Synchronous blockchain calls in the webhook — guaranteed timeout.
- No local balance cache — 100ms+ added latency per request.
- Incorrect fee calculation — settlement may fail due to limit breaches.
- Ignoring multi-currency settlements — negative balances can arise during conversion.
Contact us to get an individual assessment of your project. Order the development of a crypto card management system — we'll prepare a proposal in 2 days.







