AI resources

Configure Payment Profile notifications

The Payment Profile Webhooks deliver real-time notifications to your application whenever a profile linked to your integration changes. Instead of polling the API, you receive updates as they happen via HTTP POST.

This way, you can detect when a profile reaches the ready status to enable your recurring charge flow, take the necessary actions when a payment method linked to a profile is deactivated or cancelled, and keep your system always in sync with the actual profile state.

    flowchart TD
        A[Profile change] --> B{Check eligibility}
        B -->|Not eligible| C[Event discarded]
        B -->|Eligible| D["POST {your-url} with JSON payload"]
        D --> E[Your app responds HTTP 200]
        E --> F[Process event asynchronously]
    

Configure Webhooks

Follow the steps below to configure Payment Profile notifications.

  1. Go to Your integrations and select the application for which you want to enable notifications.
The application configured for notifications must match the one responsible for creating the profile.

configure notifications

  1. In the left menu, select Webhooks > Configure notifications.

configure notifications

  1. Set the URLs that will receive notifications. We recommend using separate URLs for test and production environments:
    • Test URL: use during development, exclusively with test credentialsUnique credentials that identify your integration in test environments..
    • Production URL: use with your integration already in production, configured with production credentialsUnique credentials that identify your integration in production environments..
  2. Select the Payment Profile event (payment_profile) to receive notifications for profile changes.
  3. Finally, click Save configuration. This will generate an exclusive secret key for the application, which will be used to validate the authenticity of received notifications, ensuring they were sent by Mercado Pago. Note that this key has no expiration date and periodic renewal is not mandatory, though recommended. To do so, click the Reset button.

Simulate receiving the notification

To ensure notifications are configured correctly, simulate receiving them by following the steps below.

  1. After configuring your Webhooks, click Simulate notification.
  2. On the simulation screen, select the URL to test.
  3. Choose the Payment Profile event type and enter the profile ID to be sent in the notification body (Data ID).
  4. Finally, click Send test to verify the request, the server response, and the event description.

Validate the notification origin

Validating the origin of a notification is essential to ensure the security and authenticity of the received information. 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 a payment_profile topic alert.

json

{
  "id": "abc123def456",
  "type": "payment_profile",
  "action": "payment_profile.updated",
  "version": 3,
  "date_created": "2026-01-10T10:00:00.000+0000",
  "live_mode": true,
  "collector_id": "123456789",
  "application_id": "1234567890",
  "data": {
    "date_last_updated": "2026-03-27T14:30:00.000+0000",
    "status": "ready",
    "payment_methods": [
      {
        "unique_id": "pm_001",
        "type": "credit_card",
        "status": "ready",
        "default_method": true,
        "card_id": 111222333
      }
    ],
    "previous_attributes": {
      "status": "pending",
      "payment_method": {
        "unique_id": "pm_001",
        "type": "credit_card",
        "status": "rejected",
        "default_method": false,
        "card_id": 111222333
      }
    }
  }
}
FieldTypePresenceDescription
idstringAlwaysPayment profile identifier returned by the API at creation time.
typestringAlwaysAlways payment_profile.
actionstringAlwaysAlways payment_profile.updated, indicating that a relevant profile attribute was modified — status, payment method, or both.
versionintegerAlwaysIncremental notification counter for this profile. Use it to order out-of-sequence events.
date_createdstringAlwaysProfile creation date (ISO 8601).
live_modebooleanAlwaystrue in production, false in test mode.
collector_idstringAlwaysID of the merchant associated with the profile.
application_idstringAlwaysID of the integrating application that originated the profile.
dataobjectAlwaysDetails of the change that occurred.
data.date_last_updatedstringAlwaysExact date and time of the profile change, in ISO 8601 format.
data.statusstringPresent only if the status was modifiedNew profile status.
data.payment_methodsarrayPresent only if a payment method changed.Current information about the affected payment methods. Includes the unique identifier (unique_id), payment method type (credit_card, debit_card, prepaid_card, bank_transfer), current status, and whether it is set as the default payment method for charges (default_method). If the payment method is a card, its ID (card_id) will also be present.
data.previous_attributesobjectAbsent in new payment method additions.Previous information about the attributes that changed in the payment profile.
previous_attributes.statusstringConditionalPrevious payment profile status.
previous_attributes.payment_methodobjectConditionalPrevious state of the affected payment method.

For the possible values of data.status and data.payment_methods[*].status and the recommended actions for each, see Profile and payment method statuses.

From the received notification, you can validate the authenticity of its origin through the secret key. This key will be sent in the x-signature header, with the following format:

plain

ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b

To confirm the validation, extract the key from the header and compare it with the key provided for your application in Your integrations. To confirm the validation, it is necessary to extract the key from the header and compare it with the key provided for your application in Your integrations.

Follow one of the approaches below to validate the authenticity of the notification.

The official SDK implements HMAC-based Webhook Signature Verification to authenticate the origin of each received notification.

To get your secret key (secret), select the application in Your integrations, click Webhooks > Configure notification, and reveal the generated key.

<?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

Actions needed after receiving the notification

When you receive a notification on your platform, Mercado Pago expects a response to validate that the receipt was correct. To do so, return an HTTP STATUS 200 or 201 within 22 seconds of receipt.

We recommend that you first respond with a 200 or 201, and then process the notification on the server, to avoid duplicate notifications.

If this response is not sent, the system will make new delivery attempts every 15 minutes. After the first failures, the interval progressively increases, but deliveries continue until the notification is confirmed.

After confirming receipt, process the event asynchronously. If your integration depends on the full profile state, query the API by sending a request to /v1/customers/{customerId}/payment-profiles/{id}GET with the id field received in the notification.

Never infer the complete profile state exclusively from the notification data, as it only delivers the fields that changed.