Inicio
Documentação
Recursos
Parcerias
Comunidade

Recursos

Confira as atualizações das nossas soluções e do funcionamento do sistema ou peça suporte técnico.

Parcerias

Conheça nosso programa para agências ou desenvolvedores que oferecem serviços de integração e vendedores que desejam contratá-los.

Comunidade

Fique por dentro das últimas novidades, peça ajuda a outros integradores e compartilhe seu conhecimento.

Configurar notificações de pagamento - Etapas de integração - Mercado Pago Developers

Configurar notificações de pagamento

As notificações Webhooks, também conhecidas como retornos de chamada web, são um método eficaz que permite aos servidores do Mercado Pago enviar informações em tempo real quando ocorre um evento específico relacionado à sua integração.

Com os Webhooks, o seu sistema não precisa realizar consultas contínuas para buscar atualizações. Esse mecanismo transmite dados de maneira passiva e automática, utilizando solicitações HTTP POST. Assim, otimiza a comunicação e reduz a carga nos servidores.

Consulte o fluxo geral de uma notificação no diagrama abaixo.

Diagram

A seguir, apresentamos um passo a passo para configurar as notificações de criação e atualização de pagamentos. Depois de configuradas, as notificações Webhook serão enviadas sempre que um pagamento for criado ou seu estado for modificado (Pendente, Rejeitado ou Aprovado). No processo de integração com o Mercado Pago, as notificações podem ser configuradas de duas maneiras:

Tipo de ConfiguraçãoDescriçãoVantagensQuando Usar
Configuração através de Suas integraçõesEste método permite configurar notificações diretamente do seu Painel de Desenvolvedor. Você pode configurar notificações para cada uma de suas aplicações, identificar contas distintas, se necessário, e validar a origem da notificação através de uma assinatura secreta.- Identificação simples de contas distintas, garantindo uma gestão adequada em ambientes diversos.
- Alta segurança ao validar a origem das notificações através de uma assinatura secreta, que garante a integridade da informação recebida.
- Mais versátil e eficaz para manter um controle centralizado e gerenciar a comunicação com as aplicações de maneira eficiente.
Recomendado para a maioria das integrações.
Configuração durante a criação de pagamentos ou preferênciasAs notificações são configuradas para cada transação individualmente durante a criação do pagamento ou preferência.- Ajustes específicos para cada transação.
- Flexibilidade em casos de necessidade de parâmetros dinâmicos obrigatórios.
- Ideal para integrações como plataformas de pagamento para múltiplos vendedores.
Conveniente em casos em que seja necessário enviar um query parameter dinâmico de forma obrigatória, além de ser adequado para integrações que funcionam como uma plataforma de pagamento para múltiplos vendedores.
Importante
As URLs configuradas durante a criação de um pagamento terão prioridade sobre aquelas configuradas através de Suas integrações.

Configuração através de Suas integrações

Você pode configurar notificações para cada uma de suas aplicações diretamente em Suas integrações de maneira eficiente e segura. Nesta seção, explicaremos como:

  1. Indicar as URLs de notificação e configurar eventos
  2. Validar a origem de uma notificação
  3. Simular o recebimento de uma notificação

1. Indicar URLs de notificação e configurar o evento

Para configurar notificações Webhooks, é necessário indicar as URLs para as quais as notificações serão enviadas. Para fazer isso, siga o passo a passo abaixo:

  1. Acesse Suas integrações e selecione a aplicação integrada com o Checkout Pro para a qual você deseja ativar as notificações.

Application

  1. No menu à esquerda, selecione Webhooks > Configurar notificações e configure a URL que será utilizada para recebê-las.

Webhooks

  1. Selecione a aba Modo produtivo e forneça uma URL HTTPS para receber notificações com sua integração produtiva.

URL

  1. Selecione o evento Pagamentos para receber notificações, que serão enviadas no formato JSON através de um HTTPS POST para a URL especificada anteriormente.

Payment

5.Por fim, clique em Salvar configuração. Isso gerará uma chave secreta exclusiva para a aplicação, utilizada para validar a autenticidade das notificações recebidas, assegurando que elas sejam provenientes do Mercado Pago. Vale ressaltar que essa chave não possui prazo de validade, mas recomenda-se sua renovação periódica como medida de segurança. Para renovar a chave, basta clicar no botão Restabelecer.

2. Simular o recebimento da notificação

Para garantir que as notificações sejam configuradas corretamente, é necessário simular o recebimento delas. Para isso, siga o passo a passo abaixo:

  1. Após configurar as URLs e os eventos, clique em Salvar configuração.
  2. Em seguida, clique em Simular para testar se a URL indicada está recebendo as notificações corretamente.
  3. Na tela de simulação, selecione a URL que será testada, que pode ser a URL de teste ou a de produção.
  4. Depois, escolha o tipo de evento e insira a identificação que será enviada no corpo da notificação (Data ID).
  5. Por fim, clique em Enviar teste para verificar a solicitação, a resposta fornecida pelo servidor e a descrição do evento. Você receberá uma resposta semelhante ao exemplo abaixo, que representa o body da notificação recebida em seu servidor.

plain

