# MD for: https://www.mercadopago.com.br/developers/en/docs/wallet-connect/configure-agreements.md \# Configure agreements An agreement is the authorization granted by the buyer that allows the seller to debit payments directly from their Mercado Pago wallet, without requiring a login for each transaction. It is the first step of the Wallet Connect integration and is mandatory before processing any payment. The flow consists of three stages: creating the agreement, obtaining the buyer's approval, and generating the payment token. Once completed, you will have the \`payer\_token\`, a credential that authorizes the charges described in the \[Process payments section\](https://www.mercadopago.com.br/developers/en/docs/wallet-connect/process-payments). > NOTE > > The same agreement can be used for multiple payments while it remains active, which means there is no need to repeat the authorization flow for each new charge. :::::AccordionComponent{title="Create agreement" pill="1"} Creating the agreement generates the authorization link that must be presented to the buyer so they can grant the seller access to their Mercado Pago wallet. Two flows are available: \*\*Standard\*\*, in which the buyer completes the authorization in the browser, and \*\*Sniffing\*\*, which attempts to open the authorization directly in the Mercado Pago app on mobile devices. Compare the options below and choose the one that best suits your integration. ::::TabsComponent :::TabComponent{title="Standard"} In the standard flow, the buyer authorizes access to their Mercado Pago wallet in the browser and may need to log in manually. To create an agreement without redirecting the buyer to the Mercado Pago app, send a \*\*POST\*\* to the endpoint :TagComponent{tag="API" text="/v2/wallet\_connect/agreements" href="/developers/en/reference/online-payments/wallet-connect/orders/create-agreement/post" color="accent"}, including your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."} and the parameters indicated below. \`\`\`curl curl -X POST \\ 'https://api.mercadopago.com/v2/wallet\_connect/agreements' \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \\ -d '{ "return\_uri": "https://www.mercadopago.com/", "external\_flow\_id": "{{EXTERNAL\_FLOW\_ID}}", "external\_user": { "id": "usertest", "description": "Test account" }, "agreement\_data": { "validation\_amount": 3.14, "description": "Test agreement" } }' \`\`\` See the table below for descriptions of the parameters that are mandatory in the request and those that, although optional, have some important particularity that should be highlighted. | Parameter | Type | Description | Requirement | |---|---|---|---| | \`Authorization\` | \_Header\_ | Refers to your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."}. | Required | | \`return\_uri\` | \_Body. String\_ | URI to which the buyer will be redirected upon completing the agreement flow. This is the address where you will receive the authorization result as query parameters. The maximum limit is 2048 characters and the value sent must match a URI previously registered for the application. | Required | | \`external\_flow\_id\` | \_Body. String\_ | Seller's internal identifier for the current flow state. Use it to correlate the agreement result with the purchase session in your system. The maximum limit is 64 characters. | Required | | \`external\_user.id\` | \_Body. String\_ | Seller's unique identifier for the buyer. The maximum limit is 256 characters and the value must not contain sensitive data. | Required | | \`external\_user.description\` | \_Body. String\_ | Label for the buyer in the seller's system, such as their name. The maximum limit is 256 characters. | Optional | | \`agreement\_data.validation\_amount\` | \_Body. Number\_ | Reference amount for the agreement. If the buyer's account balance is insufficient to cover this amount, a card will be required as a secondary payment method during the authorization. We recommend sending a value close to the average ticket of your charges. | Optional | | \`agreement\_data.description\` | \_Body. String\_ | Description of the actions the buyer is about to authorize, displayed during the approval flow. The maximum limit is 256 characters. | Optional | If the request is successful, the response will return status 201 with the identifier of the created agreement and the authorization URI to be presented to the buyer. \`\`\`json { "agreement\_id": "22abcd1235ed497f945f755fcaba3c6c", "agreement\_uri": "{{wc\_agreement\_uri\_example}}" } \`\`\` Among the returned parameters, we have those indicated in the table below. | Parameter | Type | Description | |---|---|---| | \`agreement\_id\` | \_String\_ | Unique identifier of the created agreement. Store it, as it is required to generate the payment token and to query or cancel the agreement. | | \`agreement\_uri\` | \_String\_ | URI to which the buyer must be redirected in order to authorize access to their wallet. See the \[Obtain buyer approval\](https://www.mercadopago.com.br/developers/en/docs/wallet-connect/configure-agreements#bookmark\_obtain\_buyer\_approval) stage to learn how to use it. | ::: :::TabComponent{title="Sniffing"} \*\*Sniffing\*\* is a feature that detects whether the buyer has the Mercado Pago app installed on their mobile device and, if so, opens the agreement flow directly in the app. Since the buyer is already authenticated there, the authorization is granted without having to enter credentials manually, which reduces friction and drop-off at this stage. > WARNING > > The use of sniffing must be previously coordinated with the \*\*Mercado Pago Integrations team\*\*, responsible for configuring the feature in your application. Disabling it must also be coordinated with the same team. Two implementation models are available. See the characteristics of each one in the table below and choose the one that best suits your business model. | Model | Availability | Behavior | |---|---|---| | \*\*App Link\*\* | Android devices only | The Mercado Pago app intercepts the navigation to the \`agreement\_uri\` and automatically opens the agreement flow in the app's context. | | \*\*Browser\*\* | Android and iOS devices | When opening the \`agreement\_uri\` in the browser, the page recognizes the context and applies different strategies to try to open the Mercado Pago app. If it is installed, the agreement flow opens in it. Otherwise, the buyer is directed to the default browser and may need to log in manually. \*\*This model is only available in mobile browsers when the buyer has the Mercado Pago app installed and generally requires confirmation in a system modal.\*\* | !\[sniffing\](/images/wallet-connect/sniffing-pt-v1.png) To create the agreement with sniffing enabled, send a \*\*POST\*\* to the endpoint :TagComponent{tag="POST" text="/v2/wallet\_connect/agreements" href="/developers/en/reference/online-payments/wallet-connect/orders/create-agreement/post" color="green"}, including your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."} and the parameters indicated below. \`\`\`curl curl -X POST \\ 'https://api.mercadopago.com/v2/wallet\_connect/agreements' \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \\ -d '{ "return\_uri": "https://www.mercadopago.com/", "external\_flow\_id": "{{EXTERNAL\_FLOW\_ID}}", "external\_user": { "id": "usertest", "description": "Test account" }, "agreement\_data": { "validation\_amount": 3.14, "description": "Test agreement" } }' \`\`\` See the table below for descriptions of the parameters that are mandatory in the request and those that, although optional, have some important particularity that should be highlighted. | Parameter | Type | Description | Requirement | |---|---|---|---| | \`Authorization\` | \_Header\_ | Refers to your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."}. | Required | | \`return\_uri\` | \_Body. String\_ | URI to which the buyer will be redirected upon completing the agreement flow. This is the address where you will receive the authorization result as query parameters. The maximum limit is 2048 characters and the value sent must match a URI previously registered for the application. | Required | | \`external\_flow\_id\` | \_Body. String\_ | Seller's internal identifier for the current flow state. Use it to correlate the agreement result with the purchase session in your system. The maximum limit is 64 characters. | Required | | \`external\_user.id\` | \_Body. String\_ | Seller's unique identifier for the buyer. The maximum limit is 256 characters and the value must not contain sensitive data. | Required | | \`external\_user.description\` | \_Body. String\_ | Label for the buyer in the seller's system, such as their name. The maximum limit is 256 characters. | Optional | | \`agreement\_data.validation\_amount\` | \_Body. Number\_ | Reference amount for the agreement. If the buyer's account balance is insufficient to cover this amount, a card will be required as a secondary payment method during the authorization. We recommend sending a value close to the average ticket of your charges. | Optional | | \`agreement\_data.description\` | \_Body. String\_ | Description of the actions the buyer is about to authorize, displayed during the approval flow. The maximum limit is 256 characters. | Optional | > WARNING > > The URL provided in \`return\_uri\` must point to a web resource, which means deeplinks cannot be used, and \*\*its beginning must match the return URL configured in the seller's application\*\*. For more information, refer to \[Application details\](https://www.mercadopago.com.br/developers/en/guides/additional-content/your-integrations/application-details). When receiving the \`agreement\_uri\` in the response, use an \*\*In-App Browser\*\* component to navigate to it, instead of opening it directly in the browser. Depending on the operating system, use \*\*Custom Tabs\*\* on Android devices and \*\*SVC\*\* (Safari View Controller) on iOS devices. From there, the flow proceeds normally: the buyer is redirected to the \`return\_uri\` with the authorization code, as described in the following stages. ### Context change during sniffing When sniffing happens, the user leaves your application's context (the Custom Tab on Android or the SVC on iOS) and is taken to the Mercado Pago or Mercado Libre app to complete the agreement. This has implications that you should consider when designing your flow: - Your application loses control of the interface while the user links the account in the Mercado Pago or Mercado Libre app. You will not receive intermediate events from the In-App Browser, only the final return through the \`return\_uri\`. - The return depends on the \`return\_uri\`. After the user confirms the agreement, Mercado Pago attempts to return to your application by opening the \`return\_uri\`. If you configured a verified App Link on Android or a verified Universal Link on iOS, the return opens your native application directly; otherwise, it opens the user's default browser. - Listen to the agreement webhook instead of relying only on the interface return. The agreement status advances to \`WAITING\_SELLER\_CONFIRMATION\` when the user approves it, even if they never return to your application. Confirming the agreement from the backend is more reliable than depending on the visual callback. ::: :::: ::::: :::AccordionComponent{title="Obtain buyer approval" pill="2"} After creating the agreement, redirect the buyer to the \`agreement\_uri\` returned in the response. At that URL, the buyer grants authorization for the seller to use their Mercado Pago wallet as a payment method. When the flow ends, Mercado Pago redirects the buyer to the \`return\_uri\` provided at creation, adding the operation result as query parameters. - If the authorization is granted, the \`return\_uri\` will be called in the format below. \`\`\` \`{return\_uri}?agreement\_id={agreement\_id}&code={code}&flow=agreement&external\_flow\_id={external\_flow\_id}&code\_type=validation\_code\` \`\`\` - If the buyer rejects or cancels the authorization, the \`return\_uri\` will be called in the format below, without the \`code\` parameter and with the \`error\` parameter. \`\`\` \`{return\_uri}?agreement\_id={agreement\_id}&flow=agreement&external\_flow\_id={external\_flow\_id}&error={error}\` \`\`\` See the table below for descriptions of the returned parameters. | Parameter | Type | Description | |---|---|---| | \`agreement\_id\` | \_String\_ | Unique identifier of the authorized agreement. | | \`code\` | \_String\_ | Authorization code used to generate the payment token. It is a 32-character lowercase alphanumeric code with a limited validity window. | | \`flow\` | \_String\_ | Identifies the flow that originated the redirect. Always returns the fixed value \`agreement\`. | | \`external\_flow\_id\` | \_String\_ | Seller's internal identifier, returned as sent when creating the agreement. | | \`code\_type\` | \_String\_ | Indicates the type of code returned. Always returns the fixed value \`validation\_code\`. | | \`error\` | \_String\_ | Reason why the agreement was not completed. Returns the fixed value \`access\_denied\`, which indicates that the buyer rejected or cancelled the authorization. | > NOTE > > When the agreement is confirmed, a webhook notification with the approval details will also be sent. See the \[Configure notifications\](https://www.mercadopago.com.br/developers/en/docs/wallet-connect/notifications) section to learn how to receive it. ::: :::AccordionComponent{title="Generate payment token" pill="3"} The payment token (\`payer\_token\`) is the credential that represents the buyer's authorization and allows the seller to execute charges from their wallet. This is the last stage of the agreement flow. The \`code\` parameter required to generate it can be obtained in two ways: as a query parameter in the \`return\_uri\` (recommended) or from the agreement confirmation webhook. > NOTE > > We recommend implementing webhook listening as a fallback to increase the number of completed agreements. To generate the token, send a \*\*POST\*\* to the endpoint :TagComponent{tag="API" text="/v2/wallet\_connect/agreements/{agreement\_id}/payer\_token" href="/developers/en/reference/online-payments/wallet-connect/orders/generate-payer-token/post" color="accent"}, including your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."}, the \`agreement\_id\` obtained at its creation, and the authorization code. \`\`\`curl curl -X POST \\ 'https://api.mercadopago.com/v2/wallet\_connect/agreements/{{AGREEMENT\_ID}}/payer\_token' \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \\ -d '{ "code": "{{AUTHORIZATION\_CODE}}" }' \`\`\` See the table below for descriptions of the parameters that must be sent in this request. | Parameter | Type | Description | Requirement | |---|---|---|---| | \`Authorization\` | \_Header\_ | Refers to your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."}. | Required | | \`agreement\_id\` | \_Path. String\_ | Unique identifier of the agreement, obtained in the response to its creation. | Required | | \`code\` | \_Body. String\_ | Authorization code generated during the agreement flow. It must be a 32-character lowercase alphanumeric string and can be used only once, within its validity window. | Required | If the request is successful, the response will return status 201 with the payment token associated with the agreement. \`\`\`json { "payer\_token": "abcdef1e23f4567d8e9123eb6591ff68df74c57930551ed980239f4538a7e530" } \`\`\` | Parameter | Type | Description | |---|---|---| | \`payer\_token\` | \_String\_ | Token that represents the buyer's authorization for the seller to process payments from their wallet. It must be sent in the \`transactions.payments.payment\_method.token\` field for each charge. | > WARNING > > Store the \`payer\_token\` securely, as it will be used for all payments from this buyer while the agreement remains active. The same \`code\` cannot be reused to generate a new token: if the agreement is cancelled, the entire authorization flow must be repeated. ::: :::AccordionComponent{title="Cancel agreement" pill="Optional"} Cancelling revokes the authorization granted by the buyer and invalidates the associated \`payer\_token\`, preventing new charges from their wallet. To cancel an agreement, send a \*\*DELETE\*\* to the endpoint :TagComponent{tag="API" text="/v2/wallet\_connect/agreements/{agreement\_id}" href="/developers/en/reference/online-payments/wallet-connect/orders/cancel-agreement/delete" color="accent"} \*\*without sending the body\*\* in the request. Make sure to include your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."} and the \`agreement\_id\` of the agreement you want to cancel. \`\`\`curl curl -X DELETE \\ 'https://api.mercadopago.com/v2/wallet\_connect/agreements/{{AGREEMENT\_ID}}' \\ -H 'Content-Type: application/json' \\ -H 'Authorization: Bearer {{YOUR\_ACCESS\_TOKEN}}' \`\`\` | Parameter | Type | Description | Requirement | |---|---|---|---| | \`Authorization\` | \_Header\_ | Refers to your :toolTipComponent\[test Access Token\]{content="Private key used in the backend to authenticate the requests. In Wallet Connect, the Access Token and the Public Key are provided by the team responsible for creating your application, both test and production. You can also view them in \*Your integrations > Integration data > Tests > Test credentials\*. The test Access Token starts with the prefix \`APP\_USR\`."}. | Required | | \`agreement\_id\` | \_Path. String\_ | Unique identifier of the agreement you want to cancel. | Required | If the request is successful, the response will return status 200 \*\*with no response body\*\*, indicating that the agreement was cancelled and that the associated \`payer\_token\` is no longer valid. > NOTE > > An agreement can also be cancelled by the buyer through the Mercado Pago app, or automatically when a new agreement is created and confirmed for the same buyer. To be notified about these cancellations and avoid charge attempts with an invalid token, configure the \[notifications\](https://www.mercadopago.com.br/developers/en/docs/wallet-connect/notifications). ::: > SUCCESS\_MESSAGE > > To learn in detail about all the parameters sent and returned in these requests, please refer to our :TagComponent{tag="API" text="API Reference" href="/developers/en/reference/online-payments/wallet-connect/overview" color="accent"}. Additionally, if you receive an error when configuring the agreement, consult the \[Possible errors\](https://www.mercadopago.com.br/developers/en/docs/wallet-connect/integration-errors) section for more information.