Skip to main content
Enable businesses to send money internationally through stablecoins with instant settlement. Leverage HIFI’s global network to reach recipients in multiple countries with low fees and transparent exchange rates. ⏱️ Time to complete: 35-45 minutes 🎯 What you’ll build: A complete cross-border payment flow where a US business pays a Hong Kong supplier, converting USD → USDC → HKD with instant settlement and competitive rates.

Use Case Overview

This recipe demonstrates an international B2B payment where:
  • ✅ US business deposits USD from their bank account
  • ✅ USD automatically converts to USDC stablecoin
  • ✅ USDC transfers instantly across borders
  • ✅ HKD is deposited to supplier’s Hong Kong bank account
This flow enables fast, cost-effective international business payments with transparent pricing and instant settlement.

Prerequisites

Before you start, make sure you have:
  • API keys from the Dashboard (Get API keys)
  • A tool for making API calls (cURL, Postman, or similar)
  • Basic understanding of REST APIs
  • Your sandbox endpoint: https://sandbox.hifibridge.com
All examples in this guide use the sandbox environment. When you’re ready for production, simply replace the sandbox URL with the production endpoint and use your production API keys.

What you’ll build

Here’s what we’ll accomplish in this recipe:
  1. Generate API Keys - Set up authentication for HIFI API
  2. Create Business A (Payer) - Onboard US business and complete KYB for USD rail
  3. Add Virtual Account - Set up account for USD deposits that convert to USDC
  4. Create Business B (Payee) - Onboard Hong Kong supplier (or use existing business)
  5. Execute Payment - Send USDC from Business A → HKD to Business B’s bank account
Payment Flow:
USD → Business A Bank Account → USDC → Business A Wallet → HKD → Business B Bank Account

Generate API Keys

Access to the HIFI API requires authentication via API keys. Generate your keys from the HIFI Dashboard before making any API calls.
Steps:
  1. Navigate to dashboard.hifibridge.com
  2. Log in to your account
  3. Go to Developer → API Keys
  4. Click Generate New Key
  5. Select your environment: Sandbox (for testing) or Production (for live transactions)
  6. Copy the key immediately - it’s only shown once
Important Security Notes:
  • Store your API key securely (environment variables, secrets manager, etc.)
  • Never commit API keys to version control
  • Your key authenticates all HIFI API requests
  • If compromised, immediately revoke in the Dashboard and generate a new one
API keys are shown only once. If you lose your key, you must revoke it and generate a new one. There is no way to retrieve a lost key.
Using Your API Key:Include your API key in the Authorization header of all API requests:
--header 'authorization: Bearer YOUR_API_KEY'
For a complete guide on API authentication, see our Authentication Documentation.

Create Business A (US Payer)

The paying business needs a verified business account to access fiat rails and send international payments. Every business must accept HIFI’s Terms of Service and complete KYB (Know Your Business) verification before they can move money between fiat and crypto.
Complete Business Onboarding Guide: For a comprehensive walkthrough of business onboarding and KYB verification, see our Business User Guide.

Business Creation Flow

Creating a business user involves four steps:
  1. Generate Terms of Service Link - Get acceptance link for your business
  2. Create Business User - Create the business account after TOS acceptance
  3. Update KYB Information - Provide required business details and UBO information
  4. Submit KYB - Submit for verification to unlock USD rail
Once the business has accepted the Terms of Service, create the business user account with the Create User endpoint.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "requestId": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
  "type": "business",
  "chains": ["POLYGON"],
  "email": "ustestbusiness@gmail.com",
  "dateOfBirth": "2023-12-25",
  "address": {
    "addressLine1": "4550 Market Street",
    "city": "Philadelphia",
    "stateProvinceRegion": "PA",
    "postalCode": "19104",
    "country": "USA"
  },
  "ipAddress": "127.0.0.1",
  "signedAgreementId": "96bc39ba-c6c6-412a-9452-e95a35d3f533",
  "businessName": "US Test Business",
  "ultimateBeneficialOwners": [
    {
      "firstName": "John",
      "lastName": "Doe",
      "dateOfBirth": "1980-01-01",
      "hasControl": true,
      "isSigner": true
    }
  ]
}
'
Request Fields:
requestId
string
required
Unique identifier (UUID) for this request to ensure idempotency.
type
string
required
User type. Use business for business accounts.
chains
array
Blockchain networks to provision wallets on. Options: POLYGON, ETHEREUM
email
string
required
Business email address.
dateOfBirth
string
Date associated with the business registration (YYYY-MM-DD format).
address
object
required
Business address.
ipAddress
string
IP address of the business representative creating the account.
signedAgreementId
string
required
The signedAgreementId from the Terms of Service acceptance.
businessName
string
required
Legal name of the business.
ultimateBeneficialOwners
array
required
Array of Ultimate Beneficial Owners (UBOs) who own or control the business.
Response:
{
  "id": "94dcd5c2-4508-593d-9302-fd7a5444eb20",
  "type": "business",
  "email": "ustestbusiness@gmail.com",
  "name": "US Test Business",
  "wallets": {
    "INDIVIDUAL": {
      "POLYGON": {
        "address": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760"
      },
      "ETHEREUM": {
        "address": "0x6e3D1de74422a9259578302Fd1e9eb203EACB2E8"
      }
    }
  }
}
Business user created successfully!Response Fields:
id
string
The unique business user ID. Save this - you’ll use it for all future operations with this business.
wallets
object
Automatically provisioned wallet addresses on supported blockchain networks.
What you get:
  • Business User ID (94dcd5c2-4508-593d-9302-fd7a5444eb20) - Save this for all future operations
  • Wallet addresses - Pre-provisioned on multiple blockchains, ready for instant transfers
