πŸ“š Resources
πŸ’Ό Virtual Wallets

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

FieldTypeRequiredDescriptionExample
user_idstring (UUID)YesCustomer's user ID (must be a valid UUID)"123e4567-e89b-12d3-a456-426614174000"
currencystringYesCurrency code for virtual wallet onboarding"CAD"

Supported Currencies

Currency CodeCurrency Name
CADCanadian Dollar
USDUS Dollar
EUREuro
GBPBritish 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

FieldTypeDescription
messagestringSuccess message indicating onboarding completion
currencystringCurrency code that was onboarded
user_idstring (UUID)Customer user ID that was onboarded

Error Responses

Status CodeDescription
400Invalid request format, missing required fields, invalid UUID, or invalid currency
401Unauthorized - Invalid API key or signature
403User has not completed KYC verification
404No KYC record found for the provided user ID
500Internal 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

ParameterTypeRequiredDescriptionExample
user_idstring (UUID)YesCustomer's user ID (must be a valid UUID)"123e4567-e89b-12d3-a456-426614174000"
currencystringYesCurrency 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

FieldTypeDescription
idstring (UUID)Unique identifier for the virtual wallet
user_idstring (UUID)Customer's user ID
currencystringCurrency code (CAD, USD, EUR, GBP)
currency_namestringFull name of the currency
statusstringCurrent status of the virtual wallet (ACTIVE, INACTIVE, SUSPENDED)
created_atstring (ISO 8601)Timestamp when the virtual wallet was created
updated_atstring (ISO 8601)Timestamp when the virtual wallet was last updated
bank_account_detailsobjectBank account information for receiving deposits

Bank Account Details Fields

The bank_account_details object contains all bank information needed for deposits:

FieldTypeDescription
account_numberstringVirtual account number for receiving deposits
account_namestringAccount holder name
bank_namestringName of the bank
bank_codestringBank code identifier
ibanstringInternational Bank Account Number (if applicable)
swiftstringSWIFT/BIC code (if applicable)
sort_codestringSort code (for GBP accounts)
routing_numberstringRouting number (for USD accounts)
countrystringCountry code where the account is located
currencystringCurrency of the account
account_typestringType of account (e.g., CHECKING, SAVINGS)
emailstringEmail associated with the account
bank_addressstringBank's physical address
payment_railstringPrimary payment rail supported
payment_railsarrayList of all supported payment rails

Error Responses

Status CodeDescription
400Invalid request format, missing required query parameters, invalid UUID, or invalid currency
401Unauthorized - Invalid API key or signature
403Customer does not belong to your business
404Virtual wallet not found for the specified user and currency
500Internal 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&currency=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}&currency=${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=...&currency=... β”‚
β”‚     └─> 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&currency=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-wallets endpoint 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