Configurar notificaciones de pago
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.
Consulta el flujo general de una notificación en el diagrama a continuación.

A continuación, presentamos un paso a paso para configurar las notificaciones de creación y actualización de pagos. Una vez configuradas, las notificaciones Webhook se enviarán cada vez que se cree un pago o se modifique su estado (Pendiente, Rechazado o Aprobado).
En el proceso de integración con Mercado Pago, puedes configurar las notificaciones de dos maneras:
| Tipo de Configuración | Descripción | Ventajas | Cuándo Usar |
| Configuración a través de Tus Integraciones | Este método permite configurar notificaciones directamente en tu Panel de Desarrollador. Puedes configurar notificaciones para cada una de tus aplicaciones, identificar cuentas distintas si es necesario, y validar el origen de la notificación mediante una firma secreta. | - Identificación sencilla de cuentas distintas, asegurando una adecuada gestión en entornos diversos. - Alta seguridad al validar el origen de las notificaciones mediante una firma secreta, que garantiza la integridad de la información recibida. - Más versátil y eficaz para mantener un control centralizado y gestionar la comunicación con las aplicaciones de manera eficiente. | Recomendado para la mayoría de las integraciones. |
| Configuración durante la creación de preferencias | Las notificaciones se configuran para cada transacción individualmente durante la creación de la preferencia. | - Ajustes específicos para cada transacción. - Flexibilidad en casos de necesidad de parámetros dinámicos obligatorios. - Ideal para integraciones como plataformas de pago para múltiples vendedores. | Conveniente en los casos en que sea necesario enviar un query parameter dinámico de forma obligatoria, además de ser adecuado para integraciones que funcionan como una plataforma de pago para múltiples vendedores. |
Configuración a través de Tus integraciones
Puedes configurar notificaciones para cada una de tus aplicaciones directamente desde Tus integraciones de manera eficiente y segura. En este apartado, explicaremos cómo:
- Indicar las URLs de notificación y configurar eventos
- Validar el origen de una notificación
- Simular el recibimiento de una notificación
1. Indicar URLs de notificación y configurar el evento
Para configurar notificaciones Webhooks, es necesario indicar las URLs a las que las mismas serán enviadas. Para hacerlo, sigue el paso a paso a continuación:
- Ingresa a Tus integraciones y selecciona la aplicación integrada con Checkout Pro 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 HTTPSpara recibir notificaciones con tu integración productiva.

