Authorization checkout managed by merchant
Enroll users for SmartPix payments using a custom API-based flow.
The SmartPix gives you full control over the enrollment setup (amount and duration) via API to dLocal. It runs fully within your app, with no redirection, offering a seamless and branded user experience.
Users authorize recurring payments via Open Finance. Once approved, dLocal returns a token to enable future payments without further action from the user.
Prefer a simpler, redirect-based flow? Check out Authorization checkout managed by dLocal for a pre-built integration.
Overall flow
This flow must be used to perform a single authorization without an associated payment.

User flow

Required User Experience
SmartPix identification
To adhere to Payment Schemes and Open Finance regulations, the expected user journey must be followed, meeting the criteria listed below.
Merchant checkout
As per selection of the payment method, SmartPix option can be listed alongside the other payment methods. The Open Finance iconography and the indication that the payer will connect their account to any bank. Here is an example that must be followed by the merchant:

Authorization
The next step is to present the authorization settings that will be granted by the payer. It can be a screen that continues the list of banks or a separate screen, as long as it presents:
- Trigger. The description of the authorization that will be given by the payer to allow automated transactions.
- Regulatory disclaimer.
- A Call to Action button (“Mais configurações”) that optionally allows users to set transaction limits and the authorization period in the following steps.
Below is an example of this screen and, following, an explanation of each of the fields:

1. Trigger
It is necessary to present the payer with an explicit description of the authorization that will be given to allow automated transactions to happen. This trigger, or authorization, must represent the transactions that the merchant expects to make under the payer's authorization.
The required wording is: “A [merchant] poderá realizar transferências automáticas da minha conta bancária para adicionar saldo à minha conta dLocal e concluir pagamentos solicitados por mim.”
2. Regulatory disclaimer
One regulatory disclaimer is required before the user is redirected to the chosen bank for authorization:
- The message for the payer regarding the opening of the payment account that will be opened in the payer's name with dLocal, as well as the presentation for terms and conditions. The required wording is: “Ao confirmar, você concorda com a abertura de uma conta de pagamento na dLocal, de acordo com termos e condições disponíveis aqui.”
- The terms and conditions should be linked to the wording above and are available here.
3. Call to Action button
This refers to an option that must be presented to users as a button labeled "Mais configurações".
The button does not block the main payment flow. Users can choose to skip it if they do not want to customize any settings.
When the user clicks this button, they are taken to one or more screens where they can: set transaction limits and define the authorization period.
Transaction limits
These fields indicate the maximum limit the payer allows for payments. The limits can be:
total_allowed_amount
. The total amount that can be charged using this consent is in local currency.limit_per_payment
. Max amount allowed in each charge in local currency.periodic_limits
. Represents the maximum value for each periodic limit (day, week, month, year), which still counts the number of transactions allowed and the maximum value for each transaction.
Configuration options
There are 3 possible configurations regarding the transaction limits:
- The user can define all the limits. In this case, the payer can edit the limits on the limit editing screen. It's possible to create an authorization without defining these fields, which means that no authorization limits have been set. Therefore, payments can be requested in any amount and will not be blocked by this validation. Even so, the information that no limit has been set should be displayed on the screen.
- The Merchant defines a
limit_per_payment
. In this case, the Merchant will define thelimit_per_payment
and the payer will not have access to the limit editing screen, but we should display thelimit_per_payment
that was defined. Besides that, two regulatory messages must be displayed:- “Os próximos débitos serão no valor de produtos e serviços contratados por mim, com limite máximo de [R$ XXX,XX] por transação.”
- “Não é possível definir um limite para essa autorização.”
The limit value must be provided in the fieldlimit_per_payment
of the requests. All the other limit fields in the request should remain empty.
- All limits are undefined, and the merchant does not allow the payer to define them. In this case, the payer will not be able to access the limit editing screen, but we should display that no limit has been set. Moreover, two regulatory messages must be displayed:
- “Os limites são indefinidos para permitir que o valor de sua assinatura ou compra seja debitado.”
- “Não é possível definir um limite para essa autorização.”
All limit fields below in the request should remain empty:
{
"limit_per_payment": null,
"total_allowed_amount": null,
"periodic_limits": {
"day": {
"max_payments": null,
"total_allowed_amount": null
},
"week": {
"max_payments": null,
"total_allowed_amount": null
},
"month": {
"max_payments": null,
"total_allowed_amount": null
},
"year": {
"max_payments": null,
"total_allowed_amount": null
}
}
}
UX configurations
Here are examples of the screens for the three possible configurations.

