📘

Multi-Currency Account is coming soon… Stay tuned!

What are Multi-Currency Accounts?

Multi-Currency Accounts (MCAs) are specialized bank accounts that allow users to hold, manage, exchange, and transact in multiple currencies. Unlike a standard bank account—which is typically denominated in a single currency—a Multi-Currency Account offers the account holder the flexibility to work with different currencies without needing to convert funds.

What can you do with Multi-Currency Accounts?

  1. Deposit multiple currencies from around the world into your personal Multi-Currency Account.
  2. Exchange any currency pairs within your Multi-Currency Account at competitive rates.
  3. Transfer funds in any supported currency to a recipient of your choice—whether to an external bank account or another Multi-Currency Account within the same organization.

Get Started

Prerequisites

To open a Multi-Currency Account, a HIFI user must first complete KYC verification for the MULTI_CURRENCY_ACCOUNT rail.

  • Learn more about KYC and unlocking rails here.
  • View the KYC requirements for the MULTI_CURRENCY_ACCOUNT rail here.

Multi-Currency Account Structure

The structure of a Multi-Currency Account is as follows:

  1. A User can open a Multi-Currency Account.
  2. A Multi-Currency Account can have multiple Currency Accounts, each in different currency.
  3. Each Currency Account is associated with a specific currency and includes a set of Bank Account Details for deposit.
  4. A Currency Account gives users the ability to deposit a specific currency into their Multi-Currency Account. It is a virtual bank account designed solely to funnel funds into the Multi-Currency Account.

The diagram below illustrates the relationship between each of the components highlighted above.

Currency Account

To deposit fiat currency into a Multi-Currency Account, users must first apply for and open a Currency Account for the desired currency. This can be done via the Apply for a currency account endpoint.

Let's open a USD Currency Account with a bank located in the USA, with an account purpose as "03" (Top-Up). Learn more about different account purposes here.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/users/faf56e30-6806-46a9-ab46-f8413f191a01/multi-currency-account/currency-accounts \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
  "purpose": "03",
  "currency": "USD",
  "bankLocation": "USA"
}
'

Response:

{
    "id": "94420638-9445-4cc9-a40f-3d933380d8cf",
    "userId": "faf56e30-6806-46a9-ab46-f8413f191a01",
    "createdAt": "2025-02-17T21:32:56.668465+00:00",
    "updatedAt": "2025-02-17T21:33:07.197+00:00",
    "status": "PENDING",
    "accountHolderName": "",
    "accountType": "",
    "accountPurpose": "03",
    "currency": "USD",
    "bankName": "",
    "bankCode": "",
    "branchNumber": "",
    "accountNumber": "",
    "routingNumber": "",
    "swiftCode": "",
    "sortCode": "",
    "iban": "",
    "bankCountry": "USA",
    "bankCity": "",
    "bankAddress": "",
    "bankPostalCode": ""
}

The currency account application will initially have a status of PENDING. You can either poll the "Get a Currency Account" endpoint or wait for the Currency Account webhook event to receive the latest application status updates.

After the currency account application status becomes AVAILABLE, you will receive the following currency account object with all the deposit information populated:

{
    "id": "80f08151-01ec-479b-9304-5d2820a21abd",
    "userId": "0e965562-047c-43ae-9481-fd894f7e6706",
    "createdAt": "2025-02-07T05:25:46.852516+00:00",
    "updatedAt": "2025-02-07T05:35:03.267+00:00",
    "status": "AVAILABLE",
    "accountHolderName": "Henry Wu",
    "accountType": "CHECKING",
    "accountPurpose": "03",
    "currency": "USD",
    "bankName": "Citibank",
    "bankCode": "006",
    "branchNumber": "01",
    "accountNumber": "73380000000363268",
    "routingNumber": "031100209",
    "swiftCode": "GEOORUMMXXX",
    "sortCode": "",
    "iban": "",
    "bankCountry": "United States",
    "bankCity": "New York",
    "bankAddress": "111 Wall Street, New York, New York 10043, United States",
    "bankPostalCode": "10043"
}

Deposit Funds

To deposit funds into your Multi-Currency Account, you need to transfer fiat to the currency account you successfully applied for. When making a deposit, ensure that you enter the provided deposit information accurately and ONLY deposit the same fiat currency as the currency account is for.

Once the funds have been transferred, wait for a webhook event of type MULTI_CURRENCY_ACCOUNT.DEPOSIT to track the status of the deposit.

Currency Exchange

Once you have deposited multiple currencies into your Multi-Currency Account, you can exchange between any currency pairs you own. Let's exchange USD for EUR as an example.

How to perform a currency exchange:

  1. Get the Forex Rate – Use the Get a forex rate endpoint to retrieve the latest rate for your desired currency pair.
  2. Create a Forex Order – Execute the exchange at the retrieved rate using the Create a forex order endpoint.