- Selecciona el evento Pagos para recibir notificaciones, que serán enviadas en formato
JSONa través de unHTTPS POSTa 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.
2. 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 las URLs y los Eventos, 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, que puede ser la URL de prueba o la de producción.
- 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 similar al ejemplo a continuación, que representa el
bodyde la notificación recibida en tu servidor.
json{ "action": "payment.updated", "api_version": "v1", "data": { "id": "123456" }, "date_created": "2021-11-01T02:02:02Z", "id": "123456", "live_mode": false, "type": "payment", "user_id": 724484980 }
3. 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 su servidor una notificación similar al ejemplo a continuación para una alerta del tópico payment. 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=123456ytype=payment. - Body: El cuerpo de la notificación contiene información detallada sobre el evento, como
action,api_version,data,date_created,id,live_mode,typeyuser_id. - Header: El encabezado contiene metadatos importantes, incluyendo la firma secreta de la notificación
x-signature.
plainPOST /test?data.id=123456&type=payment HTTP/1.1 Host: prueba.requestcatcher.com Accept: */* Accept-Encoding: * Connection: keep-alive Content-Length: 177 Content-Type: application/json Newrelic: eyJ2IjpbMCwxXSwiZCI6eyJ0eSI6IkFwcCIsImFjIjoiOTg5NTg2IiwiYXAiOiI5NjA2MzYwOTQiLCJ0eCI6IjU3ZjI4YzNjOWE2ODNlZDYiLCJ0ciI6IjY0NjA0OTM3OWI1ZjA3MzMyZDdhZmQxMjEyM2I5YWE4IiwicHIiOjAuNzk3ODc0LCJzYSI6ZmFsc2UsInRpIjoxNzQyNTA1NjM4Njg0LCJ0ayI6IjE3MDk3MDcifX0= Traceparent: 00-646049379b5f07332d7afd12123b9aa8-e7f77a41f687aecd-00 Tracestate: 1709707@nr=0-0-989586-960636094-e7f77a41f687aecd-57f28c3c9a683ed6-0-0.797874-1742505638684 User-Agent: restclient-node/4.15.3 X-Request-Id: bb56a2f1-6aae-46ac-982e-9dcd3581d08e X-Rest-Pool-Name: /services/webhooks.js X-Retry: 0 X-Signature: ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b X-Socket-Timeout: 22000 {"action":"payment.updated","api_version":"v1","data":{"id":"123456"},"date_created":"2021-11-01T02:02:02Z","id":"123456","live_mode":false,"type":"payment","user_id":724484980}
A partir de la notificación Webhook recibida, podrás validar la autenticidad de su origen. Mercado Pago siempre incluirá la clave secreta en las notificaciones Webhooks que serán recibidas, lo que permitirá validar su autenticidad. 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.
Sigue uno de los enfoques a continuación para validar la autenticidad de la notificación.
Los SDKs oficiales implementan verificación de firma basada en HMAC (HMAC-based Webhook Signature Verification) para autenticar el origen de cada notificación recibida.
Para obtener tu clave secreta (secret), en Tus integraciones selecciona la aplicación, haz clic en Webhooks > Configurar notificación y revela la clave generada.
<?php
use MercadoPago\Webhook\WebhookSignatureValidator;
use MercadoPago\Exceptions\InvalidWebhookSignatureException;
try {
WebhookSignatureValidator::validate(
$_SERVER['HTTP_X_SIGNATURE'],
$_SERVER['HTTP_X_REQUEST_ID'],
$_GET['data_id'],
$secret
);
http_response_code(200);
} catch (InvalidWebhookSignatureException $e) {
http_response_code(401);
}
import { WebhookSignatureValidator, InvalidWebhookSignatureError } from 'mercadopago';
try {
WebhookSignatureValidator.validate({
xSignature: req.headers['x-signature'],
xRequestId: req.headers['x-request-id'],
dataId: req.query['data.id'],
secret,
});
res.sendStatus(200);
} catch (err) {
if (err instanceof InvalidWebhookSignatureError) res.status(401).end();
else throw err;
}
from mercadopago.webhook import WebhookSignatureValidator, InvalidWebhookSignatureError
try:
WebhookSignatureValidator.validate(
request.headers.get(“x-signature”),
request.headers.get(“x-request-id”),
request.args.get(“data.id”),
secret,
)
return “”, 200
except InvalidWebhookSignatureError:
return “”, 401
import “github.com/mercadopago/sdk-go/pkg/webhook”
err := webhook.ValidateSignature(
r.Header.Get(“x-signature”),
r.Header.Get(“x-request-id”),
r.URL.Query().Get(“data.id”),
secret,
)
if err != nil {
w.WriteHeader(http.StatusUnauthorized)
return
}
w.WriteHeader(http.StatusOK)
using MercadoPago.Error;
using MercadoPago.Webhook;
try {
WebhookSignatureValidator.Validate(
xSignature: Request.Headers[“x-signature”],
xRequestId: Request.Headers[“x-request-id”],
dataId: Request.Query[“data.id”],
secret: secret);
return Ok();
} catch (InvalidWebhookSignatureException) {
return Unauthorized();
}
import com.mercadopago.webhook.WebhookSignatureValidator;
import com.mercadopago.exceptions.MPInvalidWebhookSignatureException;
try {
WebhookSignatureValidator.validate(
request.getHeader(“x-signature”),
request.getHeader(“x-request-id”),
request.getParameter(“data.id”),
secret);
response.setStatus(200);
} catch (MPInvalidWebhookSignatureException e) {
response.setStatus(401);
}
require 'mercadopago/webhook/validator'
begin
Mercadopago::Webhook::Validator.validate(
request.headers['x-signature'],
request.headers['x-request-id'],
request.params['data.id'],
secret
)
head :ok
rescue Mercadopago::Webhook::InvalidWebhookSignatureError
head :unauthorized
end
Una vez que las notificaciones sean configuradas, consulta las acciones necesarias después de recibir una notificación para informar que las mismas fueron debidamente recibidas:
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.
sequenceDiagram
participant MercadoPago as Mercado Pago
participant Integrador as Integrador
MercadoPago->>Integrador: reintento: 1. Demora: 0 minutos
MercadoPago->>Integrador: reintento: 2. Demora: 15 minutos
MercadoPago->>Integrador: reintento: 3. Demora: 30 minutos
MercadoPago->>Integrador: reintento: 4. Demora: 6 horas
MercadoPago->>Integrador: reintento: 5. Demora: 48 horas
MercadoPago->>Integrador: reintento: 6. Demora: 96 horas
MercadoPago->>Integrador: reintento: 7. Demora: 96 horas
MercadoPago->>Integrador: reintento: 8. Demora: 96 horas
Luego de responder la notificación, confirmando su recibimiento, puedes obtener toda la información sobre el evento del tópico payments notificado haciendo un GET al endpoint v1/payments/{id}.
Con esta información podrás realizar las actualizaciones necesarias a tu plataforma, como por ejemplo, actualizar un pago aprobado.
Además, para consultar el estado del evento posterior a la notificación, puedes utilizar los diferentes métodos de nuestros SDKs para realizar la consulta con el ID que fue enviado en la notificación.
MercadoPago.SDK.setAccessToken("ENV_ACCESS_TOKEN");
switch (type) {
case "payment":
Payment payment = Payment.findById(data.id);
break;
case "plan":
Plan plan = Plan.findById(data.id);
break;
case "subscription":
Subscription subscription = Subscription.findById(data.id);
break;
case "invoice":
Invoice invoice = Invoice.findById(data.id);
break;
case "point_integration_wh":
// POST contiene la informaciòn relacionada a la notificaciòn.
break;
}
mercadopago.configurations.setAccessToken('ENV_ACCESS_TOKEN');
switch (type) {
case 'payment':
const payment = await mercadopago.payment.findById(data.id);
break;
case 'plan':
const plan = await mercadopago.plans.get(data.id);
break;
case 'subscription':
const subscription = await mercadopago.subscriptions.get(data.id);
break;
case 'invoice':
const invoice = await mercadopago.invoices.get(data.id);
break;
case 'point_integration_wh':
// Contiene la informaciòn relacionada a la notificaciòn.
break;
}
sdk = Mercadopago::SDK.new('PROD_ACCESS_TOKEN')
case payload['type']
when 'payment'
payment = sdk.payment.search(filters: { id: payload['data']['id'] })
when 'plan'
plan = sdk.preapproval_plan.search(filters: { id: data['data']['id'] })
end
MercadoPagoConfig.AccessToken = "ENV_ACCESS_TOKEN";
switch (type)
{
case "payment":
Payment payment = await Payment.FindByIdAsync(payload["data"]["id"].ToString());
break;
case "plan":
Plan plan = await Plan.FindByIdAsync(payload["data"]["id"].ToString());
break;
case "subscription":
Subscription subscription = await Subscription.FindByIdAsync(payload["data"]["id"].ToString());
break;
case "invoice":
Invoice invoice = await Invoice.FindByIdAsync(payload["data"]["id"].ToString());
break;
case "point_integration_wh":
// Contiene la informaciòn relacionada a la notificaciòn.
break;
}
sdk = mercadopago.SDK("ENV_ACCESS_TOKEN")
notification_type = data["type"]
if notification_type == "payment":
payment = sdk.payment().get(payload["data"]["id"])
elif notification_type == "plan":
plan = sdk.preapproval().get(payload["data"]["id"])
elif notification_type == "subscription":
subscription = sdk.preapproval().get(payload["data"]["id"])
elif notification_type == "invoice":
invoice = sdk.invoice().get(payload["data"]["id"])
elif notification_type == "point_integration_wh":
# Contiene la informaciòn relacionada a la notificaciòn.
else:
return
cfg, err := config.New("ENV_ACCESS_TOKEN")
if err != nil {
fmt.Println(err)
}
switch req.Body.Type {
case "payment":
client := payment.NewClient(cfg)
resource, err = client.Get(context.Background(), req.Body.data.id)
if err != nil {
fmt.Println(err)
return
}
case "plan":
client := preapprovalplan.NewClient(cfg)
resource, err := client.Get(context.Background(), req.Body.data.id)
if err != nil {
fmt.Println(err)
return
}
}