# MD for: https://www.mercadopago.com.ar/developers/en/docs/wallet-connect/notifications.md \# Configure notifications \*\*Webhooks\*\* notifications, also known as \*\*web callbacks\*\*, are an effective method that allows Mercado Pago servers to send information in \*\*real time\*\* when a specific event related to your integration occurs. Instead of your system making constant queries to check for updates, Webhooks allow data transmission in a \*\*passive and automatic\*\* manner between Mercado Pago and your integration through an \*\*HTTPS POST\*\* request, optimizing communication and reducing server load. :::AccordionComponent{title="Configure Webhooks"} Below is a step-by-step guide to receive notifications in Wallet Connect integrations. Once configured, Webhook notifications will be sent whenever any update occurs on the reported topics, including creation and update of orders, transaction processing, and linking events. 1\. Access \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app) and select the application created by the team responsible for your Wallet Connect integration, for which you want to activate notifications. 2\. In the left menu, select \*\*Webhooks > Configure notifications\*\*. 3\. Select the \*\*Production mode\*\* tab and provide an \`HTTPS URL\` to receive notifications with your productive integration. > NOTE > > If it is necessary to identify multiple accounts, add the parameter \`?client=(sellername)\` at the end of the indicated URL to identify sellers. 4\. Select the events to receive notifications: - \*\*Order (Mercado Pago)\*\*: to receive payment notifications made with the Orders API. - \*\*Wallet Connect\*\*: to receive notifications for linking events (confirmation and cancellation). 5\. Finally, click \*\*Save configuration\*\*. This will generate an exclusive secret key for the application, which will allow validating the authenticity of received notifications, ensuring they were sent by Mercado Pago. Keep in mind that this generated key has no expiration date and periodic renewal is not mandatory, although it is recommended. To do so, just click the \*\*Reset\*\* button. ::: :::AccordionComponent{title="Simulate notification reception"} To ensure that notifications are configured correctly, it is necessary to simulate their reception. To do this, follow the step-by-step below. 1\. After configuring the URL and events, click \*\*Save configuration\*\*. 2\. Then, click \*\*Simulate\*\* to test whether the indicated URL is receiving notifications correctly. 3\. In the simulation screen, select the URL to be tested. 4\. Next, select the \*\*event type\*\* and enter the \*\*identification\*\* that will be sent in the notification body (Data ID). 5\. Finally, click \*\*Send test\*\* to verify the request, the response provided by the server, and the event description. > WARNING > > If for any reason you are not receiving notifications from Mercado Pago, you can alternatively obtain information about the resource that was not notified by sending a request to the endpoint :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/wallet-connect/orders/get-order/get" color="accent"}. The use of this method is not recommended, so we also suggest contacting \[Support\](https://www.mercadopago.com.ar/developers/en/support). ::: :::AccordionComponent{title="Validate the origin of the notification"} Validating the origin of a notification is essential to ensure the security and authenticity of the information received. This process helps prevent fraud and ensures that only legitimate notifications are processed. Mercado Pago will send your server a notification similar to the example below for an \`order\` topic alert. This example includes the complete notification, containing the query params, the \`body\`, and the \`header\` of the notification. - \*\*Query params\*\*: Query parameters that accompany the URL. In the example, these are \`data.id=ORD01JQ4S4KY8HWQ6NA5PXB65B3D3\` and \`type=order\`. - \*\*Body\*\*: The notification body contains detailed information about the event, such as \`action\`, \`api\_version\`, \`application\_id\`, \`date\_created\`, \`id\`, \`live\_mode\`, \`type\`, \`user\_id\`, and \`data\`. - \*\*Header\*\*: The header contains important metadata, including the notification's secret signature \`x-signature\`. \`\`\` POST /test?data.id=ORD01JQ4S4KY8HWQ6NA5PXB65B3D3&type=order HTTP/1.1 Host: prueba.requestcatcher.com Accept: \*/\* Content-Type: application/json X-Request-Id: 2066ca19-c6f1-498a-be75-1923005edd06 X-Signature: ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b {"action":"order.action\_required","api\_version":"v1","application\_id":"76506430185983","date\_created":"2021-11-01T02:02:02Z","id":"123456","live\_mode":false,"type":"order","user\_id":2025701502,"data":{"id":"ORD01JQ4S4KY8HWQ6NA5PXB65B3D3"}} \`\`\` > RED\_MESSAGE > > Although the \`data.id\` parameter is returned in the notification with alphanumeric characters in uppercase, to use it in the notification validation process it will be necessary to send it in lowercase. That is, considering the previous example, the value \`ORD01JQ4S4KY8HWQ6NA5PXB65B3D3\` should be used as \`ord01jq4s4ky8hwq6na5pxb65b3d3\`. From the received Webhook notification, you can validate the authenticity of its origin. Mercado Pago will always include the secret key in the Webhook notifications received, which will allow validating their authenticity. This key will be sent in the \`x-signature\` header. To confirm the validation, it is necessary to extract the key contained in the header and compare it with the key provided for your application in \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app). To do this, follow the step-by-step below. 1\. To extract the timestamp (\`ts\`) and key (\`v1\`) from the \`x-signature\` header, split the header content by the "," character. The value for the \`ts\` prefix is the notification timestamp (in milliseconds) and \`v1\` is the encrypted key. 2\. Using the template below, replace the parameters with the data received in your notification. \`\`\` id:\[data.id\_url\];request-id:\[x-request-id\_header\];ts:\[ts\_header\]; \`\`\` 3\. In \[Your integrations\](https://www.mercadopago.com.ar/developers/panel/app), select the integrated application, click \*\*Webhooks > Configure notification\*\* and reveal the generated secret key. 4\. Generate the counter-key for validation. To do this, calculate an \[HMAC\](https://en.wikipedia.org/wiki/HMAC) with the \`SHA256 hash\` function in hexadecimal base, using the secret signature as the key and the template with the values as the message. php phpnodejavapython ``` $cyphedSignature = hash_hmac('sha256', $data, $key); ``` ``` const crypto = require('crypto'); const cyphedSignature = crypto .createHmac('sha256', secret) .update(signatureTemplateParsed) .digest('hex'); ``` ``` String cyphedSignature = new HmacUtils("HmacSHA256", secret).hmacHex(signedTemplate); ``` ``` import hashlib, hmac, binascii cyphedSignature = binascii.hexlify(hmac_sha256(secret.encode(), signedTemplate.encode())) ``` 5\. Finally, compare the generated key with the key extracted from the header, making sure they match exactly. See complete code examples below: php phpjavascriptpython ``` ``` ``` const xSignature = headers['x-signature']; const xRequestId = headers['x-request-id']; const urlParams = new URLSearchParams(window.location.search); const dataID = urlParams.get('data.id'); const parts = xSignature.split(','); let ts; let hash; parts.forEach(part => { const [key, value] = part.split('='); if (key && value) { const trimmedKey = key.trim(); const trimmedValue = value.trim(); if (trimmedKey === 'ts') { ts = trimmedValue; } else if (trimmedKey === 'v1') { hash = trimmedValue; } } }); const secret = 'your_secret_key_here'; const manifest = `id:${dataID};request-id:${xRequestId};ts:${ts};`; const hmac = crypto.createHmac('sha256', secret); hmac.update(manifest); const sha = hmac.digest('hex'); if (sha === hash) { console.log("HMAC verification passed"); } else { console.log("HMAC verification failed"); } ``` ``` import hashlib import hmac import urllib.parse xSignature = request.headers.get("x-signature") xRequestId = request.headers.get("x-request-id") queryParams = urllib.parse.parse_qs(request.url.query) dataID = queryParams.get("data.id", [""])[0] parts = xSignature.split(",") ts = None hash = None for part in parts: keyValue = part.split("=", 1) if len(keyValue) == 2: key = keyValue[0].strip() value = keyValue[1].strip() if key == "ts": ts = value elif key == "v1": hash = value secret = "your_secret_key_here" manifest = f"id:{dataID};request-id:{xRequestId};ts:{ts};" hmac_obj = hmac.new(secret.encode(), msg=manifest.encode(), digestmod=hashlib.sha256) sha = hmac_obj.hexdigest() if sha == hash: print("HMAC verification passed") else: print("HMAC verification failed") ``` ::: :::AccordionComponent{title="Actions required after receiving the notification"} When you receive a notification on your platform, Mercado Pago expects a response to validate that the reception was correct. To do this, you must return an \`HTTP STATUS 200 (OK)\` or \`201 (CREATED)\`. The \*\*waiting time\*\* for this confirmation will be \*\*22 seconds\*\*. If this confirmation is not sent, the system will understand that the notification was not received and will make a new send attempt \*\*every 15 minutes\*\*, until it receives the response. After responding to the notification and confirming its receipt, you can obtain all the information about the notified resource by sending a request to the endpoint :TagComponent{tag="GET" text="/v1/orders/{id}" href="/developers/en/reference/online-payments/wallet-connect/orders/get-order/get" color="accent"}. ::: :::::AccordionComponent{title="Event types"} Learn about the linking and payment events that trigger Webhook notifications and see examples of the data sent in each case. ::::TabsComponent :::TabComponent{title="Linking"} There are two types of events related to linking, notified by the \`wallet\_connect\` topic: - \*\*Linking confirmation by the user\*\*: This event notifies the integrator when a user confirms the agreement. \`\`\`json { "id": "22abcd1235ed497f945f755fcaba3c6c", "type": "wallet\_connect", "entity": "agreement", "action": "status.updated", "date": "2021-09-30T23:24:44Z", "model\_version": 1, "version": 0, "data": { "id": "22abcd1235ed497f945f755fcaba3c6c", "status": "confirmed\_by\_user" } } \`\`\` > NOTE > > To obtain the \`agreement\_code\`, send a request to the endpoint :TagComponent{tag="GET" text="/v2/wallet\_connect/agreements/{agreement\_id}" href="/developers/en/reference/online-payments/wallet-connect/orders/get-agreement/get" color="accent"}. This code allows you to proceed with generating the payment token and subsequently creating payments. - \*\*Linking cancellation\*\*: The user can cancel an active agreement. When this happens, the existing agreement is cancelled and the associated \`payer\_token\` is invalidated, so it can no longer be used to process payments. > WARNING > > New charge attempts made with the invalidated \`payer\_token\` will be rejected. \`\`\`json { "id": "22abcd1235ed497f945f755fcaba3c6c", "type": "wallet\_connect", "entity": "agreement", "action": "status.updated", "date": "2021-09-30T23:24:44Z", "model\_version": 1, "version": 0, "data": { "id": "22abcd1235ed497f945f755fcaba3c6c", "status": "canceled" } } \`\`\` | Notification type | Action | Description | |---|---|---| | Linking confirmation | \`status.updated\` | The user confirmed a linking. | | Linking cancellation | \`status.updated\` | The linking was cancelled by the user. | ::: :::TabComponent{title="Payments"} Payment webhook notifications are sent for the \`order\` topic. The possible types are \`order\_processed\`, \`order\_failed\`, and \`order\_refunded\`. - \*\*Processed order\*\*: \`\`\`json { "action": "order\_processed", "api\_version": "v1", "application\_id": "76506430185983", "date\_created": "2021-11-01T02:02:02Z", "id": "123456", "live\_mode": true, "type": "order", "user\_id": 2025701502, "data": { "id": "ORDBTA01KJZ06DEJX3DMY26FAB44BXNN" } } \`\`\` - \*\*Failed order\*\*: \`\`\`json { "action": "order\_failed", "api\_version": "v1", "application\_id": "76506430185983", "date\_created": "2021-11-01T02:02:02Z", "id": "123457", "live\_mode": true, "type": "order", "user\_id": 2025701502, "data": { "id": "ORDBTA01KJZ0DM49EFP6Q2TXXXXXXXXX" } } \`\`\` - \*\*Refunded order\*\*: \`\`\`json { "action": "order\_refunded", "api\_version": "v1", "application\_id": "76506430185983", "date\_created": "2021-11-01T02:02:02Z", "id": "123458", "live\_mode": true, "type": "order", "user\_id": 2025701502, "data": { "id": "ORDBTA01KJZ0AYZPD3SXDYCQ109Q69EA" } } \`\`\` ::: :::: :::::