Automatic Wallet Provisioning: Every business user automatically receives wallet addresses on supported blockchain networks. These wallets are fully functional immediately - no additional setup required.
Provide the required business information for KYB (Know Your Business) verification using the Update KYC endpoint.
KYB vs KYC: While the endpoint is named “KYC,” it handles both individual (KYC) and business (KYB) verification. For businesses, you’ll provide company details, tax information, and Ultimate Beneficial Owner (UBO) documentation.
Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/94dcd5c2-4508-593d-9302-fd7a5444eb20/kyc \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "firstName": "US Test Business",
  "nationality": "USA",
  "taxIdentificationNumber": "678898765"
}
'
Request Fields:
firstName
string
Business name (can be used for additional identification).
nationality
string
required
Country where the business is registered (ISO 3166-1 alpha-3 country code).
taxIdentificationNumber
string
required
Business tax identification number (e.g., EIN for US businesses).
Response:The response includes comprehensive business information including UBO details, business structure, compliance questionnaires, and uploaded documents. The full response structure includes:
  • Basic business information (name, email, address, tax details)
  • Ultimate Beneficial Owners with their personal information and documents
  • Business formation documents
  • Compliance screening information
  • Uploaded verification documents
Business information updated!
Document Upload: For a complete KYB submission in production, you’ll need to upload various business documents including: incorporation articles, business registration, proof of address, and UBO identification documents. See the Business User Guide for detailed document requirements. In sandbox, KYB may be automatically approved with minimal documentation.
UBO Document Upload: UBO (Ultimate Beneficial Owner) details are handled via a separate Add a UBO endpoint. After you create a UBO, save the uboId from the response and use it when calling the Add Documents endpoint so the files are attached to that specific UBO.
Submit the KYB application to unlock the USD rail using the Submit KYC endpoint.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/94dcd5c2-4508-593d-9302-fd7a5444eb20/kyc/submissions \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "rails": "USD"
}
'
Request Fields:
rails
string
required
The currency rail to unlock. Use USD for US Dollar operations.
Response:
{
  "USD": {
    "status": "CREATED",
    "message": "Your KYC application has been successfully created. We will review it shortly."
  }
}
KYB application submitted!Response Fields:
USD
object
Status information for the USD rail submission.
KYB Review Process:
  1. Status starts as CREATED (immediate)
  2. Transitions to PENDING (within minutes in sandbox)
  3. Final status: ACTIVE or REJECTED (typically automatic in sandbox, 3-7 business days in production)
Business Verification Timeline: Business KYB verification typically takes longer than individual KYC due to additional compliance requirements. In production, expect 3-7 business days for review. Monitor the status using the Retrieve KYC Status endpoint or subscribe to KYC.STATUS_UPDATE webhook events.

Add Virtual Account (Business A)