Get an Exchange Rate

To retrieve an exchange rate, call the Get a forex rate endpoint, providing the currency pair and the amount you wish to exchange.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/multi-currency-account/exchanges/rate \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
  "source": {
    "currency": "USD",
    "amount": 10
  },
  "destination": {
    "currency": "EUR"
  },
  "userId": "faf56e30-6806-46a9-ab46-f8413f191a01"
}
'

Response:

{
    "id": "736c17bd-fcb1-4bb5-ad9b-76d74d7f8ca0",
    "createdAt": "2025-02-01T04:32:27.037269+00:00",
    "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
    "source": {
        "amount": 10,
        "currency": "USD"
    },
    "destination": {
        "amount": 9.62,
        "currency": "EUR"
    },
    "rate": 0.96189,
    "expiresAt": "2025-02-01T04:33:26.557+00:00"
}

Exchange Currencies Using an Exchange Rate

Once you have obtained an exchange rate, you can proceed with the currency exchange by using the exchange rate id.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/multi-currency-account/exchanges \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
  "source": {
    "currency": "USD",
    "amount": 10
  },
  "destination": {
    "currency": "EUR"
  },
  "requestId": "79d661c4-f9d1-44a8-937a-0b3de6c6bf63",
  "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
  "rateId": "736c17bd-fcb1-4bb5-ad9b-76d74d7f8ca0"
}
'

Response:

{
    "id": "dc93b3d3-ae96-4bd6-848f-7e96adb0082f",
    "createdAt": "2025-02-11T15:23:59.811266+00:00",
    "updatedAt": "2025-02-11T15:24:02.604+00:00",
    "requestId": "bf068b04-66cb-4658-b84d-7ecea493de85",
    "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
    "rateId": "736c17bd-fcb1-4bb5-ad9b-76d74d7f8ca0",
    "source": {
        "amount": 10,
        "currency": "USD"
    },
    "destination": {
        "amount": 9.62,
        "currency": "EUR"
    },
    "reference": null,
    "status": "SUCCESS",
    "failedReason": ""
}

Transfer

You can transfer funds from your Multi-Currency Account to:

  • An external recipient (e.g., a bank account outside your organization).
  • Another internal Multi-Currency Account owned by a user within your organization.

The diagram below illustrates these two types of transfers:

Transfer to an External Recipient

Transferring funds to an external recipient involves two steps:

  1. Create a recipient – The recipient must pass KYC before receiving funds.
  2. Create a transfer – Initiate the transfer to the recipient.

Create a recipient

Use the Create a Transfer Recipient endpoint to register a recipient. You will need to provide the recipient's bank details along with their personal or business information, depending on whether the recipient is an individual or a business entity.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/multi-currency-account/transfers/recipients \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
  "type": "individual",
  "bank": {
    "accountType": "CHECKING",
    "address": {
      "addressLine1": "Example St 1.",
      "city": "New York",
      "stateProvinceRegion": "NY",
      "postalCode": "10003",
      "country": "USA"
    },
    "currency": "USD",
    "accountName": "Henry Wu",
    "accountNumber": "123456788",
    "bankName": "Bank of America",
    "routingNumber": "026009593"
  },
  "recipient": {
    "address": {
      "addressLine1": "Example St 1.",
      "city": "New York City",
      "stateProvinceRegion": "NY",
      "postalCode": "10003",
      "country": "USA"
    },
    "type": "20",
    "phone": "+185743482934",
    "email": "test@hifibridge.com",
    "name": "Henry Wu",
    "nationality": "USA",
    "occupation": "40400"
  },
  "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01"
}
'

Response:

{
    "id": "6e6316b0-630f-4775-9f6c-21bc4a0bd0fe",
    "createdAt": "2025-02-11T15:43:42.327349+00:00",
    "updatedAt": "2025-02-11T15:43:49.861+00:00",
    "status": "PENDING",
    "rejectionReasons": null,
    "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
    "type": "individual",
    "recipient": {
        "type": "20",
        "name": "Henry Wu",
        "phone": "+185743482934",
        "email": "test@hifibridge.com",
        "address": {
            "city": "New York",
            "country": "USA",
            "postalCode": "10003",
            "addressLine1": "Example St 1.",
            "stateProvinceRegion": "NY"
        },
        "nationality": "USA",
        "occupation": "40400",
        "certificationType": null,
        "certificationNumber": null,
        "certificationFrontUrl": null,
        "certificationBackUrl": null,
        "certificationIssuanceAuth": null,
        "certificationIssuanceDate": null,
        "certificationExpirationDate": null
    },
    "bank": {
        "currency": "USD",
        "accountName": "Henry Wu",
        "accountType": "CHECKING",
        "accountNumber": "123456788",
        "accountPurpose": null,
        "accountHolder": {
            "address": null,
            "phone": null,
            "govIdType": null,
            "govIdNumber": null
        },
        "bankName": "Bank of America",
        "bankCode": null,
        "branchName": null,
        "branchCode": null,
        "ifscCode": null,
        "sortCode": null,
        "address": {
        		"addressLine1": "Example St 1.",
          	"city": "New York",
          	"stateProvinceRegion": "NY",
          	"postalCode": "10003",
          	"country": "USA"
        },
        "swiftCode": null,
        "routingNumber": "026009593",
        "iban": null
    }
}

