This guide walks through the complete flow for issuing a Visa/Mastercard virtual card to a user: onboarding, KYC, wallet deployment, card creation, funding via USDC deposit, and securely displaying card details.
Test this flow in the Sandbox at https://crypto-sandbox.yativo.com/api/. KYC checks are auto-approved in the Sandbox environment.
Prerequisites
- An authenticated Yativo Crypto API key
- User identity information for KYC (name, date of birth, address, government ID)
Onboard the user
Submit basic user information to begin the card onboarding process.curl -X POST https://crypto-api.yativo.com/api/yativo-card/onboard \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \
-H "Content-Type: application/json" \
-d '{
"firstName": "Alice",
"lastName": "Martinez",
"email": "alice@example.com",
"phoneNumber": "+14155552671",
"dateOfBirth": "1990-06-15",
"nationality": "US",
"address": {
"line1": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}'
Response:{
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"kycStatus": "pending",
"createdAt": "2026-03-26T12:00:00Z"
}
Wait for KYC approval
KYC review can be instant (automated) or take up to 24 hours for manual review. Poll the status endpoint or listen for the kyc.approved webhook event.curl -X GET "https://crypto-api.yativo.com/api/yativo-card/kyc-status?cardUserId=cus_01J2KJ3MNPQ7R4S5T6U7VCRD01" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..."
KYC status values:| Status | Description |
|---|
pending | Under review |
approved | User can proceed |
rejected | KYC failed — reason in rejectionReason |
more_info_required | Additional documents needed |
Rather than polling, register a webhook for kyc.status_changed to get notified the moment the status updates.
Accept terms and conditions
Before a card can be issued, the user must accept the card program’s terms.curl -X POST https://crypto-api.yativo.com/api/yativo-card/accept-terms \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \
-H "Content-Type: application/json" \
-d '{
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"termsVersion": "2.1.0",
"acceptedAt": "2026-03-26T12:05:00Z"
}'
Retrieve the latest terms version from GET /yativo-card/terms and display the full terms text to users in your UI before recording acceptance.
Initialize the card wallet (deploy safe)
Deploy a smart contract wallet for the user. This wallet holds the USDC that funds the card.curl -X POST https://crypto-api.yativo.com/api/yativo-card/deploy-safe \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \
-H "Content-Type: application/json" \
-d '{
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01"
}'
Response:{
"walletId": "wlt_01J2KK3MNPQ7R4S5T6U7VWLT77",
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"walletAddress": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"chain": "polygon",
"status": "deployed",
"deployedAt": "2026-03-26T12:07:00Z"
}
Create a virtual card
With the wallet deployed and KYC approved, create the virtual card.curl -X POST https://crypto-api.yativo.com/api/yativo-card/create-card \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \
-H "Content-Type: application/json" \
-d '{
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"type": "virtual",
"label": "Alice Main Card",
"spendingLimit": {
"amount": "500.00",
"interval": "monthly"
}
}'
Response:{
"cardId": "crd_01J2KL3MNPQ7R4S5T6U7VCRD88",
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"type": "virtual",
"label": "Alice Main Card",
"status": "active",
"network": "visa",
"last4": "4242",
"expiryMonth": 3,
"expiryYear": 2029,
"spendingLimit": {
"amount": "500.00",
"interval": "monthly"
},
"createdAt": "2026-03-26T12:08:00Z"
}
Get the USDC funding address
Retrieve the deposit address for the card wallet. Users send USDC to this address to fund their card.curl -X GET "https://crypto-api.yativo.com/api/yativo-card/crd_01J2KL3MNPQ7R4S5T6U7VCRD88/wallet/funding-address" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..."
Response:{
"cardId": "crd_01J2KL3MNPQ7R4S5T6U7VCRD88",
"chain": "polygon",
"asset": "USDC",
"address": "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984",
"minimumDeposit": "5.00",
"balance": "0.00"
}
Display this address to users. When they send USDC to it, the card is funded automatically — no manual step required. Display card details securely with an ephemeral token
Card details (full PAN, CVV, expiry) are sensitive and must never be stored or logged. Use the ephemeral token API to retrieve them for a short-lived display session.curl -X POST "https://crypto-api.yativo.com/api/yativo-card/cus_01J2KJ3MNPQ7R4S5T6U7VCRD01/cards/crd_01J2KL3MNPQ7R4S5T6U7VCRD88/ephemeral-token" \
-H "Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJ1c3JfMDFIWVo..." \
-H "Content-Type: application/json" \
-d '{
"ttlSeconds": 300
}'
Ephemeral token response:{
"token": "eph_eyJhbGciOiJSUzI1NiJ9.eyJjYXJkSWQiOiJjcmRfMDFKMkts...",
"expiresAt": "2026-03-26T12:13:00Z",
"ttlSeconds": 300
}
Never log, store, or transmit full card details (PAN, CVV) through your servers. Use the ephemeral token pattern to retrieve them directly in the browser or mobile app for display-only purposes.
Physical Cards
To issue a physical card instead of virtual, set "type": "physical" in the create-card request and include shipping details:
{
"cardUserId": "cus_01J2KJ3MNPQ7R4S5T6U7VCRD01",
"type": "physical",
"label": "Alice Physical Card",
"shipping": {
"name": "Alice Martinez",
"line1": "123 Main Street",
"city": "San Francisco",
"state": "CA",
"postalCode": "94105",
"country": "US"
}
}
Physical card delivery typically takes 5–10 business days. The card arrives inactive and must be activated via POST /yativo-card/{cardId}/activate.
Next Steps