Now that Business A has passed KYB, create a Virtual Account for onramping. This is a bank account number automatically created by HIFI that the business can deposit USD into. When fiat arrives, it’s automatically converted to USDC and sent to their wallet.
Complete Virtual Account Guide: For more details on virtual accounts and onramping, see our Virtual Accounts Guide.
A Virtual Account enables Business A to deposit USD from their bank, which automatically converts to USDC on Polygon for international payment distribution.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/users/94dcd5c2-4508-593d-9302-fd7a5444eb20/virtual-accounts \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "sourceCurrency": "usd",
  "destinationCurrency": "usdc",
  "destinationChain": "POLYGON"
}
'
Request Fields:
sourceCurrency
string
required
Fiat currency to deposit. Use usd for US Dollars.
destinationCurrency
string
required
Stablecoin to receive after conversion. Use usdc for USD Coin.
destinationChain
string
required
Blockchain network for the stablecoin. Options: POLYGON, ETHEREUM
externalWalletId
string
Optional external wallet ID if using a wallet outside HIFI’s custody.
Response:
{
  "message": "Virtual account created successfully",
  "accountInfo": {
    "id": "c3d1b830-a57c-54d8-a103-df4e0713ff82",
    "createdAt": "2025-11-13T20:15:03.187Z",
    "updatedAt": "2025-11-13T20:15:03.187Z",
    "provider": "CROSS_RIVER",
    "userId": "94dcd5c2-4508-593d-9302-fd7a5444eb20",
    "source": {
      "paymentRail": ["ach", "wire", "rtp"],
      "currency": "usd"
    },
    "destination": {
      "chain": "POLYGON",
      "currency": "usdc",
      "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760",
      "externalWalletId": null
    },
    "status": "activated",
    "microDeposits": {
      "count": 0,
      "data": []
    },
    "depositInstructions": {
      "bankName": "Cross River Bank",
      "bankAddress": "885 Teaneck Road, Teaneck, NJ 07666",
      "beneficiary": {
        "name": "US Test Business",
        "address": "1234 Walnut Street, Suite 1200, Philadelphia, PA, 19107, US"
      },
      "ach": {
        "routingNumber": "021214891",
        "accountNumber": "388125286772"
      },
      "wire": {
        "routingNumber": "021214891",
        "accountNumber": "388125286772"
      },
      "rtp": {
        "routingNumber": null,
        "accountNumber": null
      },
      "reference": null,
      "depositBy": null,
      "instruction": "Please deposit usd to the bank account provided. Please ensure that the beneficiary name matches the account holder name provided, or the payment may be rejected."
    },
    "settlementRuleId": null
  }
}
Virtual account created!Response Fields:
accountInfo.id
string
The unique virtual account ID. Save this for monitoring deposits.
accountInfo.status
string
Account status. activated means it’s ready to receive deposits.
accountInfo.provider
string
Banking partner providing the virtual account infrastructure.
accountInfo.source
object
Source configuration for fiat deposits.
accountInfo.destination
object
Destination configuration for crypto conversion.
accountInfo.depositInstructions
object
Most Important: Bank account details Business A needs to send money to.
How to Use: Provide these deposit instructions to Business A. When they send money to this account via wire transfer or ACH, HIFI automatically detects the deposit, converts it to USDC, and sends it to their wallet. The USDC is then available for international payments. For monitoring deposits, subscribe to ONRAMP.CREATE webhook events.

Create Business B (HK Payee)

The recipient business (Business B in Hong Kong) needs a business account with an HKD bank account to receive the payment. Follow the same business creation flow as Business A, but complete KYB for the appropriate Hong Kong rail.
Using an Existing Business: If Business B already exists in your system, you can skip business creation and just ensure they have an active Hong Kong bank account. You’ll need their userId and accountId for the payment transaction.

Required Information

To complete this recipe, you’ll need:
  • Business B’s userId - From creating their business account
  • Business B’s HKD accountId - From adding their Hong Kong bank account
For the complete flow of creating Business B and adding their HKD bank account, follow the same steps as Business A but:
  1. Use Hong Kong business information and address details
  2. Submit KYB for the Hong Kong rail
  3. Add an Offramp Account (Hong Kong bank account) instead of a Virtual Account
For detailed instructions on adding offramp accounts for international recipients, see our Offramp Guide.

Execute Payment

Now you can send the international payment from Business A (US) to Business B (Hong Kong). Create an offramp transaction that converts USDC to HKD and sends it to Business B’s Hong Kong bank account. This is a two-step process:
  1. Create offramp request - Get a quote for the conversion
  2. Accept the quote - Execute the payment