{
  "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 a origem da notificação

A validação da origem de uma notificação é fundamental para assegurar a segurança e a autenticidade das informações recebidas. Este processo ajuda a prevenir fraudes e garante que apenas notificações legítimas sejam processadas.

O Mercado Pago enviará ao seu servidor uma notificação semelhante ao exemplo abaixo para um alerta do tópico payment. Neste exemplo, está incluída a notificação completa, que contém os query params, o body e o header da notificação.

  • Query params: São parâmetros de consulta que acompanham a URL. No exemplo, temos data.id=123456 e type=payment.
  • Body: O corpo da notificação contém informações detalhadas sobre o evento, como action, api_version, data, date_created, id, live_mode, type e user_id.
  • Header: O cabeçalho contém metadados importantes, incluindo a assinatura secreta da notificação x-signature.

plain

POST /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 da notificação Webhook recebida, você poderá validar a autenticidade de sua origem. O Mercado Pago sempre incluirá a chave secreta nas notificações Webhooks que serão recebidas, o que permitirá validar sua autenticidade. Essa chave será enviada no header x-signature, que será semelhante ao exemplo abaixo.

plain

`ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b`

Para confirmar a validação, é necessário extrair a chave contida no header e compará-la com a chave fornecida para sua aplicação em Suas integrações. Para isso, siga o passo a passo abaixo. Ao final, disponibilizamos nossos SDKs com exemplos de códigos completos para facilitar o processo.

  1. Para extrair o timestamp (ts) e a chave (v1) do header x-signature, divida o conteúdo do header pelo caractere “,", o que resultará em uma lista de elementos. O valor para o prefixo ts é o timestamp (em milissegundos) da notificação e v1 é a chave encriptada. Seguindo o exemplo apresentado anteriormente, ts=1742505638683 e v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b.
  2. Utilizando o template abaixo, substitua os parâmetros com os dados recebidos na sua notificação.

plain

id:[data.id_url];request-id:[x-request-id_header];ts:[ts_header];
  • Os parâmetros com o sufixo _url vêm de query params. Exemplo: [data.id_url] será substituído pelo valor correspondente ao ID do evento (data.id). Este query param pode ser encontrado na notificação recebida. No exemplo de notificação mencionado anteriormente, o data.id_url é 123456.
  • [x-request-id_header] deverá ser substituído pelo valor recebido no header x-request-id. No exemplo de notificação mencionado anteriormente, o x-request-id é bb56a2f1-6aae-46ac-982e-9dcd3581d08e.
  • [ts_header] será o valor ts extraído do header x-signature. No exemplo de notificação mencionado anteriormente, o ts é 1742505638683.
  • Após aplicar os dados ao template, o resultado seria o seguinte id:123456;request-id:bb56a2f1-6aae-46ac-982e-9dcd3581d08e;ts:1742505638683;
Importante
Se algum dos valores apresentados no modelo anterior não estiver presente na notificação recebida, você deve removê-lo.
  1. Em Suas integrações, selecione a aplicação integrada, clique em Webhooks > Configurar notificação e revele a chave secreta gerada.

Signature

  1. Gere a contrachave para a validação. Para fazer isso, calcule um HMAC com a função de hash SHA256 em base hexadecimal, utilizando a chave secreta como chave e o template com os valores como mensagem.
          
$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()))

        
  1. Finalmente, compare a chave gerada com a chave extraída do header, certificando-se de que correspondam exatamente. Além disso, você pode usar o timestamp extraído do header para compará-lo com um timestamp gerado no momento da recepção da notificação, a fim de estabelecer uma tolerância de atraso na recepção da mensagem.

A seguir, você pode ver exemplos 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")
}

	})
}

        

Após configurar as notificações, acesse a seção Ações necessárias após receber uma notificação para confirmar que elas foram devidamente recebidas.

Ações necessárias após receber a notificação

Quando você recebe uma notificação na sua plataforma, o Mercado Pago espera uma resposta para validar que essa recepção foi correta. Para isso, você deve devolver um HTTP STATUS 200 (OK) ou 201 (CREATED).

O tempo de espera para essa confirmação será de 22 segundos. Se não for enviada essa resposta, o sistema entenderá que a notificação não foi recebida e realizará uma nova tentativa de envio a cada 15 minutos, até que receba a resposta. Após a terceira tentativa, o prazo será prorrogado, mas os envios continuarão acontecendo.

Após responder a notificação, confirmando seu recebimento, você pode obter todas as informações sobre o evento do tópico payments notificado fazendo um GET ao endpoint v1/payments/{id}.

Com essas informações, você poderá realizar as atualizações necessárias na sua plataforma, como por exemplo, atualizar um pagamento aprovado.

Além disso, para consultar o status do evento após a notificação, você pode utilizar os diferentes métodos dos nossos SDKs para realizar a consulta com o ID que foi enviado na notificação.

          
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;
}

        
          
MercadoPago::SDK.configure(access_token: 'ENV_ACCESS_TOKEN')
case payload['type']
when 'payment'
  payment = MercadoPago::Payment.search(id: payload['data']['id'])
when 'plan'
  plan = MercadoPago::Plan.search(id: payload['data']['id'])
when 'subscription'
  subscription = MercadoPago::Subscription.search(id: payload['data']['id'])
when 'invoice'
  invoice = MercadoPago::Invoice.search(id: payload['data']['id'])
when 'point_integration_wh'
  # Contiene la informaciòn relacionada a la notificaciòn.
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

        
          
accessToken := "{{ACCESS_TOKEN}}"
cfg, err := config.New(accessToken)
if err != nil {
	fmt.Println(err)
	return
}
client := customer.NewClient(cfg)
switch req.Type {
case "payment":
	client := payment.NewClient(cfg)
	resource, err = client.Get(context.Background(), resource.ID)
	if err != nil {
		fmt.Println(err)
		return
	}
case "plan":
    client := preapprovalplan.NewClient(cfg)
    resource, err := client.Get(context.Background(), preApprovalPlanID)
	if err != nil {
		fmt.Println(err)
		return
	}
case "invoice":
	client := invoice.NewClient(cfg)
	resource, err := client.Get(context.Background(), req.Data.ID)
	if err != nil {
		fmt.Println(err)
		return
	}
case "point_integration_wh":
	// Contiene la informaciòn relacionada a la notificaciòn.
}