Configurar notificaciones
Las notificaciones Webhooks, tambiĂ©n conocidas como devoluciones de llamada web, son un mĂ©todo efectivo que permiten a los servidores de Mercado Pago enviar informaciĂłn en tiempo real cuando ocurre un evento especĂfico relacionado con tu integraciĂłn. En lugar de que tu sistema realice consultas constantes para verificar actualizaciones, los Webhooks permiten la transmisiĂłn de datos de manera pasiva y automĂĄtica entre Mercado Pago y tu integraciĂłn a travĂ©s de una solicitud HTTP POST, optimizando la comunicaciĂłn y reduciendo la carga en los servidores.
Configurar notificaciones
A continuaciĂłn, presentaremos un paso a paso para poder recibir notificaciones de pago en integraciones con Checkout Transparente. Una vez configuradas, las notificaciones Webhook se enviarĂĄn siempre que ocurra cualquier actualizaciĂłn sobre el tĂłpico reportado, incluyendo creaciĂłn y actualizaciĂłn de orders y procesamiento de transacciones.
- Ingresa a Tus integraciones y selecciona la aplicaciĂłn integrada con Checkout Transparente para la que deseas activar las notificaciones.
- En el menĂș de la izquierda, selecciona Webhooks > Configurar notificaciones.
- Selecciona la pestaña Modo productivo y proporciona una
URL HTTPS
para recibir notificaciones con tu integraciĂłn productiva.
- Selecciona el evento Order (Mercado Pago) para recibir notificaciones, que serĂĄn enviadas en formato
JSON
a través de unHTTP POST
a la URL especificada anteriormente.
- Por Ășltimo, haz clic en Guardar configuraciĂłn. Esto generarĂĄ una clave secreta exclusiva para la aplicaciĂłn, que permitirĂĄ validar la autenticidad de las notificaciones recibidas, garantizando que hayan sido enviadas por Mercado Pago. Ten en cuenta que esta clave generada no tiene plazo de caducidad y su renovaciĂłn periĂłdica no es obligatoria, aunque sĂ recomendada. Para hacerlo, basta con cliquear en el botĂłn Restablecer.
Simular la recepciĂłn de la notificaciĂłn
Para garantizar que las notificaciones sean configuradas correctamente, es necesario simular su recepciĂłn. Para hacerlo, sigue el paso a paso a continuaciĂłn.
- Después de configurar la URL y lo evento, haz clic en Guardar configuración.
- Luego, haz clic en Simular para probar si la URL indicada estĂĄ recibiendo las notificaciones correctamente.
- En la pantalla de simulaciĂłn, selecciona la URL que se va a probar.
- A continuaciĂłn, elige el tipo de evento e ingresa la identificaciĂłn que se enviarĂĄ en el cuerpo de la notificaciĂłn (Data ID).
- Por Ășltimo, haz clic en Enviar prueba para verificar la solicitud, la respuesta proporcionada por el servidor y la descripciĂłn del evento. RecibirĂĄs una respuesta segĂșn el ejemplo a continuaciĂłn, que representa el body de la notificaciĂłn recibida en tu servidor.
json
{ "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" } }
Validar origen de la notificaciĂłn
La validaciĂłn del origen de una notificaciĂłn es fundamental para asegurar la seguridad y la autenticidad de la informaciĂłn recibida. Este proceso ayuda a prevenir fraudes y garantiza que solo las notificaciones legĂtimas sean procesadas.
Mercado Pago enviarĂĄ a tu servidor una notificaciĂłn similar al ejemplo a continuaciĂłn para una alerta del tĂłpico order
. En este ejemplo, se incluye la notificaciĂłn completa, que contiene los query params, el body
y el header
de la notificaciĂłn.
- Query params: Son paråmetros de consulta que acompañan la URL. En el ejemplo, tenemos
data.id=ORD01JQ4S4KY8HWQ6NA5PXB65B3D3
ytype=order
. - Body: El cuerpo de la notificaciĂłn contiene informaciĂłn detallada sobre el evento, como
action
,api_version
,application_id
,date_created
,id
,live_mode
,type
,user_id
ydata
. - Header: El encabezado contiene metadatos importantes, incluyendo la firma secreta de la notificaciĂłn
x-signature
.
plain
POST /test?data.id=ORD01JQ4S4KY8HWQ6NA5PXB65B3D3&type=order HTTP/1.1 Host: prueba.requestcatcher.com Accept: */* Accept-Encoding: * Connection: keep-alive Content-Length: 177 Content-Type: application/json Newrelic: eyJ2IjpbMCwxXSwiZCI6eyJ0eSI6IkFwcCIsImFjIjoiOTg5NTg2IiwiYXAiOiI5NjA2MzYwOTQiLCJ0eCI6ImY4MzljZjg4ODg2MGRmZTIiLCJ0ciI6ImMwOGMwZGMyMjNjZDY2YjJkZWQwMjUxZmYxNWNiNGQ1IiwicHIiOjEuMjUwMzIsInNhIjp0cnVlLCJ0aSI6MTc0Mjg0MjU4MDE2NCwiaWQiOiIxOGI2NDcxNjNkNzI3NjU4IiwidGsiOiIxNzA5NzA3In19= Traceparent: 00-c08c0dc223cd66b2ded0251ff15cb4d5-18b647163d727658-01 Tracestate: 1709707@nr=0-0-989586-960636094-18b647163d727658-f839cf888860dfe2-1-1.250320-1742842580164 User-Agent: restclient-node/4.15.3 X-Request-Id: 2066ca19-c6f1-498a-be75-1923005edd06 X-Rest-Pool-Name: /services/webhooks.js X-Retry: 0 X-Signature: ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b X-Socket-Timeout: 22000 {"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"}}
A partir de la notificación Webhook recibida, podrås validar la autenticidad de su origen a través la clave secreta en las notificaciones Webhooks que serån recibidas. Esta clave serå enviada en el header x-signature
, que serĂĄ similar al ejemplo debajo.
plain
ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b
Para confirmar la validaciĂłn, es necesario extraer la clave contenida en el header y compararla con la clave otorgada para tu aplicaciĂłn en Tus integraciones. Para eso, sigue el paso a paso a continuaciĂłn. Al final, disponibilizamos nuestros SDKs con ejemplos de cĂłdigos completos para facilitar el proceso.
- Para extraer el timestamp (
ts
) y la clave (v1
) del headerx-signature
, divide el contenido del header por el carĂĄcter â,", lo que resultarĂĄ en una lista de elementos. El valor para el prefijots
es el timestamp (en milisegundos) de la notificaciĂłn yv1
es la clave encriptada. Siguiendo el ejemplo presentado anteriormente,ts=1742505638683
yv1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b
. - Utilizando el template a continuaciĂłn, sustituye los parĂĄmetros con los datos recibidos en tu notificaciĂłn.
plain
id:[data.id_url];request-id:[x-request-id_header];ts:[ts_header];
- Los parĂĄmetros con el sufijo
_url
provienen de query params. Ejemplo: [data.id_url
] se sustituirĂĄ por el valor correspondiente al ID del evento (data.id
). Este query param puede ser hallado en la notificaciĂłn recibida. En el ejemplo de notificaciĂłn mencionado anteriormente, eldata.id_url
esORD01JQ4S4KY8HWQ6NA5PXB65B3D3
. - [x-request-id_header] deberĂĄ ser sustituido por el valor recibido en el header
x-request-id
. En el ejemplo de notificaciĂłn mencionado anteriormente, elx-request-id
es2066ca19-c6f1-498a-be75-1923005edd06
. - [
ts_header
] serĂĄ el valorts
extraĂdo del headerx-signature
. En el ejemplo de notificaciĂłn mencionado anteriormente, elts
es1742505638683
. - Al aplicar los datos al template, quedarĂa de la siguiente manera:
id:ORD01JQ4S4KY8HWQ6NA5PXB65B3D3;request-id:2066ca19-c6f1-498a-be75-1923005edd06;ts:1742505638683;
- En Tus integraciones, selecciona la aplicaciĂłn integrada, haz clic en Webhooks > Configurar notificaciĂłn y revela la clave secreta generada.
- Genera la contraclave para la validaciĂłn. Para hacer esto, calcula un HMAC con la funciĂłn de
hash SHA256
en base hexadecimal, utilizando la clave secreta como clave y el template con los valores como mensaje.
$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()))
- Finalmente, compara la clave generada con la clave extraĂda del header, asegurĂĄndote de que tengan una correspondencia exacta. AdemĂĄs, puedes usar el timestamp extraĂdo del header para compararlo con un timestamp generado en el momento de la recepciĂłn de la notificaciĂłn, con el fin de establecer una tolerancia de demora en la recepciĂłn del mensaje.
A continuaciĂłn, puedes ver ejemplos de cĂłdigo completo:
<?php
// Obtain the x-signature value from the header
$xSignature = $_SERVER['HTTP_X_SIGNATURE'];
$xRequestId = $_SERVER['HTTP_X_REQUEST_ID'];
// Obtain Query params related to the request URL
$queryParams = $_GET;
// Extract the "data.id" from the query params
$dataID = isset($queryParams['data.id']) ? $queryParams['data.id'] : '';
// Separating the x-signature into parts
$parts = explode(',', $xSignature);
// Initializing variables to store ts and hash
$ts = null;
$hash = null;
// Iterate over the values to obtain ts and v1
foreach ($parts as $part) {
// Split each part into key and value
$keyValue = explode('=', $part, 2);
if (count($keyValue) == 2) {
$key = trim($keyValue[0]);
$value = trim($keyValue[1]);
if ($key === "ts") {
$ts = $value;
} elseif ($key === "v1") {
$hash = $value;
}
}
}
// Obtain the secret key for the user/application from Mercadopago developers site
$secret = "your_secret_key_here";
// Generate the manifest string
$manifest = "id:$dataID;request-id:$xRequestId;ts:$ts;";
// Create an HMAC signature defining the hash type and the key as a byte array
$sha = hash_hmac('sha256', $manifest, $secret);
if ($sha === $hash) {
// HMAC verification passed
echo "HMAC verification passed";
} else {
// HMAC verification failed
echo "HMAC verification failed";
}
?>
// Obtain the x-signature value from the header
const xSignature = headers['x-signature']; // Assuming headers is an object containing request headers
const xRequestId = headers['x-request-id']; // Assuming headers is an object containing request headers
// Obtain Query params related to the request URL
const urlParams = new URLSearchParams(window.location.search);
const dataID = urlParams.get('data.id');
// Separating the x-signature into parts
const parts = xSignature.split(',');
// Initializing variables to store ts and hash
let ts;
let hash;
// Iterate over the values to obtain ts and v1
parts.forEach(part => {
// Split each part into key and value
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;
}
}
});
// Obtain the secret key for the user/application from Mercadopago developers site
const secret = 'your_secret_key_here';
// Generate the manifest string
const manifest = `id:${dataID};request-id:${xRequestId};ts:${ts};`;
// Create an HMAC signature
const hmac = crypto.createHmac('sha256', secret);
hmac.update(manifest);
// Obtain the hash result as a hexadecimal string
const sha = hmac.digest('hex');
if (sha === hash) {
// HMAC verification passed
console.log("HMAC verification passed");
} else {
// HMAC verification failed
console.log("HMAC verification failed");
}
import hashlib
import hmac
import urllib.parse
# Obtain the x-signature value from the header
xSignature = request.headers.get("x-signature")
xRequestId = request.headers.get("x-request-id")
# Obtain Query params related to the request URL
queryParams = urllib.parse.parse_qs(request.url.query)
# Extract the "data.id" from the query params
dataID = queryParams.get("data.id", [""])[0]
# Separating the x-signature into parts
parts = xSignature.split(",")
# Initializing variables to store ts and hash
ts = None
hash = None
# Iterate over the values to obtain ts and v1
for part in parts:
# Split each part into key and value
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
# Obtain the secret key for the user/application from Mercadopago developers site
secret = "your_secret_key_here"
# Generate the manifest string
manifest = f"id:{dataID};request-id:{xRequestId};ts:{ts};"
# Create an HMAC signature defining the hash type and the key as a byte array
hmac_obj = hmac.new(secret.encode(), msg=manifest.encode(), digestmod=hashlib.sha256)
# Obtain the hash result as a hexadecimal string
sha = hmac_obj.hexdigest()
if sha == hash:
# HMAC verification passed
print("HMAC verification passed")
else:
# HMAC verification failed
print("HMAC verification failed")
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"fmt"
"net/http"
"strings"
)
func main() {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
// Obtain the x-signature value from the header
xSignature := r.Header.Get("x-signature")
xRequestId := r.Header.Get("x-request-id")
// Obtain Query params related to the request URL
queryParams := r.URL.Query()
// Extract the "data.id" from the query params
dataID := queryParams.Get("data.id")
// Separating the x-signature into parts
parts := strings.Split(xSignature, ",")
// Initializing variables to store ts and hash
var ts, hash string
// Iterate over the values to obtain ts and v1
for _, part := range parts {
// Split each part into key and value
keyValue := strings.SplitN(part, "=", 2)
if len(keyValue) == 2 {
key := strings.TrimSpace(keyValue[0])
value := strings.TrimSpace(keyValue[1])
if key == "ts" {
ts = value
} else if key == "v1" {
hash = value
}
}
}
// Get secret key/token for specific user/application from Mercadopago developers site
secret := "your_secret_key_here"
// Generate the manifest string
manifest := fmt.Sprintf("id:%v;request-id:%v;ts:%v;", dataID, xRequestId, ts)
// Create an HMAC signature defining the hash type and the key as a byte array
hmac := hmac.New(sha256.New, []byte(secret))
hmac.Write([]byte(manifest))
// Obtain the hash result as a hexadecimal string
sha := hex.EncodeToString(hmac.Sum(nil))
if sha == hash {
// HMAC verification passed
fmt.Println("HMAC verification passed")
} else {
// HMAC verification failed
fmt.Println("HMAC verification failed")
}
})
}
Acciones necesarias después de recibir la notificación
Cuando recibes una notificaciĂłn en tu plataforma, Mercado Pago espera una respuesta para validar que esa recepciĂłn fue correcta. Para eso, debes devolver un HTTP STATUS 200 (OK)
o 201 (CREATED)
.
El tiempo de espera para esa confirmaciĂłn serĂĄ de 22 segundos. Si no se envĂa esta respuesta, el sistema entenderĂĄ que la notificaciĂłn no fue recibida y realizarĂĄ un nuevo intento de envĂo cada 15 minutos, hasta que reciba la respuesta. DespuĂ©s del tercer intento, el plazo serĂĄ prorrogado, pero los envĂos continuarĂĄn sucediendo.
Luego de responder la notificaciĂłn, confirmando su recibimiento, puedes obtener toda la informaciĂłn sobre el recurso notificado enviando un GET al endpoint /v1/orders/{id}API.
Con esta informaciĂłn podrĂĄs realizar las actualizaciones necesarias en tu plataforma, como actualizar un pago aprobado.