Issue virtual Visa cards backed by stablecoin collateral, with support for Google Wallet and 3DS.
This guide covers the full lifecycle of a virtual card: from issuance and funding, through per-card configuration and spending controls, to fraud protection and transaction visibility. All operations are available both via the API (API key auth) and the CryptoMate Portal.
Cards is a virtual prepaid card product powered by cryptocurrency collateral. Designed for businesses, it uses stablecoins on Polygon as the backing asset: each card is linked to a stablecoin wallet, and funds are automatically converted to dollars at a 1:1 ratio, making integration with conventional payment networks seamless.
Each virtual card is a prepaid Visa card backed by stablecoin collateral. At the account level, a single holding wallet on the Polygon network holds all funds. When a purchase is made, the holding wallet balance is verified and the appropriate amount is debited.
Holding wallet (USDC, Polygon) └── Virtual Card A ── purchase → authorization → settled └── Virtual Card B ── purchase → authorization → settled └── Virtual Card C ...
Cards are issued against a card pack. Each company has a maximum number of active cards based on their contracted product. You can check available capacity via Get contracted product.
The cardholder pre-loads funds onto the card’s individual deposit wallet. Purchases are auto-approved against that balance.
WEBHOOK
Each purchase triggers a real-time webhook to your endpoint. You have 1,200 ms to respond with "00" / "SUCCESS" to approve or "05" to decline. Timeout = decline.
The approval_method cannot be changed after card creation. If the wrong method is set, delete the card and reissue.
Set daily_limit, weekly_limit, and monthly_limit (in USD) at creation. These are enforced per card independently. You can update them at any time — see Spending limits below.Omitting a limit means no limit is applied for that time window.
All cards draw from a shared holding wallet. Before cards can transact you must fund this wallet with USDC on Polygon.Retrieve the holding wallet deposit address via Get holding balance. The minimum deposit is 10 USD.
A minimum balance is always locked in the holding wallet to preserve capacity for at least one transaction. Withdrawals that would breach this floor are rejected.
To return funds to your treasury, use Withdraw from holding.For cards using TOP_UP approval, each card also has a personal deposit wallet. Fetch those addresses with Get card top-up wallets. Deposits sent to these wallets are attributed to that specific card and used to settle its purchases.
Use Freeze or unfreeze card to temporarily block a card. A frozen card declines all purchase attempts until unfrozen. The card state moves between ACTIVE and FROZEN without losing its configuration.Useful for: temporary employee suspension, suspicious activity hold, cardholder request.
If a velocity rule triggers, the card is automatically moved to BLOCKED. Manually unblock it with Unblock card. Unblocking also resets the authorization counter so the card can transact immediately.
Reissue card generates a new card number and CVV while keeping the same cardholder configuration, limits, and approval method. Use this when a card number is compromised. The old card is deactivated.
If a TOP_UP card’s deposit wallet address needs to be rotated (e.g. for compliance or security), use Rotate deposit wallet. A new address is generated and associated with the card. The old address stops accepting deposits.
Delete card permanently deactivates the card. Any remaining balance in the card’s individual wallet is returned to the holding wallet. This action is irreversible.
3DS adds cardholder verification to e-commerce purchases. Two modes are available per card:
Mode
Behavior
sms
A one-time code is sent to the cardholder’s registered phone.
webhook
A webhook is sent to your endpoint with the OTP challenge. Your system delivers it via your own channel.
Configure the mode with Set 3DS configuration.When a 3DS challenge fires, a notification_3ds_authorization webhook is delivered to your endpoint. For webhook mode, use Respond to 3DS authorization to submit the OTP entered by the cardholder.
Velocity rules define rate limits at the account level, applied per individual card. They protect against card probing and rapid fraudulent use.Each rule specifies:
max_authorizations — the maximum number of approved authorizations allowed
time_window_seconds — the sliding window over which the count is measured
You can configure up to 5 rules. When any rule is breached, the transaction is declined and the card is automatically blocked. Unblocking the card also resets its authorization counter, ensuring the card can resume normal operation immediately.Manage rules with:
When a velocity block fires, a card_blocked_by_velocity webhook is sent to your endpoint so your systems can react in real time (alert the cardholder, open a fraud investigation, etc.).
The risk score engine evaluates every purchase in real time. It assigns a numeric score by combining up to six signals, each weighted independently. If the score reaches or exceeds a configurable threshold, the transaction is declined.
Card used in a different country less than 4 hours after the previous transaction
Compares merchant country of current vs. last approved transaction
Unfamiliar MCC
mcc_profile
Merchant category code was never seen in the card’s 90-day history
Requires ≥ 5 historical transactions to activate
Amount above baseline
amount_baseline
Purchase amount exceeds the 95th percentile of the card’s historical amounts
Requires ≥ 5 historical transactions to activate
Unusual hour
time_window
Transaction hour appears in less than 5% of the card’s historical transactions
Requires ≥ 5 historical transactions to activate
High decline rate
decline_rate
3 or more transactions were declined on this card in the last 24 hours
Detects rapid retry / card probing
Foreign merchant country
merchant_country
Merchant’s country differs from the cardholder’s country (set via metadata.country at card creation)
Signal is 0 if metadata.country is not set
Signals that require a minimum history return 0 (no contribution) until the card has enough approved transactions. A brand-new card is only evaluated by geo_distance, decline_rate, and merchant_country.
The engine is configured at the account level from the Portal (Cards → Configuration → Risk Score). Each weight can be set to 0 to disable that signal entirely. Setting all weights to 0 disables the engine for the whole account.
Field
Description
threshold
Score at or above which a transaction is rejected. Range: 0.0 – any positive value.
In this configuration a transaction is rejected only if, for example, both impossible travel (0.5) and high decline rate (0.4) fire simultaneously (score = 0.9 ≥ 0.8). A single signal is not enough to reach the threshold.Strict setup — any single anomaly blocks the transaction:
Here, impossible travel alone (1.0) exceeds the threshold. Even an unusual hour (0.3) is enough to reject.Disabled engine — all weights set to 0, no transaction is ever rejected by risk score:
The engine is designed to fail open: if the transaction history cannot be fetched, or if the configuration cannot be loaded, the risk score check is skipped and the transaction proceeds normally. This ensures that a Redis or database hiccup never causes unexpected declines.
The risk score engine evaluates each purchase and may decline transactions that appear high-risk. When a trusted cardholder is incorrectly blocked (false positive), you can arm a one-shot fuse that bypasses risk evaluation for the next single purchase on that card. After that purchase fires, the fuse is automatically consumed and normal validation resumes.
The fuse bypasses only the risk score check. All other controls (spending limits, velocity rules, frozen status, holding balance) still apply.
Search transactions returns the transaction history for your account with filtering by card, date range, status, and more.Get transaction returns the full detail of a single transaction by ID.
Cards is the most event-heavy product. Register your webhook URL and webhook_key from the Portal (Settings → Webhooks) or via Subscribe webhook URL and Subscribe webhook key.All card events arrive with "product": "cards" in the envelope.
Event
When it fires
authorization
A purchase needs your approval (WEBHOOK mode). Respond within 1,200 ms with "00" / "SUCCESS" to approve or "05" to decline. Timeout = decline.
authorized
A purchase was approved (TOP_UP / NONE mode, or your webhook approved it).
cleared
An authorized purchase cleared and funds settled.
declined
A purchase was declined (by your webhook, by velocity rules, by risk score, or by insufficient balance).
reversal
An authorized purchase was reversed by the merchant or network.
refund
A merchant refund was applied to the card.
deposit
Funds arrived at a card’s top-up wallet.
visa_direct_deposit
A Visa Direct deposit credited the card.
warranty_withdraw
A withdrawal from the holding balance completed.
notification_3ds_authorization
A 3DS challenge was triggered. Deliver the OTP to the cardholder.
card_blocked_by_velocity
A velocity rule triggered and blocked the card. Sent once per ACTIVE → BLOCKED transition.
See Webhooks for the full envelope format, authentication via X-Webhook-Key, and payload examples.