Wallet payments
Wallet payments (WALLET) let users pay by authenticating with their wallet provider (the wallet app or service that confirms the payment).
Do not start new integrations on the legacy wallet token modelIf you are integrating for the first time, use the Enrollment API for all tokenized and recurring wallet flows. The legacy
wallet.tokenmodel is supported for existing merchants only. It does not receive new feature development. Starting on the legacy model might require a migration later.
For tokenized/recurring flows, dLocal supports two integration models:
- Enrollment API (use this for all new integrations): The user completes a one-time redirect to authorize future payments. dLocal returns an enrollment ID used for all subsequent direct charges. No redirect or re-authentication required.
- Legacy wallet token (existing merchants only): The user completes a redirect and the webhook returns a
wallet.token. No new integrations should use this model. See Tokenized wallets: Legacy.
Prerequisites
Complete these steps before you create a wallet payment:
- Use the Create payment endpoint for one-time wallet payments and legacy token enrollment. Use the Create enrollment endpoint for new Enrollment API integrations.
- Identify the wallet
payment_method_idfor the user's country in the Payment method section. - Set
payment_method_flowbased on the payment flow:- Use
REDIRECTfor one-time payments and enrollment. - Use
DIRECTonly after you receive and store a validwallet.token(legacy) or anACTIVEenrollment ID (Enrollment API).
- Use
- Include
notification_urlto receive the final asynchronous payment or enrollment status. - Include
callback_urlforREDIRECTflows so the wallet provider can return the user to your site. - Include
device.typefor allREDIRECTrequests.
Related references
Use these pages when you build and validate your integration:
- Create payment: create one-time wallet payments, legacy token enrollments, and recurring
DIRECTcharges. - Create enrollment: create enrollments using the Enrollment API (recommended for new integrations).
- Get enrollment: retrieve enrollment status. Use this to check the current state if you miss an enrollment webhook.
- Cancel an enrollment: cancel an active enrollment when a user unsubscribes or changes their payment method.
- The wallet object: review the supported
walletfields for the legacy flow, includingsave,verify,capture, andtoken. - Payment method section: confirm wallet availability, country support, and payment-method-specific requirements.
- Receive notifications: implement webhook handling for asynchronous
PENDING,PAID,REJECTED,VERIFIED, andACTIVEupdates. - Cancel a
wallet.token: cancel a stored legacy token when a user cancels or changes their payment method.
Available wallets
To integrate wallet payments, identify each wallet you want to support and set its payment_method_id in the payment request.
Payment method listGet the payment method list or view all available wallets by country in the Payment method section.
Payment flow
Choose one of these flows based on whether you need a one-time payment or future DIRECT charges.
| Flow | Description | Best for |
|---|---|---|
One-time payments (REDIRECT) | Redirect the user to the wallet's website to authenticate and complete the payment. After authentication, the wallet provider redirects the user back to your site. dLocal does not issue a token. | One-time purchases |
Tokenized (recurring) payments: Enrollment API (REDIRECT, then DIRECT) 🆕 | Redirect the user once to authorize future payments via the Create enrollment endpoint. dLocal returns an enrollment ID. Use it for subsequent DIRECT payments without redirecting the user again. | Subscriptions, recurring billing. Recommended for new integrations. |
Tokenized (recurring) payments: Legacy (REDIRECT, then DIRECT) ❗ | Redirect the user to the wallet's website to authenticate and authorize future payments. Send wallet.save = true in the request. The asynchronous notification includes a wallet.token. Use that token for subsequent DIRECT payments. Do not use for new integrations. See Tokenized wallets: Legacy. | Existing merchants only. No new integrations. |
One-time payments
In this flow, redirect the user to the wallet's app/website to authenticate and complete the payment.
Sale
{
"amount": 26,
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"device": {
"type": "WEB"
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 26,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"country": "BR",
"created_date": "2018-12-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-0aa0cc00-..."
}{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 26,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"country": "BR",
"created_date": "2018-12-26T20:37:20.000+0000",
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications"
}After you receive the synchronous response, redirect the user to redirect_url. dLocal sends the final PAID or REJECTED status by webhook to your notification_url.
Tokenized wallets: Enrollment API
Recommended for new integrationsUse the Enrollment API to establish a reusable authorization. All subsequent charges go directly, with no redirect or re-authentication required. For method-specific parameters, see Yape Recurring and Pix with Biometrics.
The Enrollment API supports two integration patterns:
| Pattern | When to use |
|---|---|
Enrollment only (POST /enrollments) | Establish the user authorization without an initial charge. Use when enrollment and first payment happen at different steps. |
Payment + Enrollment in the same request (POST /payments with enrollment object) | Create a payment and establish the authorization in a single API call. Use when the first charge and enrollment happen simultaneously. |
Enrollment only
Use POST /enrollments when you want to create the enrollment without an initial payment. See the full Create enrollment API reference for all available fields.
Enrollment types:
The valid type values depend on the payment method. Not all payment methods support all types.
ON_DEMAND: Merchant initiates recurring payments at any time, with no frequency or amount restrictions. Valid for all enrollment-capable payment methods.MERCHANT_SUBSCRIPTION: Merchant initiates recurring payments based on defined subscription settings (frequency, amount, dates). Only valid for payment methods that expose a structured subscription protocol (for example, Pix Automático). See the individual payment method pages to confirm which type applies.
external_id
external_idis your internal identifier for the enrollment. It appears in all enrollment webhooks, letting you correlate dLocal enrollment events back to your own records.
{
"currency": "BRL",
"country": "BR",
"type": "ON_DEMAND",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"document": "<DOCUMENT_NUMBER>",
"email": "[email protected]"
},
"device": {
"type": "WEB"
},
"external_id": "<YOUR_EXTERNAL_ID>",
"description": "Subscription enrollment",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}{
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"external_id": "<YOUR_EXTERNAL_ID>",
"currency": "BRL",
"country": "BR",
"type": "ON_DEMAND",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "REDIRECT",
"created_date": "2025-12-26T20:37:20.000+0000",
"status": "PENDING",
"status_detail": "The enrollment is pending.",
"status_code": "100",
"redirect_url": "https://pay.dlocal.com/gmf-apm/payments/E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"notification_url": "http://merchantsite.com/notifications"
}{
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"external_id": "<YOUR_EXTERNAL_ID>",
"currency": "BRL",
"country": "BR",
"type": "ON_DEMAND",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "REDIRECT",
"created_date": "2025-12-26T20:37:20.000+0000",
"status": "ACTIVE",
"status_detail": "The enrollment is active.",
"status_code": "200",
"notification_url": "http://merchantsite.com/notifications"
}After receiving the synchronous response, redirect the user to redirect_url. The user completes authorization with their wallet provider. dLocal then sends the enrollment webhook to your notification_url with the final status.
callback_url behaviorWhen and how the user lands on
callback_urlafter completing the enrollment redirect depends on the payment method. See the individual payment method pages for specifics.
Enrollment IDOnce the enrollment status is
ACTIVE, theidfield (for example,E-4-32e1218f-...) is your enrollment ID. Persist it: it must be included in all subsequent recurring payment requests for this user.To check the current enrollment status at any time (for example, if your server was temporarily unavailable), use the Get enrollment endpoint.
To cancel an enrollment, use the Cancel an enrollment endpoint.
Enrollment status codes:
For the full list of enrollment status_code values and their meanings, see the Get enrollment and Create enrollment API references.
status | status_code | Description |
|---|---|---|
PENDING | 100 | The enrollment has been created and is awaiting user authorization. |
ACTIVE | 200 | The user completed authorization. The enrollment ID is ready to use for recurring charges. |
CANCELLED | 400 | The enrollment was cancelled. |
REJECTED | 300 | The user did not complete or declined the authorization. |
Examples contain placeholdersReplace
<PM_CODE>with thepayment_method_idof the wallet you are integrating (for example,YEfor Yape Recurring). See the Payment method section for all available IDs.
Payment + Enrollment in the same request
Include an enrollment object in a POST /payments call to create a payment and an enrollment in one request. Use this pattern when the first charge and enrollment happen simultaneously. See the Create payment and Create enrollment API references for all available fields.
Payment method-specific requirementsThe example below uses
payment_method_flow: "DIRECT"as a generic skeleton. For Yape (YE), the first enrollment+payment request must usepayment_method_flow: "REDIRECT".Yape requires a user redirect for first-time authorization. See the Yape Recurring section for the correct Yape-specific example.
Yape also requires
device.typein all enrollment requests, andpayer.phoneis mandatory whendevice.typeisWEB.
{
"amount": 285,
"currency": "BRL",
"country": "BR",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "DIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"device": {
"type": "WEB"
},
"enrollment": {
"external_id": "<YOUR_EXTERNAL_ID>",
"type": "ON_DEMAND",
"description": "Monthly subscription authorization",
"notification_url": "https://merchantsite.com/enrollment_notifications",
"callback_url": "https://merchantsite.com/enrollment_callback"
},
"order_id": "ord-221124442ab",
"notification_url": "https://merchantsite.com/payments",
"callback_url": "https://merchantsite.com/payment_callback"
}{
"id": "R-4-22112444-2ab0-4f5g-6h7i-8j9k0l1m2n3o",
"amount": 285,
"currency": "BRL",
"country": "BR",
"payment_method_id": "<PM_CODE>",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"created_date": "2024-07-26T20:37:20.000+0000",
"status": "PENDING",
"status_detail": "The payment is pending.",
"status_code": "100",
"order_id": "ord-221124442ab",
"notification_url": "https://merchantsite.com/payments",
"redirect_url": "https://pay.dlocal.com/gmf-apm/payments-redirect/M-0aa0cc00-...",
"enrollment": {
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"external_id": "<YOUR_EXTERNAL_ID>",
"created_date": "2024-07-26T20:37:20.000+0000",
"status": "PENDING",
"status_detail": "The enrollment is pending.",
"status_code": "100"
}
}{
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"external_id": "<YOUR_EXTERNAL_ID>",
"currency": "BRL",
"country": "BR",
"type": "ON_DEMAND",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "REDIRECT",
"created_date": "2024-07-26T20:37:20.000+0000",
"status": "ACTIVE",
"status_detail": "The enrollment is active.",
"status_code": "200",
"notification_url": "https://merchantsite.com/enrollment_notifications"
}{
"id": "R-4-22112444-2ab0-4f5g-6h7i-8j9k0l1m2n3o",
"amount": 285,
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"currency": "BRL",
"country": "BR",
"payment_method_id": "<PM_CODE>",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"enrollment": {
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4",
"external_id": "<YOUR_EXTERNAL_ID>"
},
"order_id": "ord-221124442ab",
"notification_url": "https://merchantsite.com/payments",
"created_date": "2024-07-26T20:37:20.000+0000"
}
Single request, dual outcomeThis request produces two independent asynchronous notifications: one for the enrollment (sent to
enrollment.notification_url) and one for the payment (sent tonotification_url). They may arrive in any order. Persist theenrollment.idonly after the enrollment notification reachesACTIVEstatus. Grant entitlement only after the payment notification reachesPAIDstatus.
Recurring charges with an enrollment ID
Once the enrollment is ACTIVE, charge the user directly. Add enrollment.id inside an enrollment object in subsequent POST /payments calls. No redirect or re-authentication required. See the Create payment API reference for the full list of fields.
{
"amount": 26,
"currency": "BRL",
"country": "BR",
"payment_method_id": "<PM_CODE>",
"payment_method_flow": "DIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"enrollment": {
"id": "E-4-32e1218f-b6ec-3f21-13d5-50v12ere2ca4"
},
"order_id": "ord-221124442cd",
"notification_url": "https://merchantsite.com/payments"
}{
"id": "R-4-55ab7891-cd12-4ef3-ab56-789012cdef34",
"amount": 26,
"currency": "BRL",
"country": "BR",
"payment_method_id": "<PM_CODE>",
"payment_method_type": "WALLET",
"payment_method_flow": "DIRECT",
"created_date": "2024-07-27T10:15:00.000+0000",
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"order_id": "ord-221124442cd",
"notification_url": "https://merchantsite.com/payments"
}
Final status is payment-method-specificFor most wallets (Mercado Pago, Nequi, and NuPay, for example), the synchronous response to a
DIRECTcharge is the final status (PAIDorREJECTED), as shown above. Yape (YE) is the exception: it always returnsPENDINGsynchronously, and dLocal delivers the final status by webhook within seconds. Always confirm per-payment-method behavior in the relevant country section before implementing.
Tokenized wallets: Legacy
Legacy integrationThe wallet object tokenization flow below is supported for existing merchants only and does not receive new feature development. New integrations must use the Enrollment API described above.
The enrollment and recurring charge are two separate API calls.
Step 1: Enrollment (REDIRECT)
REDIRECT)Redirect the user to the wallet's website to authenticate and authorize future payments. Send wallet.save = true in the request. The asynchronous notification includes a wallet.token. Use that wallet.token for future payments without authenticating the user again. See The wallet object for the supported wallet fields.
Option A: Sale + verify flow
Enroll and charge simultaneously (wallet.verify: false, amount > 0). Use this option to charge the user and issue a wallet.token in the same flow.
{
"amount": 26,
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"wallet": {
"save": true,
"verify": false,
"capture": true
},
"device": {
"type": "WEB"
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 26,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"country": "BR",
"created_date": "2018-12-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-0aa0cc00-..."
}{
"id": "R-4-41f8628f-b6ec-4c02-96d5-c5b03cac7cb0",
"amount": 26,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"country": "BR",
"created_date": "2018-12-26T20:37:20.000+0000",
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"order_id": "5346523564",
"wallet": {
"token": "<WALLET_TOKEN>"
},
"notification_url": "http://merchantsite.com/notifications"
}
Payment failed, enrollment succeededThe notification includes a
wallet.tokenas long as the user authenticated successfully, regardless of whether dLocal approved the payment.
Option B: Verify flow
Enroll without charging (wallet.verify: true, amount: 0). dLocal verifies the wallet and issues a wallet.token without making a charge. Use this for free trials or deferred billing.
{
"amount": 0,
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"wallet": {
"save": true,
"verify": true,
"capture": false
},
"device": {
"type": "WEB"
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}{
"id": "D-4-75c7473a-ab86-4e43-bd39-c840268747d3",
"amount": 0,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"country": "BR",
"created_date": "2018-12-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-0aa0cc00-..."
}{
"id": "D-4-75c7473a-ab86-4e43-bd39-c840268747d3",
"amount": 0,
"status": "VERIFIED",
"status_detail": "The wallet was verified.",
"status_code": "700",
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"wallet": {
"token": "<WALLET_TOKEN>"
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"created_date": "2018-12-26T20:37:20.000+0000"
}Expect the asynchronous response at notification_url after the user approves the enrollment in the wallet provider.
Persist wallet.token for all future charges. Only store tokens from VERIFIED (700) or PAID (200) status. Tokens from rejected flows are invalid.
Step 2: Recurring charge (DIRECT)
DIRECT)Pay with a wallet.token. The request does not redirect the user.
Recurring wallet paymentsFor recurring wallet payments in the Philippines and Indonesia, include the user's mobile number in the
payer.phonefield of the payment request.
{
"amount": 10,
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_flow": "DIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"phone": "<PHONE_NUMBER>",
"document": "<DOCUMENT_NUMBER>",
"address": {
"country": "BR",
"state": "Example State",
"city": "Example City",
"zip_code": "<ZIP_CODE>",
"street": "Example Street",
"number": "123"
}
},
"wallet": {
"token": "<WALLET_TOKEN>"
},
"order_id": "fe32a6ef-3954-4b5f-8712-d1c1079beba3",
"description": "test-wallet",
"notification_url": "https://notifications.merchant.com"
}{
"id": "F-4-b302affe-e590-4b29-98cc-57ec2dd10592",
"amount": 10,
"currency": "BRL",
"payment_method_id": "PZ",
"payment_method_type": "WALLET",
"payment_method_flow": "DIRECT",
"country": "BR",
"created_date": "2022-09-29T06:52:48.000+0000",
"expiration_date": "2022-10-04T06:52:48.000+0000",
"status": "PAID",
"status_detail": "The payment was paid.",
"status_code": "200",
"order_id": "fe32a6ef-3954-4b5f-8712-d1c1079beba3",
"description": "test-wallet",
"notification_url": "https://notifications.merchant.com"
}
Synchronous responseFor most wallets, the synchronous response to a
DIRECTcharge is the final status (PAIDorREJECTED). No need to wait for a notification. Yape (YE) is the exception: it returnsPENDINGsynchronously, and dLocal delivers the final status by webhook within seconds.Always confirm per-payment-method behavior in the relevant section.
Device ID for Mercado PagoAdd the Device ID by following The DeviceId Object (for Mercado Pago only).
Include it in the wallet object. It improves fraud detection on Mercado Pago's side and can improve authorization rates.
Cancel a wallet.token
wallet.tokenCancel with the API
Call the cancel endpoint when a user unsubscribes, changes their payment method, or you need to cancel access programmatically.
See Cancel a wallet.token in the API reference section.
curl --request POST \
--url "https://api.dlocal.com/payments/wallet/<WALLET_TOKEN>/cancel"{
"wallet": {
"token": "<WALLET_TOKEN>"
},
"status": "CANCELLED",
"status_detail": "The wallet token was cancelled."
}Customer-initiated cancellation
Users can cancel a subscription or recurring authorization directly from their wallet app (Nequi, GCash, Mercado Pago, and Yape, for example). The behavior when this happens depends on which integration model you are using:
Enrollment API: The next DIRECT charge attempt returns status_code 328 when the enrollment has been cancelled. Handle 328 by stopping all future charge attempts against that enrollment ID and triggering a new enrollment flow for the user. You can also use the Cancel an enrollment endpoint proactively when a user unsubscribes on your side, so the enrollment is invalidated at dLocal before the next scheduled charge runs.
Legacy wallet token: The next DIRECT charge attempt using the cancelled wallet.token returns status_code 328 (invalid token). Handle 328 by stopping all future charge attempts and triggering a new enrollment flow. Always call the cancel token endpoint on your side when a user unsubscribes so your records stay in sync with the wallet provider.
Cancellation, whether merchant-initiated or customer-initiated, permanently invalidates the wallet.token or enrollment reference. Never retry a 328.
How wallet providers notify dLocal of user-initiated cancellations:
Not all wallet providers behave the same way when a user cancels access from within their app:
Proactive notification: The wallet provider notifies dLocal in real time. dLocal sends a webhook to your Payins Notification URL configured in dLocal's merchant dashboard to confirm that the authorization has been canceled. Listen for this webhook and update your records before the next scheduled charge.
Silent cancellation: The wallet provider does not notify dLocal. Your integration discovers the cancellation when the next DIRECT charge attempt returns status_code 328. Stop retrying and start a new enrollment flow.
Device type
Include device.type in all REDIRECT flows where the user is present, including both POST /payments and POST /enrollments. Wallet providers can use different experiences, such as deep links, app-to-app redirects, or push notifications. dLocal uses this field to route the best experience for each context without requiring integration changes.
Omit device.type from DIRECT charges that use a wallet.token or an enrollment.id reference. Those are customer-not-present requests.
| Value | Description |
|---|---|
WEB | The user is on a desktop or mobile browser. |
MOBILE_APP | The user is inside your native iOS or Android app. |
{
"amount": 26,
"currency": "BRL",
"country": "BR",
"payment_method_id": "PZ",
"payment_method_flow": "REDIRECT",
"payer": {
"name": "Example Payer",
"email": "[email protected]",
"document": "<DOCUMENT_NUMBER>"
},
"device": {
"type": "MOBILE_APP"
},
"order_id": "5346523564",
"notification_url": "http://merchantsite.com/notifications",
"callback_url": "http://merchantsite.com/callback"
}For payment methods where device.type is already mandatory, such as Yape, see the payment-method-specific sections for full behavior details.
Sandbox testing
Use the description field in your request body to control payment behavior in the sandbox environment.
Enrollment flows (REDIRECT)
REDIRECT)description value | Behavior |
|---|---|
| Omitted | Returns PENDING. Use the mock playground UI to manually approve or reject. Recommended for UX testing. |
"100:approved" | Returns PENDING, then auto-sends a PAID (or VERIFIED / ACTIVE) webhook after ~60 seconds. Recommended for automated testing. |
"100:rejected" | Returns PENDING, then auto-sends a REJECTED webhook after ~60 seconds. |
Recurring charges (DIRECT)
DIRECT)description value | Behavior |
|---|---|
"200" | Returns PAID immediately. |
"300" | Returns REJECTED immediately. |
Mock server vs. real provider environmentBy default, all sandbox payments are routed through dLocal's mock server, which provides stable, predictable behavior across all wallet payment methods. If you need to test against the actual sandbox environment of a specific wallet provider to validate provider-side behavior or UX, check with your assigned dLocal TAM. Some providers require additional configuration or have limited sandbox availability.