Complete Offramp Guide: For more details on offramps and cross-border transfers, see our Offramp Transfer Guide.
Create an offramp request to get a quote for converting 10 USDC to HKD using the Create an offramp endpoint.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/offramps \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY' \
  --header 'content-type: application/json' \
  --data '
{
  "requestId": "e6c2e4fc-83d2-4e3b-9836-7ff57f2709be",
  "purposeOfPayment": "payment_for_services",
  "supportingDocumentType": "billing_document",
  "description": "Payment for supplier services",
  "source": {
    "amount": 10,
    "currency": "usdc",
    "chain": "POLYGON",
    "userId": "94dcd5c2-4508-593d-9302-fd7a5444eb20"
  },
  "destination": {
    "currency": "hkd",
    "accountId": "556d4f54-2514-4d10-ac93-c2aff03d2de5",
    "userId": "e06caa8a-4c0f-58d7-95a5-baf676e1e39a",
    "paymentReference": "Invoice #12345"
  }
}
'
Request Fields:
requestId
string
required
Unique identifier (UUID) for this offramp request to ensure idempotency.
purposeOfPayment
string
Purpose of the payment for compliance. Common values for B2B: payment_for_services, payment_for_goods, invoice_payment, contract_payment, etc.
supportingDocumentType
string
Type of supporting document if required. Options: billing_document, invoice, contract, purchase_order, etc.
supportingDocumentUrl
string
URL to the supporting document if required by regulations.
description
string
Description of the payment (e.g., invoice number, contract reference).
source
object
required
Source of the offramp (crypto side - Business A).
destination
object
required
Destination of the offramp (fiat side - Business B).
developerFee
array
Optional: Developer fees to collect on the transaction.
Response:
{
  "transferType": "OFFRAMP",
  "transferDetails": {
    "id": "63b7f9de-31e9-4726-bf5c-b4f21a6af796",
    "requestId": "e6c2e4fc-83d2-4e3b-9836-7ff57f2709be",
    "createdAt": "2025-11-17T14:36:15.277Z",
    "updatedAt": "2025-11-17T14:36:16.377Z",
    "status": "OPEN_QUOTE",
    "failedReason": null,
    "error": null,
    "errorDetails": null,
    "source": {
      "userId": "94dcd5c2-4508-593d-9302-fd7a5444eb20",
      "chain": "POLYGON",
      "currency": "usdc",
      "amount": 10,
      "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760",
      "user": {
        "email": "ustestbusiness@gmail.com",
        "lastName": null,
        "firstName": null,
        "businessName": "US Test Business"
      }
    },
    "destination": {
      "userId": "e06caa8a-4c0f-58d7-95a5-baf676e1e39a",
      "amount": 75.63,
      "currency": "hkd",
      "user": {
        "email": "hkgtestbusiness@gmail.com",
        "lastName": null,
        "firstName": null,
        "businessName": "HKG Test Business"
      },
      "accountId": "556d4f54-2514-4d10-ac93-c2aff03d2de5",
      "paymentReference": "Invoice #12345"
    },
    "receipt": {},
    "quoteInformation": {
      "sendGross": {
        "amount": "10.000000",
        "currency": "usdc"
      },
      "sendNet": {
        "amount": "9.730000",
        "currency": "usdc"
      },
      "taxFee": {
        "amount": "0.170000",
        "currency": "usdc"
      },
      "railFee": {
        "amount": "0.100000",
        "currency": "usdc"
      },
      "receiveGross": {
        "amount": "75.63",
        "currency": "hkd"
      },
      "receiveNet": {
        "amount": "75.63",
        "currency": "hkd"
      },
      "rate": "7.563000",
      "expiresAt": "2025-11-17T14:37:14.946+00:00"
    },
    "depositInformation": []
  }
}
Offramp quote created!Response Fields:
transferDetails.id
string
Unique offramp transaction ID. Save this - you’ll need it to accept the quote and monitor status.
transferDetails.type
string
Transfer type. Always OFFRAMP for cross-border payment transactions.
transferDetails.status
string
Current status. OPEN_QUOTE means you have an active quote waiting to be accepted.
transferDetails.source
object
Source details showing Business A’s wallet and amount being sent.
transferDetails.destination
object
Destination details showing Business B’s bank account and amount they’ll receive.
transferDetails.quoteInformation
object
Critical: Detailed breakdown of the conversion including exchange rate, fees, and amounts.
Understanding the Quote:In this example:
  • Business A sends 10 USDC
  • After fees (tax: 0.170 USDC, rail: 0.100 USDC), 9.73 USDC is converted
  • At a rate of 7.56 HKD per USDC
  • Business B receives 75.63 HKD in their Hong Kong bank account
Quote Expiration: Quotes typically expire after 15-30 minutes to protect against exchange rate volatility. If your quote expires before acceptance, create a new offramp request for a fresh quote with updated rates.
After reviewing the quote, exchange rate, and fees, accept it to execute the cross-border payment using the Accept Quote endpoint.Request:
curl --request POST \
  --url https://sandbox.hifibridge.com/v2/offramps/63b7f9de-31e9-4726-bf5c-b4f21a6af796/quote/accept \
  --header 'accept: application/json' \
  --header 'authorization: Bearer YOUR_API_KEY'