Authorization period
The next setting is the duration of the authorization, for which the start date and end date must be displayed on screen for the payer.
wallet.recurring_info.start_date
indicates the start date of the authorization, and it is recommended to use the date when the authorization was created.wallet.recurring_info.end_date
indicates the expiry date of the authorization, which can be undefined, indicating that the authorization will not expire until the customer requests cancellation: i) from the merchant, ii) from dLocal, or iii) from their home banking.
The expiration date must always be editable by the payer.
Success screen
After the step described above, the user will be redirected to the bank to complete the authorization. Once this is successfully completed, dLocal will receive the redirect from the payer's bank and then redirect to the address indicated by the merchant, which will display the success screen.
In this step, it is required to show a confirmation screen in which the payer must be shown the authorization settings that have just been created (trigger, transaction limits, and term), in addition to the following information:
- Payer account data created in dLocal (branch and account number)
- Payer's name and tax ID
- Payment method: Pix
- Payment Initiation Service Provider: dLocal
- Authorization ID: identifier linking the payer to dLocal and its authorized bank.
- Regulatory disclaimer: “Importante: Os pagamentos sempre respeitarão os limites do seu banco ou os limites definidos aqui, o que for menor. Além disso, é necessário ter saldo em conta no momento em que cada pagamento é solicitado.”
Full screen content
It could be a single screen with all the information:

Expandable screen
Or a combination of a confirmation screen and a “More information” option that takes the payer to more information:

One-time user authorization
The one-time authorization requires the user to select their preferred bank at the merchant's checkout, being redirected to their online banking to authorize the use of their Pix account for future payments. dLocal will provide a token via API that links the user to their account for subsequent payments.
Get bank list
This service returns all enabled payment methods in a specified country, and for SmartPix, it provides a list of supported banks. Merchants must use it to display the bank list at checkout, allowing users to select their preferred bank to authorize future payments.
Example request
curl -X GET \
-H 'X-Date: 2022-09-01T17:30:04.310Z' \
-H 'X-Login: sak223k2wdksdl2' \
-H 'X-Trans-Key: fm12O7G9' \
-H 'Content-Type: application/json' \
-H 'X-Version: 2.1' \
-H 'User-Agent: MerchantTest / 1.0 ' \
-H 'Authorization: V2-HMAC-SHA256, Signature: 1bd227f9d892a7f4581b998c21e353b1686a6bdad5940e7bb6aa596c96e0a6ec' \
-d '{body}'
https://api.dlocal.com/payments-methods?country=BR
[
{
"id": "OS",
"type": "WALLET",
"name": "Smart Pix",
"logo": "https://static.dlocal.com/images/providers/OS.png",
"allowed_flows": [
"DIRECT",
"REDIRECT"
],
"details": {
"banks": [
{
"id": "213",
"name": "Banco Arbi S.A",
"logo": "https://static.dlocal.com/imagesbancoarbi.svg"
},
{
"id": "318",
"name": "Banco Bmg S.A",
"logo": "https://static.dlocal.com/images/bancobmg.svg"
},
{
"id": "1",
"name": "Banco do Brasil S.A",
"logo": "https://static.dlocal.com/images/bancodobrasil.svg"
},
{
"id": "612",
"name": "Banco Guanabara S.A.",
"logo": "https://static.dlocal.com/images/bancoguanabara.svg"
},
{
"id": "604",
"name": "Banco Industrial do Brasil S.A",
"logo": "https://static.dlocal.com/images/bancoindustrial.svg"
},
]
},
},
]
Path params
Query param | Required | Format | Description |
---|---|---|---|
country | Yes | ISO 3166-1 alpha-2 code | Country code for checking enabled payment methods and a list of banks for the specific SmartPix (OS ). |
Response params
Field | Type | Description |
---|---|---|
id | String | Id of the payment method. |
type | String | Type of the payment method WALLET . |
name | String | Name of the payment method. |
logo | String | Logo of the payment method. |
allowed_flows | Array of string | Flows allowed: DIRECT or REDIRECT . |
details.banks | Array of objects | List of supported banks. |
details.banks[].id | String | ID of the Bank. |
details.banks[].name | String | Name of the Bank. |
details.banks[].logo | String | Logo of the Bank. |
Authorization with or without charge (verify)
Once the user has selected their bank at the merchant's checkout, this service must be used if the merchant wants to perform a single authorization with or without a related payment. The user will be redirected to their online banking to authorize the use of their account for payments, for which Dlocal will return a valid token.
If the authorization has a related first payment, amount
should be >0
and verify
should be false. If the authorization has no first payment, the amount should be 0
and verify
should be true.
Example request
curl -X POST \
-H 'X-Date: {X-Date}' \
-H 'X-Login: {X-Login}' \
-H 'X-Trans-Key: {X-Trans-Key}' \
-H 'Content-Type: application/json' \
-H 'X-Version: 2.1' \
-H 'User-Agent: MerchantTest / 1.0 ' \
-H 'Authorization: V2-HMAC-SHA256, Signature: {Signature}' \
-d '{body}'
https://api.dlocal.com/payments
{
"amount": 0,
"currency": "BRL",
"country": "BR",
"payment_method_id": "OS",
"payment_method_flow": "DIRECT",
"payment_method_details": {
"bank_id": "318"
},
"payer": {
"name": "Thiago Gabriel",
"email": "[email protected]",
"document": "53033315550"
},
"wallet": {
"save": true,
"verify": true,
"recurring_info": {
"trigger": "A [merchant] poderá realizar transferências automáticas da minha conta bancária para adicionar saldo à minha conta dLocal e concluir pagamentos solicitados por mim.",
"start_date": "2024-11-01",
"end_date": "2028-12-30",
"limit_per_payment": 10000,
"total_allowed_amount": 90000,
"periodic_limits": {
"day": {
"max_payments": 1,
"total_allowed_amount": 1000
},
"week": {
"max_payments": 4,
"total_allowed_amount": 10000
},
"month": {
"max_payments": 10,
"total_allowed_amount": 30000
},
"year": {
"max_payments": 50,
"total_allowed_amount": 50000
}
}
}
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}
{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 0,
"currency": "BRL",
"payment_method_id": "OS",
"payment_method_type": "WALLET",
"payment_method_flow": "DIRECT",
"country": "BR",
"created_date": "2024-07-26T20:37:20.000+0000",
"status": "PENDING",
"status_detail": "The payment is pending.",
"status_code": "100",
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"redirect_url": "https://pay.dlocal.com/gmf-apm/payments-redirect/M-fd77f5b7-ca28-7u54-9ed8-ef89d374a80c"
}
Asynchronous notification (webhook)
{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 0,
"status": "VERIFIED",
"status_detail": "The payment was verified",
"status_code": "700",
"currency": "BRL",
"country": "BR",
"payment_method_id": "OS",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Thiago Gabriel",
"email": "[email protected]",
"document": "53033315550"
},
"creditor_account": {
"branch": "0001",
"number": "30200000003"
},
"wallet": {
"token": "979d887a-2c63-4719-ba65-0b20b50f1cab"
},
"order_id": "5346523564",
"notification_url": "http://www.merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback",
"created_date": "2024-07-26T20:37:20.000+0000"
}
{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 3200,
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"currency": "BRL",
"country": "BR",
"payment_method_id": "OS",
"payment_method_type": "WALLET",
"payment_method_flow": "DIRECT",
"payer": {
"name": "Thiago Gabriel",
"email": "[email protected]",
"document": "53033315550"
},
"wallet": {
"token": "979d887a-2c63-4719-ba65-0b20b50f1cab"
},
"order_id": "5346523566",
"notification_url": "http://www.merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback",
"created_date": "2024-08-10T20:37:20.000+0000"
}
Request params
Field | Required | Type & Length | Description |
---|---|---|---|
amount | Yes | Number Length: 10,2 | Set amount=0 to execute an authorization with no charge. Set amount>0 to execute an authorization with charge. |
currency | Yes | Three-letter ISO-4217 currency code | Transaction currency: BRL . |
country | Yes | ISO 3166-1 alpha-2 code | Payment processing country: BR . |
payment_method_id | Yes | String | ID of the selected payment method: OS . |
payment_method_flow | Yes | String | REDIRECT |
payment_method_details.bank_id | Yes | String | ID of the bank selected by the user. |
payer.name | Yes | String (max. 100) | Payer’s name. |
payer.email | Yes | String (max. 100) | Payer’s email. |
payer.document | Yes | Number (between 7 or 11 digits) | Payer’s document. |
wallet.save | No | Boolean | Set wallet.save=true so the asynchronous notification will include a wallet.token , which has to be used for further payments. Default false . |
wallet.verify | No | Boolean | Set wallet.verify=true to execute an authorization with no charge. |
wallet.recurring_info.trigger | Yes | String | Description of the authorization given by the payer that allows automatic payment. |
wallet.recurring_info.start_date | No | String | Date of the first charge (YYYY-MM-DD). Default today's date. |
wallet.recurring_info.end_date | No | String | Date of the last charge (YYYY-MM-DD). |
wallet.recurring_info.limit_per_payment | No | Number Length: 10,2 | Max amount allowed in each charge in local currency. |
wallet.recurring_info..total_allowed_amount | No | Number Length: 10,2 | Total allowed amount to be charged using this consent in local currency. |
wallet.recurring_info.periodic_limits | No | Array of objects | Possible values: day , week , month , year |
period | Yes | String (enum) | Period for the limit: day , week , month , or year |
max_payments | No | Number Length: 10,2 | Max number of transactions of that period. |
total_allowed_amount | No | Number Length: 10,2 | Total allowed amount of that period in local currency. |
order_id | No | String (max. 125) | ID given by the merchant in their system. |
notification_url | No | String (max. 200) | Notifications will be sent for every change of status of a payment to this URL. |
Response params
Field | Type | Description |
---|---|---|
creditor_account.branch | String | dLocal branch where the account was opened. |
creditor_account.number | String | Number assigned to the payment account. |
wallet.token | String | Token generated for future payments of the user based on the authorization made in their online banking. |
Updated 32 minutes ago