The recipient will initially have a status of PENDING. You can either poll the "Get a recipient" endpoint or wait for the recipient webhook event to receive the latest recipient KYC status updates.

Create a payout transfer

When initiating a payout transfer, you need to specify the transfer type, ensuring that it is not INTERNAL_TRANSFER, as that is used for transfers between internal Multi-Currency Accounts (which will be covered later).

Additionally, you must specify the paymentMethod to indicate whether the transfer is:

  • CROSS-BORDER – Uses SWIFT as the PaymentNetwork.
  • LOCAL – Uses the respective local payment network.

In the transfer request:

  • The source object represents the user sending the funds.
  • The destination object represents the recipient receiving the funds.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/multi-currency-account/transfers \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
	"requestId": "6d136d9a-a3cd-4f74-a7b0-a7dcbd028293",
  "type": "PAYOUT",
  "paymentMethod": "CROSS-BORDER",
  "paymentNetwork": "SWIFT",
  "feeBearer": "OUR",
  "purpose": "1001",
  "pobo": true,
  "source": {
    "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
    "amount": "10",
    "currency": "USD"
  },
  "destination": {
    "currency": "USD",
    "recipientId": "6e6316b0-630f-4775-9f6c-21bc4a0bd0fe"
  }
}
'

Response:

{
    "id": "ba1ed885-30f3-427d-a5f1-0404db7fef89",
    "createdAt": "2025-02-14T22:21:02.280578+00:00",
    "updatedAt": "2025-02-14T22:21:06.024+00:00",
    "requestId": "ba1ed885-30f3-427d-a5f1-0404db7fef89",
    "type": "PAYOUT",
    "status": "PENDING",
    "description": null,
    "paymentMethod": "CROSS-BORDER",
    "paymentNetwork": "SWIFT",
    "source": {
        "userId": "0e965562-047c-43ae-9481-fd894f7e6706",
        "amount": 11,
        "currency": "USD"
    },
    "destination": {
        "amount": 10,
        "currency": "USD",
        "recipientId": "6e6316b0-630f-4775-9f6c-21bc4a0bd0fe",
        "userId": null
    },
    "rateId": null,
    "feeBearer": "OUR",
    "purpose": "1001",
    "gpi": null,
    "failedReason": null,
    "remark": null
}

The payout transfer will initially have a status of PENDING. You can either poll the "Retrieve a transfer order" endpoint or wait for the transfer webhook event to receive the latest payout transfer status updates.

Create an Internal Transfer

To create an internal transfer, set the transfer type to INTERNAL_TRANSFER and specify the destination user who will receive the funds.

Request:

curl --request POST \
     --url https://sandbox.hifibridge.com/v2/multi-currency-account/transfers \
     --header 'accept: application/json' \
     --header 'authorization: Bearer zpka_xxxxx' \
     --header 'content-type: application/json' \
     --data '
{
	"requestId": "6d136d9a-a3cd-4f74-a7b0-a7dcbd028293",
  "type": "INTERNAL_TRANSFER",
  "feeBearer": "OUR",
  "purpose": "1001",
  "source": {
    "userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01",
    "amount": "10",
    "currency": "USD"
  },
  "destination": {
    "currency": "USD",
		"userId": "7a8ac012-f5e7-45e0-bda5-851f542b2e01"
  }
}
'

Response:

{
    "id": "ba1ed885-30f3-427d-a5f1-0404db7fef89",
    "createdAt": "2025-02-14T22:21:02.280578+00:00",
    "updatedAt": "2025-02-14T22:21:06.024+00:00",
    "requestId": "ba1ed885-30f3-427d-a5f1-0404db7fef89",
    "type": "INTERNAL_TRANSFER",
    "status": "PENDING",
    "description": null,
    "paymentMethod": null,
    "paymentNetwork": null,
    "source": {
        "userId": "0e965562-047c-43ae-9481-fd894f7e6706",
        "amount": 11,
        "currency": "USD"
    },
    "destination": {
        "amount": 10,
        "currency": "USD",
      	"recipientId": null,
        "userId": "0e965562-047c-43ae-9481-fd894f7e6706"
    },
    "rateId": null,
    "feeBearer": "OUR",
    "purpose": "1001",
    "gpi": null,
    "failedReason": null,
    "remark": null
}