Virtual Wallets API
Virtual Wallets enable your customers to hold and receive funds in multiple currencies. This API allows you to onboard customers to virtual wallets, which creates dedicated virtual accounts for receiving deposits.
Overview
Virtual wallets provide:
- Virtual Account Numbers - Dedicated account numbers for receiving bank transfers
- Multi-Currency Support - Support for CAD, USD, EUR, and GBP
- Automated Deposits - Incoming transfers are automatically credited to the customer's wallet
- KYC Integration - Leverages existing KYC verification for seamless onboarding
Virtual Wallet Onboarding
Onboard a customer to a virtual wallet for a specific currency. This endpoint initiates the onboarding process for the specified currency.
Prerequisites
- Customer must have completed KYC verification
- Customer must be registered and linked to your business account
- Valid API key with appropriate permissions
Endpoint
POST /api/v1/client/virtual-wallets
Authentication
This endpoint requires HMAC authentication (Business API Key). Include your API key and signature in the request headers:
x-api-key: <your-api-key>
x-timestamp: <RFC3339-timestamp>
x-signature: <HMAC-signature>For detailed information on HMAC authentication, see the Authentication Guide.
Request Body
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
user_id | string (UUID) | Yes | Customer's user ID (must be a valid UUID) | "123e4567-e89b-12d3-a456-426614174000" |
currency | string | Yes | Currency code for virtual wallet onboarding | "CAD" |
Supported Currencies
| Currency Code | Currency Name |
|---|---|
CAD | Canadian Dollar |
USD | US Dollar |
EUR | Euro |
GBP | British Pound |
Request Example
{
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"currency": "CAD"
}Success Response (200 OK)
{
"message": "Customer onboarding completed successfully",
"currency": "CAD",
"user_id": "123e4567-e89b-12d3-a456-426614174000"
}Response Fields
| Field | Type | Description |
|---|---|---|
message | string | Success message indicating onboarding completion |
currency | string | Currency code that was onboarded |
user_id | string (UUID) | Customer user ID that was onboarded |
Error Responses
| Status Code | Description |
|---|---|
400 | Invalid request format, missing required fields, invalid UUID, or invalid currency |
401 | Unauthorized - Invalid API key or signature |
403 | User has not completed KYC verification |
404 | No KYC record found for the provided user ID |
500 | Internal server error during onboarding process |
Error Response Examples
User has not completed KYC (403):
{
"error": "user is yet to complete kyc"
}No KYC record found (404):
{
"error": "no kyc record for id provided"
}Invalid currency (400):
{
"error": "invalid currency"
}Example: cURL
curl -X POST https://api.sznd.app/api/v1/client/virtual-wallets \
-H "Content-Type: application/json" \
-H "x-api-key: your_api_key_here" \
-H "x-timestamp: 2025-01-30T12:20:15Z" \
-H "x-signature: generated_signature_here" \
-d '{
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"currency": "CAD"
}'Example: JavaScript
const crypto = require('crypto');
async function onboardVirtualWallet(userId, currency) {
const apiKey = 'your_api_key_here';
const secretKey = 'your_secret_key_here';
const timestamp = new Date().toISOString();
const body = JSON.stringify({
user_id: userId,
currency: currency
});
// Generate HMAC signature
const dataToSign = `${body}|${timestamp}`;
const signature = crypto
.createHmac('sha256', secretKey)
.update(dataToSign)
.digest('hex');
const response = await fetch('https://api.sznd.app/api/v1/client/virtual-wallets', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-api-key': apiKey,
'x-timestamp': timestamp,
'x-signature': signature
},
body: body
});
return await response.json();
}
// Usage
const result = await onboardVirtualWallet(
'123e4567-e89b-12d3-a456-426614174000',
'CAD'
);
console.log(result);Get Virtual Wallet Details
Retrieve the details of a virtual wallet for a customer, including bank account information and currency. This endpoint should be called after the virtual wallet onboarding request has been processed.
Processing Time & Availability
After submitting a virtual wallet onboarding request via POST /api/v1/client/virtual-wallets:
- Processing Time: The virtual wallet setup is processed asynchronously and typically completes within 24 hours
- Webhook Notification: A webhook will be delivered to your configured webhook URL when the virtual wallet is ready and bank account details are available
- Polling: You can query this endpoint after 24 hours to retrieve the virtual wallet details, or wait for the webhook notification
Endpoint
GET /api/v1/client/virtual-wallets
Authentication
This endpoint requires HMAC authentication (Business API Key). Include your API key and signature in the request headers:
x-api-key: <your-api-key>
x-timestamp: <RFC3339-timestamp>
x-signature: <HMAC-signature>For detailed information on HMAC authentication, see the Authentication Guide.
Query Parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
user_id | string (UUID) | Yes | Customer's user ID (must be a valid UUID) | "123e4567-e89b-12d3-a456-426614174000" |
currency | string | Yes | Currency code for the virtual wallet. Must be one of: CAD, USD, EUR, GBP | "CAD" |
Success Response (200 OK)
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"currency": "CAD",
"currency_name": "Canadian Dollar",
"status": "ACTIVE",
"created_at": "2025-01-30T10:00:00Z",
"updated_at": "2025-01-30T10:00:00Z",
"bank_account_details": {
"account_number": "1234567890",
"account_name": "John Doe",
"bank_name": "Example Bank",
"bank_code": "001",
"iban": "CA12345678901234567890",
"swift": "EXAMCA01",
"sort_code": "12-34-56",
"routing_number": "123456789",
"country": "CA",
"currency": "CAD",
"account_type": "CHECKING",
"email": "customer@example.com",
"bank_address": "123 Main St, Toronto, ON",
"payment_rail": "ACH",
"payment_rails": ["ACH", "WIRE"]
}
}Response Fields
| Field | Type | Description |
|---|---|---|
id | string (UUID) | Unique identifier for the virtual wallet |
user_id | string (UUID) | Customer's user ID |
currency | string | Currency code (CAD, USD, EUR, GBP) |
currency_name | string | Full name of the currency |
status | string | Current status of the virtual wallet (ACTIVE, INACTIVE, SUSPENDED) |
created_at | string (ISO 8601) | Timestamp when the virtual wallet was created |
updated_at | string (ISO 8601) | Timestamp when the virtual wallet was last updated |
bank_account_details | object | Bank account information for receiving deposits |
Bank Account Details Fields
The bank_account_details object contains all bank information needed for deposits:
| Field | Type | Description |
|---|---|---|
account_number | string | Virtual account number for receiving deposits |
account_name | string | Account holder name |
bank_name | string | Name of the bank |
bank_code | string | Bank code identifier |
iban | string | International Bank Account Number (if applicable) |
swift | string | SWIFT/BIC code (if applicable) |
sort_code | string | Sort code (for GBP accounts) |
routing_number | string | Routing number (for USD accounts) |
country | string | Country code where the account is located |
currency | string | Currency of the account |
account_type | string | Type of account (e.g., CHECKING, SAVINGS) |
email | string | Email associated with the account |
bank_address | string | Bank's physical address |
payment_rail | string | Primary payment rail supported |
payment_rails | array | List of all supported payment rails |
Error Responses
| Status Code | Description |
|---|---|
400 | Invalid request format, missing required query parameters, invalid UUID, or invalid currency |
401 | Unauthorized - Invalid API key or signature |
403 | Customer does not belong to your business |
404 | Virtual wallet not found for the specified user and currency |
500 | Internal server error |
Error Response Examples
Missing user_id parameter (400):
{
"error": "user_id query parameter is required"
}Missing currency parameter (400):
{
"error": "currency query parameter is required"
}Invalid currency (400):
{
"error": "invalid currency. Supported currencies: CAD, USD, EUR, GBP"
}Virtual wallet not found (404):
{
"error": "virtual wallet not found for the specified user and currency"
}Customer does not belong to business (403):
{
"error": "customer does not belong to your business"
}Example: cURL
curl -X GET "https://api.sznd.app/api/v1/client/virtual-wallets?user_id=123e4567-e89b-12d3-a456-426614174000¤cy=CAD" \
-H "x-api-key: your_api_key_here" \
-H "x-timestamp: 2025-01-30T12:20:15Z" \
-H "x-signature: generated_signature_here"Example: JavaScript
const crypto = require('crypto');
async function getVirtualWalletDetails(userId, currency) {
const apiKey = 'your_api_key_here';
const secretKey = 'your_secret_key_here';
const timestamp = new Date().toISOString();
const queryParams = `user_id=${userId}¤cy=${currency}`;
const url = `https://api.sznd.app/api/v1/client/virtual-wallets?${queryParams}`;
// Generate HMAC signature for GET request
// Note: For GET requests, sign the query string and timestamp
const dataToSign = `${queryParams}|${timestamp}`;
const signature = crypto
.createHmac('sha256', secretKey)
.update(dataToSign)
.digest('hex');
const response = await fetch(url, {
method: 'GET',
headers: {
'x-api-key': apiKey,
'x-timestamp': timestamp,
'x-signature': signature
}
});
return await response.json();
}
// Usage - Call after 24 hours or when webhook is received
const walletDetails = await getVirtualWalletDetails(
'123e4567-e89b-12d3-a456-426614174000',
'CAD'
);
console.log('Virtual Wallet Details:', walletDetails);
console.log('Account Number:', walletDetails.bank_account_details.account_number);Webhook Notification
When the virtual wallet is ready, a webhook will be sent to your configured webhook URL. The webhook payload will include:
- Event type:
virtual_wallet.ready - User ID and currency
- Virtual wallet ID
- Bank account details
- Timestamp
Configure your webhook URL in your business settings to receive these notifications automatically. See the Webhooks Documentation for more details.
Integration Flow
The complete virtual wallet integration follows these steps:
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Virtual Wallet Onboarding Flow β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β β
β 1. Register Customer β
β POST /api/v1/client/customers β
β ββ> Returns user_id β
β β
β 2. Complete KYC Verification β
β POST /api/v1/client/customers/kyc β
β ββ> Customer completes KYC verification β
β β
β 3. Onboard to Virtual Wallet β
β POST /api/v1/client/virtual-wallets β
β ββ> Initiates virtual wallet creation process β
β β
β 4. Wait for Processing (24 hours) β
β ββ> Virtual wallet setup is processed asynchronously β
β ββ> Webhook notification sent when ready β
β β
β 5. Retrieve Virtual Wallet Details β
β GET /api/v1/client/virtual-wallets?user_id=...¤cy=... β
β ββ> Returns bank account details and virtual account info β
β β
β 6. Customer Receives Virtual Account β
β ββ> Virtual account number available β
β ββ> Customer can receive deposits via bank transfer β
β β
β 7. Funds Available in Wallet β
β ββ> Incoming transfers credited automatically β
β ββ> Check balance via GET /api/v1/users/{id}/wallets β
β β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββStep 1: Register Customer
First, register the customer using the Customer Registration endpoint:
curl -X POST https://api.sznd.app/api/v1/client/customers \
-H "Content-Type: application/json" \
-H "x-api-key: your_api_key_here" \
-H "x-timestamp: 2025-01-30T12:20:15Z" \
-H "x-signature: generated_signature_here" \
-d '{
"email": "customer@example.com",
"first_name": "John",
"last_name": "Doe",
"phone_number": "+1234567890",
"country_code": "CA",
"date_of_birth": "1990-05-15"
}'Step 2: Complete KYC
The customer must complete KYC verification. See the KYC Documentation for details.
Step 3: Onboard to Virtual Wallet
Once KYC is complete, onboard the customer to the virtual wallet:
curl -X POST https://api.sznd.app/api/v1/client/virtual-wallets \
-H "Content-Type: application/json" \
-H "x-api-key: your_api_key_here" \
-H "x-timestamp: 2025-01-30T12:20:15Z" \
-H "x-signature: generated_signature_here" \
-d '{
"user_id": "123e4567-e89b-12d3-a456-426614174000",
"currency": "CAD"
}'Step 4: Wait for Processing
The virtual wallet setup is processed asynchronously and typically completes within 24 hours. You have two options:
Option A: Wait for Webhook Notification (Recommended)
Configure your webhook URL to receive a notification when the virtual wallet is ready. The webhook will include all bank account details.
Option B: Poll the GET Endpoint
After 24 hours, query the GET endpoint to retrieve virtual wallet details:
curl -X GET "https://api.sznd.app/api/v1/client/virtual-wallets?user_id=123e4567-e89b-12d3-a456-426614174000¤cy=CAD" \
-H "x-api-key: your_api_key_here" \
-H "x-timestamp: 2025-01-30T12:20:15Z" \
-H "x-signature: generated_signature_here"Step 5: Use Virtual Account Details
Once the virtual wallet is ready, use the bank account details from the response to receive deposits. The customer can now receive funds via bank transfer using the provided account information.
Important Notes
KYC Requirement
The customer must have completed KYC verification before virtual wallet onboarding can proceed. The system checks the KYC status and will return a 403 error if KYC is not completed.
Idempotency
If a customer is already onboarded for a specific currency, the endpoint may return success if the wallet already exists.
Processing Time
The virtual wallet onboarding request is processed asynchronously. After submitting the POST request:
- Processing Time: Virtual wallet setup typically completes within 24 hours
- Webhook Notification: A webhook will be delivered to your configured webhook URL when the virtual wallet is ready
- Retrieving Details: After 24 hours, you can query the
GET /api/v1/client/virtual-walletsendpoint to retrieve bank account details, or wait for the webhook notification
Virtual Account Details
After successful onboarding, the customer's wallet will include virtual account details (account number, bank name, etc.) that can be used to receive deposits. These details are available through the wallet API endpoints.
Related Resources
- Virtual Wallets API - View virtual wallet balances and details
- Customers API - Customer registration and management
- KYC Documentation - KYC verification process
- Transactions API - View transaction history