Response:
{
  "transferType": "OFFRAMP",
  "transferDetails": {
    "id": "63b7f9de-31e9-4726-bf5c-b4f21a6af796",
    "requestId": "e6c2e4fc-83d2-4e3b-9836-7ff57f2709be",
    "createdAt": "2025-11-17T14:36:15.277Z",
    "updatedAt": "2025-11-17T14:36:16.377Z",
    "status": "CRYPTO_INITIATED",
    "failedReason": null,
    "error": null,
    "errorDetails": null,
    "source": {
      "userId": "94dcd5c2-4508-593d-9302-fd7a5444eb20",
      "chain": "POLYGON",
      "currency": "usdc",
      "amount": 10,
      "walletAddress": "0x0466DCD644Ae2Ee5d88CF0e1976c3ce237A0D760",
      "user": {
        "email": "ustestbusiness@gmail.com",
        "lastName": null,
        "firstName": null,
        "businessName": "US Test Business"
      }
    },
    "destination": {
      "userId": "e06caa8a-4c0f-58d7-95a5-baf676e1e39a",
      "amount": 75.63,
      "currency": "hkd",
      "user": {
        "email": "hkgtestbusiness@gmail.com",
        "lastName": null,
        "firstName": null,
        "businessName": "HKG Test Business"
      },
      "accountId": "556d4f54-2514-4d10-ac93-c2aff03d2de5",
      "paymentReference": "Invoice #12345"
    },
    "receipt": {},
    "quoteInformation": {
      "sendGross": {
        "amount": "10.000000",
        "currency": "usdc"
      },
      "sendNet": {
        "amount": "9.730000",
        "currency": "usdc"
      },
      "taxFee": {
        "amount": "0.170000",
        "currency": "usdc"
      },
      "railFee": {
        "amount": "0.100000",
        "currency": "usdc"
      },
      "receiveGross": {
        "amount": "75.63",
        "currency": "hkd"
      },
      "receiveNet": {
        "amount": "75.63",
        "currency": "hkd"
      },
      "rate": "7.563000",
      "expiresAt": "2025-11-17T14:37:14.946+00:00"
    },
    "depositInformation": []
  }
}
Quote accepted! Cross-border payment is processing.The status has changed from OPEN_QUOTE to CRYPTO_INITIATED, meaning the transaction is now being executed.Cross-Border Payment Status Progression:
  1. OPEN_QUOTE - Quote generated, waiting for acceptance
  2. CRYPTO_INITIATED - Processing crypto conversion
  3. CRYPTO_PENDING - Waiting for blockchain confirmation
  4. FIAT_PENDING - Converting to HKD and initiating bank transfer
  5. COMPLETED - HKD deposited to Business B’s Hong Kong bank account
Monitoring Payment Status:Track the payment progress using:
  • Polling: Call Retrieve an offramp with the transaction ID (63b7f9de-31e9-4726-bf5c-b4f21a6af796)
  • Webhooks: Subscribe to OFFRAMP.UPDATE events for real-time status notifications
Settlement Times:
  • Sandbox: Instant simulation for testing
  • Production: Typically 1-3 business days depending on the destination country’s banking system and payment rail
Business Payment Notifications: Consider implementing webhook handlers to send notifications to both Business A (payer) and Business B (recipient) as the payment progresses. Include transaction details, exchange rates, and expected settlement times to provide transparency and improve cash flow management.

🎉 Congratulations!

You’ve successfully completed a cross-border business payment! By following this recipe, you can now:
  • ✅ Generate API keys and authenticate with HIFI
  • ✅ Onboard businesses and complete KYB for multiple currency rails
  • ✅ Create virtual accounts for fiat-to-crypto conversion
  • ✅ Execute international payments with instant settlement via stablecoins
  • ✅ Provide transparent fee structures and competitive exchange rates

Next Steps

Ready to build a full cross-border payment platform? Here’s what to explore next:
  • Webhooks - Set up real-time notifications for payment status updates and settlement confirmations
  • Rails Overview - Explore additional currency corridors to expand your global payment coverage
  • Offramp Guide - Deep dive into offramp transactions, compliance requirements, and settlement rules
  • Business User Guide - Learn about KYB requirements, UBO verification, and business document management
  • Error Handling - Implement robust error handling for failed transactions, expired quotes, and compliance issues
  • API Reference - Explore all available endpoints and parameters for advanced features