Fiat to Stablecoin (Pay-in)
Understanding a Pay-in
UnblockPay's API enables you to convert fiat currencies into stablecoins and transfer them to blockchain wallets — either wallets managed by UnblockPay or external wallets. This process is called a Pay-in (also known as an on-ramp).
To create a pay-in, first you need to create a Customer and a Wallet.
How to create or manage a Pay-in
Step 1: Create a quote - POST v1/payin
This endpoint returns a fresh exchange rate for converting fiat money into stablecoins. The quote is valid for 5 minutes and returns a unique id you'll reference when initiating the pay-in.
In the request body, specify the sender with the fiat currency and local payment_rail, and the receiver with the stablecoin currency and blockchain payment_rail. You can optionally include an amount on either side and a partner_fee to apply a markup on top of UnblockPay's rate.
Here's an request example:
{
"symbol": "USDC/BRL",
"type": "on_ramp"
}
Here's an example response:
{
"id": "bfc36f00-ed1f-11ef-9fe4-378e29e10831",
"quotation": "5.6766",
"symbol": "USDC/BRL",
"expires_at": 1739790908
}
Step 2: Initiate a fiat to stablecoin pay-in - POST /payin
This endpoint initiates the pay-in process by creating a transaction that converts fiat money into stablecoins and sends the tokens to a blockchain wallet. You'll need to provide the pay-in amount in fiat currency, the quote_id from the previous step, along with customer_id, sender and receiver informations.
You can send stablecoins to either a wallet managed by UnblockPay (using wallet_id) or an external blockchain wallet (not managed by UnblockPay - using address).
Here's an example request for sending stablecoins to an UnblockPay-managed wallet (wallet_id):
{
"amount": 8000,
"quote_id": "{quote_id}",
"customer_id": "{customer_id}",
"sender": {
"currency": "BRL",
"payment_rail": "pix",
"name": "Satoshi Nakamoto",
"document": "12345678900"
},
"receiver": {
"currency": "USDC",
"payment_rail": "solana",
"wallet_id": "0196c1ab-a142-77a9-aa5f-38b3489393fa"
}
}
Here's an example request for sending stablecoins to an external blockchain wallet (address):
{
"amount": 8000,
"quote_id": "{quote_id}",
"customer_id": "0196c1ab-a142-77a9-aa5f-38b3489393fa",
"sender": {
"currency": "BRL",
"payment_rail": "pix",
"name": "Satoshi Nakamoto",
"document": "12345678900"
},
"receiver": {
"currency": "USDC",
"payment_rail": "solana",
"address": "HbXsDU6CByKZSi77cj5jTM7NXjBLExYDQ4hFWUJhjA3P"
}
}
After initiating a pay-in, we will send a webhook with the event type payin.created.
The sender object will include:
|
Parameter |
Definition |
Example |
|---|---|---|
|
currency |
The fiat currency you want to convert into stablecoins. |
|
|
payment_rail |
The local payment network for initiating the pay-in. |
|
|
name |
The first name and last name of the sender. |
|
|
document |
The tax ID or government-issued number from the sender. |
|
The receiver object will include:
|
Parameter |
Definition |
Example |
|---|---|---|
|
currency |
The stablecoin you want to receive the pay-in. |
|
|
payment_rail |
Blockchain network where the stablecoin settlement will occur. |
|
|
wallet_id |
If sending tokens to a UnblockPay-managed wallet, this is our wallet's unique identifier where you want to send the tokens. |
|
|
address |
If sending tokens to an external wallet (not managed by UnblockPay), this is the blockchain wallet address where you want to send the tokens. |
|
Since UnblockPay cannot pull funds directly from sender bank accounts, the response includes sender_deposit_instructions with the bank account information where the customer should send the fiat. For Brazil, the deposit_address is a Pix Copy & Paste code — you can display it as-is or generate a QR code from it in your frontend.
Here's an example response with Pix in Brazil:
{
"id": "0196eed8-afa4-752e-8d67-77bb96b7f662",
"status": "awaiting_deposit",
"type": "on_ramp",
"partner_id": "f7a3b1d2-9e34-4a3c-9f4c-8d3f7a1b2c45",
"customer_id": "01967de4-5087-72f9-aeda-413035deb7ea",
"quotation": "5.7114",
"sender_deposit_instructions": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix",
"deposit_address": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/47d0c1ba7a9f49b0ab8bf70abf1af8e05204000053039865802BR5925UNBLOCK SERVICOS DIGITAIS6014Rio de Janeiro62070503***630408EF",
"bank_account": {
"bank_name": "UnblockPay's Bank Partner in Brazil",
"beneficiary": {
"document": "58.444.469/0001-08",
"name": "UNBLOCK SERVICOS DIGITAIS LTDA"
}
}
},
"sender": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix"
},
"receiver": {
"amount": 1400.7,
"currency": "USDC",
"payment_rail": "solana",
"wallet_id": "0196ee9f-a96a-76f3-bc49-a421a097fd23",
"address": "BnHcqwecCN55Rx15QixnWKrcbb7QTuetcgpb9LWK1GQt",
},
"receipt": {
"initial_fiat_amount": 8000,
"final_crypto_amount": 1400.7,
"unblockpay_fee": 7.01
},
"created_at": "2025-05-20T17:58:20.324Z",
"updated_at": "2025-05-20T17:58:20.324Z",
"finished_at": null
}
The transaction will be created in an awaiting_deposit status, and you'll receive deposit instructions for sending fiat currency.
The sender_deposit_instructions will include:
|
Parameter |
Definition |
Example |
|---|---|---|
|
amount |
The exact amount of fiat money you need to send to the |
|
|
currency |
The fiat currency you want to convert into stablecoins. |
|
|
payment_rail |
The local payment network for initiating the pay-in. |
|
|
deposit_address |
UnblockPay's bank account information where you should send fiat money. |
|
For Brazil, the deposit_address is a Pix QR code value. Customers can copy this code to make payments from any bank account using Pix Copy & Paste. You can also generate and display a QR code in your frontend.
Once we detect the fiat deposit, the status will be updated to processing and we'll automatically process the conversion and initiate the stablecoin transfer to the receiver.
The finished_at field is only populated when the pay-in reaches a final status.
If you want to understand our fee structure, please check the Fee section.
Transactional Fees
View transaction details - GET v1/transactions/{id}
This endpoint allows you to check the status and details of a transaction at any time. You'll need the transaction ID that was returned when you initiated the pay-in.
Here's an example response showing a processing pay-in:
{
"id": "0196eed8-afa4-752e-8d67-77bb96b7f662",
"status": "processing",
"type": "on_ramp",
"partner_id": "f7a3b1d2-9e34-4a3c-9f4c-8d3f7a1b2c45",
"customer_id": "01967de4-5087-72f9-aeda-413035deb7ea",
"quotation": "5.7114",
"sender": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix",
"pix_end_to_end_id": "E332646682025052017594d3e1eb3f59",
"bank_account": {
"bank_name": "BCO XP S.A.",
"bank_code": "33264668",
"bank_account_number": "330487",
"beneficiary": {
"name": "LUCCA FREIRE",
"document": "14965065700"
}
}
},
"receiver": {
"amount": 1400.7,
"currency": "USDC",
"payment_rail": "solana",
"wallet_id": "0196ee9f-a96a-76f3-bc49-a421a097fd23",
"address": "BnHcqwecCN55Rx15QixnWKrcbb7QTuetcgpb9LWK1GQt"
},
"receipt": {
"initial_fiat_amount": 8000,
"final_crypto_amount": 1400.7,
"unblockpay_fee": 7.01
},
"created_at": "2025-05-20T17:58:20.324Z",
"updated_at": "2025-05-20T17:59:41.617Z",
"finished_at": null
}
Here's an example response showing a completed pay-in:
{
"id": "0196eed8-afa4-752e-8d67-77bb96b7f662",
"status": "completed",
"type": "on_ramp",
"partner_id": "f7a3b1d2-9e34-4a3c-9f4c-8d3f7a1b2c45",
"customer_id": "01967de4-5087-72f9-aeda-413035deb7ea",
"quotation": "5.7114",
"sender": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix",
"pix_end_to_end_id": "E332646682025052017594d3e1eb3f59",
"bank_account": {
"bank_name": "BCO XP S.A.",
"bank_code": "33264668",
"bank_account_number": "330487",
"beneficiary": {
"name": "LUCCA FREIRE",
"document": "14965065700"
}
}
},
"receiver": {
"amount": 1400.7,
"currency": "USDC",
"payment_rail": "solana",
"wallet_id": "0196ee9f-a96a-76f3-bc49-a421a097fd23",
"address": "BnHcqwecCN55Rx15QixnWKrcbb7QTuetcgpb9LWK1GQt"
},
"receipt": {
"initial_fiat_amount": 8000,
"final_crypto_amount": 1400.7,
"unblockpay_fee": 7.01
},
"created_at": "2025-05-20T17:58:20.324Z",
"updated_at": "2025-05-20T17:59:41.617Z",
"finished_at": "2025-02-17T04:02:09.676Z"
}
Cancel a transaction - PUT v1/transactions/{id}
This endpoint allows you to cancel a transaction that is still in the awaiting_deposit status. You cannot cancel pay-ins that are in other statuses. Once cancelled, the transaction cannot be resumed and you'll need to create a new one if needed.
Here's an example response showing a cancelled pay-in:
{
"id": "0196eed8-afa4-752e-8d67-77bb96b7f662",
"status": "cancelled",
"type": "on_ramp",
"partner_id": "f7a3b1d2-9e34-4a3c-9f4c-8d3f7a1b2c45",
"customer_id": "01967de4-5087-72f9-aeda-413035deb7ea",
"quotation": "5.7114",
"sender_deposit_instructions": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix",
"deposit_address": "00020101021226790014br.gov.bcb.pix2557brcode.starkinfra.com/v2/47d0c1ba7a9f49b0ab8bf70abf1af8e05204000053039865802BR5925UNBLOCK SERVICOS DIGITAIS6014Rio de Janeiro62070503***630408EF",
"bank_account": {
"bank_name": "UnblockPay's Bank Partner in Brazil",
"beneficiary": {
"document": "58.444.469/0001-08",
"name": "UNBLOCK SERVICOS DIGITAIS LTDA"
}
}
},
"sender": {
"amount": 8000,
"currency": "BRL",
"payment_rail": "pix"
},
"receiver": {
"amount": 1400.7,
"currency": "USDC",
"payment_rail": "solana",
"wallet_id": "0196ee9f-a96a-76f3-bc49-a421a097fd23",
"address": "BnHcqwecCN55Rx15QixnWKrcbb7QTuetcgpb9LWK1GQt"
},
"receipt": {
"initial_fiat_amount": 8000,
"final_crypto_amount": 1400.7,
"unblockpay_fee": 7.01
},
"created_at": "2025-05-20T17:58:20.324Z",
"updated_at": "2025-05-20T17:58:20.324Z",
"finished_at": null
}
After canceling a pay-in, we will send a webhook with the event type payin.cancelled.
Pay-in API endpoints
Here are the endpoints you'll need to create, list or cancel a pay-in transaction:
-
POST v1/quote: Create a stablecoin/fiat quote -
POST v1/payin: Initiate fiat to stablecoin pay-in transaction -
GET v1/transactions/{id}: View details of a specific transaction -
PUT v1/transactions/{id}: Cancel a transaction (only available for transactions withawaiting_depositstatus)
For the full schema and request/response details, see the API Reference.

