Introduction
Welcome to the HIFI Quickstart Guide (USD)! In this guide, we will walk you through the process of creating a user, passing KYC to unlock USD rail, creating a virtual account, adding offramp accounts, simulating onramps in the sandbox, and offramps. By following along, you’ll gain a clear understanding of how our endpoints work and how to integrate them into your application. To get started, you’ll need an API key, which you can get by reaching out to a member of the sales team. You’ll have two different API keys for two different HIFI environments. Today we’ll start in the Sandbox environment with the sandbox API key. You can follow our Sandbox guide to generate a sandbox API key. Let’s first create a user!User
A user object can represent either an individual or a business. All the available rails, accounts, onramps, offramps, transfer, etc, are associated with a user object. To create a HIFI user, you need to provide a basic set of user information. The user must also review and accept HIFI’s Terms and Service to obtain a valid signed agreement ID, which signifies a legally binding agreement to use our service. A successfully created user will have provisioned wallets and be granted access to our on-chain functionalities.Get a Valid Signed Agreement ID
To get HIFI’s Terms and Service page, you can call the Generate Terms of Service Link endpoint. You will need to pass in anidempotencyKey
, which can be any UUID. This idempotencyKey
will be used as your signed agreement ID.
Request:
JSON
url
and the signedAgreementId
. The url
directs you to HIFI’s Terms of Service page. The signedAgreementId
is the idempotencyKey
you passed in, which will be valid only after you accept the Terms of Service.
HIFI will trigger the
TOS_LINK.UPDATE
webhook event as soon as the user clicks the accept button.Create User
Now that we have the user’s validsignedAgreementId
and basic personal information, we can create a user by calling the Create User endpoint. We have provided all the basic personal information with dummy values in the curl request.
Request:
- The
id
is the user ID, which should be saved for future API calls for this particular user. - The
wallets
object contains all the wallet types and addresses provisioned for the user.
32051b2f-0798-55a7-9c42-b08da4192c97
.
KYC
After successfully creating a user, the user needs to decide which rails to unlock and submit KYC to enable access to those rails. In this guide, we will focus on the USD rail. To read more about the rails we support, click here To unlock, the USD rail, follow these steps:- Gather the required KYC information for the USD rail by either consulting our KYC documentation or using the Retrieve KYC Requirements endpoint.
- Update the user’s KYC information using the Update KYC Information endpoint.
- Upload documentation using the Add Documents endpoint.
- Submit the user’s KYC information through the Submit KYC endpoint to unlock the rail.
- Check the user’s KYC status for the USD rail via the Retrieve KYC Status endpoint.
Retrieve KYC Requirements
The Retrieve KYC Requirements endpoint provides the required and optional KYC fields needed to unlock a specific rail, as well as any invalid or missing KYC information the user currently holds, assuming they intend to submit KYC for this rail. This information helps identify what needs to be updated via the Update KYC endpoint before submitting KYC for the rail. Let’s get the KYC requirements for USD rails by calling the Retrieve KYC Requirements endpoint and passing in USD as the rails and the userId. Request:- The
required
fields represents all the mandatory KYC information needed for the USD rails KYC application. - The
optional
fields represents all the additional KYC information that is not mandatory but may be provided for the USD_EURO rails KYC application. - The
invalid
represent any fields that must be corrected before the KYC application can proceed for the USD rail. From the response, we can see that the user still have multiple missing KYC fields that needs to be provided before they can submit their KYC application for the rail.
Update KYC
Update KYC Information
To update the user’s KYC information, you can use the Update KYC endpoint. Let’s update the user’s KYC information. We have provided all the needed KYC fields with dummy values in the curl request. Request:Upload KYC Documentation
We have successfully updated the user’s KYC information now, let’s also upload the documentation. Users can upload raw documentation directly via the Upload a File endpoint. HIFI will return a file ID, which can later be used to attach the document to the user. Upload Documentation RequestfileId
, you can attach the documentation to the user. For the documentation required for the USD rail, please refer to Individual Documents
.
In this example, we will use the previously uploaded file as the user’s driver’s license to satisfy the identity
requirement.
Add Documentation Request
Submit KYC
To submit the KYC information the user currently holds for the USD rails, we can use the Submit KYC endpoint.📘 The Submit KYC endpoint submits the existing KYC information stored for the user to the specified rail. If you want to submit any new KYC data that the user doesn’t currently hold, you must first update the user’s KYC information using the Update KYC endpoint before calling Submit KYC.Let’s submit the user’s KYC information to unlock the USD_EURO rails. This can be done by calling the Submit KYC endpoint and providing the
userId
and the rails
.
Request:
"CREATED"
. The user can either call the Retrieve KYC Status endpoint or wait for webhook events to receive updates on the user’s latest KYC status for that rail.
Retrieve KYC Status
To get the KYC status for a specific rails, the user can call the Retrieve KYC Status endpoint. Let’s Get the KYC status for the user’s USD rail by passing in theuserId
and the rails
in the query param.
Request:
"ACTIVE"
if KYC is approved. In the sandbox environment, KYC approval should occur automatically.
Account
After creating a user who has passed KYC, you can add virtual accounts or offramp accounts for them to enable onramp or offramp transfers. The USD rail supports services for both onramp and offramp.- Virtual account: A bank account used to collect fiat currency deposits from your end users. Once the funds are received, they will be automatically converted to cryptocurrency.
- Offramp account: A bank account used as the destination for the offramping process. For example, during offramping, stablecoin is converted into fiat currency and sent to the offramp account.
Add Virtual Account
A Virtual Account is a bank account created by our system to facilitate onramp. Users can deposit fiat money into the virtual account, and the deposited funds are automatically converted into stablecoin. The parameters you pass in will determine the rail you want this onramp virtual account to support. For example, passing thesourceCurrency
as usd
, destinationCurrency
as usdc
, and destinationChain
as POLYGON
, will allow the user to deposit usd
into the virtual bank account to onramp to usdc
on POLYGON
.
Let’s make a Create a virtual account call using the user id we created earlier, with the parameters we just mentioned:
Request
accountInfo
object:
- The
id
is the unique identifier for the newly created virtual account. This ID should be saved for future retrieval of account information, including deposit instructions and micro-deposit details required by the institution. - The
source.paymentRail
indicates the payment methods supported by this virtual account. - The
source.currency
,destination.chain
, anddestination.currency
together represents the complete onramp rail. In our case, anyusd
deposited into the virtual account will be converted tousdc
and sent todestination.walletAddress
on thePOLYGON
blockchain. - The
status
reflects whether this virtual account is active for onramping. - IMPORTANT: The
depositInstructions
object contains the bank account details that the user needs to deposit fiat into for onramping.
Add Offramp Account
To offramp, you can add a USD offramp bank account by making an Create a USD Offramp Bank Account call. Let’s add a USD offramp bank account for Wire. To do this, you’ll need to provide your bank account details. However, for the purpose of this guide, we’ve pre-configured the bank account details for you, so all you need to do is call the Create a USD Offramp Bank Account endpoint: Request:id
returned in the response object is the unique identifier for the USD offramp bank account. This ID should be saved for future use whenever you want to initiate an offramp through a Wire transfer.
Transfer
After creating both virtual accounts and offramp accounts, the user can now perform three types of transfers/conversions:- Onramp Fiat to Stablecoin: Convert fiat currency from an onramp bank account to stablecoin.
- Stablecoin Transfer: Transfer stablecoin between users or wallet addresses.
- Offramp Stablecoin to Fiat: Convert stablecoin to fiat currency and send it to an offramp bank account.
- Onramp $2 USD and convert to 2 USDC into User A’s wallet.
- Transfer the 1 USDC from User A’s wallet to User B’s wallet.
- Offramp User A’s 1 USDC to User A’s bank account as $1 USD.
📘 Please note that in the sandbox environment, no real money movement occurs, so the onramping and offramping won’t actually process real funds. However, all the request and response examples will provide a clear overview of how the transfer occurs.
Onramp $2 USD to 2 USDC
Onramping fiat to stablecoin via a virtual account requires your end user to send US Dollars to the virtual account we just created. For example, if the user wants to send USD via Wire, they can use their bank app or contact their bank to send $1 USD to the following destination:- Bank Name: Cross River Bank
- Beneficiary Name: John Doe
- Beneficiary Address: 123 Main St, New York, NY, 10010, US
- Routing Number: 021214891
- Account Number: 344176915009
ONRAMP.CREATE
.
In the webhook events, you should see a new onramp transaction created for the deposit we just simulated.
COMPLETE
, you can check the balance
of the user’s wallet to see the testnet USDC we just onramped!
The
bankInfo
under the source
object contains the information of the sender and the sending bank.Transfer 1 USDC Between Wallets
After the onramp transfer is completed, User A will have 1 USDC in their wallet. Now we can transfer the 1 USDC from User A’s wallet to User B’s wallet. To do this, we can call the Create a crypto transfer endpoint. Let’s take a look at the request fields:- The
requestId
is a unique identifier for the transfer request, ensuring that a request is processed only once to prevent duplicates. - The
source.userId
represents the user who wants to send the stablecoin. In our case, this is User A’s user id. - The
destination.userId
represents the user who will receive the stablecoin. In our case, this is User B’s user id. - The
chain
,currency
, andamount
fields indicate that we are sending 1usdc
on thePOLYGON
blockchain.
transferDetails
object:
- The
id
is a unique identifier for this transfer, which you can save to get the most up-to-date transfer status using the Retrieve a crypto transfer endpoint. - The
status
represents the transfer status, which initially appears as"CREATED"
. You will want to either register a webhook or poll the Retrieve a crypto transfer endpoint to monitor the latest transfer status until the transfer is"COMPLETED"
. - The
receipt.transactionHash
is the transaction hash on the blockchain, which you can use to check the transaction status online with a blockchain explorer. - The
failedReason
will show the reason if the transfer fails. - The
sender
andrecipient
objects provide detailed information about the sender and recipient users.
Offramp 1 USDC to $ 1 USD
Now let’s offramp the rest of the 1 USDC to userA’s bank account. To do this, we can call the Create an offramp endpoint. Let’s take a look at the request fields:- The
requestId
is a unique identifier for the transfer request, ensuring that a request is processed only once to prevent duplicates. - The
source.userId
represents the user from whom we want to offramp. In our case, this is User A’s user id. - The
destination.userId
represents the user receiving the offramp funds, and thedestination.accountId
is the receiving offramp account owned bydestination.userId
. In our case, thedestination.userId
will be User A’s user id, and thedestination.accountId
will be User A’s USD offramp account id. - The
chain
,source.currency
,destination.currency
, andsource.amount
fields indicate that we are converting 1usdc
on thePOLYGON
blockchain tousd
and sending thatusd
todestination.accountId
.
transferDetails
object:
-
The
id
is a unique identifier for this transfer, which you can save to get the most up-to-date transfer status using the Retrieve an offramp endpoint. -
The
status
represents the transfer status, which initially appears as"OPEN_QUOTE"
. You will have to call the Accept Quote Endpoint to kick off the offramp process -
The
receipt.transactionHash
is the transaction hash on the blockchain, which you can use to check the transaction status online with a blockchain explorer. -
The
error
anderrorDetails
will show the reason if the transfer fails. -
The
sourceUser
anddestinationUser
objects provide detail information about the sender and recipient users. -
The
quoteInformation
object provides the conversion rate information between the source and destination currencies.
expiresAt
field.
Request:
CRYPTO_INITIATED
. Next, you can either poll our Get Offramp Transaction
endpoint to get the latest status or subscribe to the webhook to wait for the status update event.
Congratulations 🎉! You’ve successfully navigated several key processes, including creating a user, submitting KYC to unlock rails, adding onramp/offramp accounts, and transferring funds between users. We hope this guide has provided you with a solid understanding of how to utilize HIFI’s API endpoints to manage digital currency transfers seamlessly. If you have any further questions or need additional support, please refer to our documentation or contact our support team. Happy coding!