Configurar notificaçÔes
As notificaçÔes Webhooks, tambĂ©m conhecidas como devoluçÔes de chamada web, sĂŁo um mĂ©todo eficaz que permitem aos servidores do Mercado Pago enviar informaçÔes em tempo real quando ocorre um evento especĂfico relacionado Ă sua integração. Em vez de seu sistema realizar consultas constantes para verificar atualizaçÔes, os Webhooks permitem a transmissĂŁo de dados de maneira passiva e automĂĄtica entre Mercado Pago e sua integração atravĂ©s de uma solicitação HTTP POST, otimizando a comunicação e reduzindo a carga nos servidores.
Configurar notificaçÔes
A seguir, apresentaremos um passo a passo para poder receber notificaçÔes de pagamento em integraçÔes com Checkout Transparente. Uma vez configuradas, as notificaçÔes Webhook serão enviadas sempre que ocorrer qualquer atualização sobre o tópico reportado, incluindo criação e atualização de orders e processamento de transaçÔes.
- Acesse Suas integraçÔes e selecione a aplicação integrada com Checkout Transparente para a qual deseja ativar as notificaçÔes.
- No menu à esquerda, selecione Webhooks > Configurar notificaçÔes.
- Selecione a aba Modo de produção e forneça uma
URL HTTPS
para receber notificaçÔes com sua integração produtiva.
- Selecione o evento Order (Mercado Pago) para receber notificaçÔes, que serão enviadas em formato
JSON
através de umHTTP POST
para a URL especificada anteriormente.
- Por fim, clique em Salvar configuração. Isso gerarå uma chave secreta exclusiva para a aplicação, que permitirå validar a autenticidade das notificaçÔes recebidas, garantindo que tenham sido enviadas pelo Mercado Pago. Tenha em mente que esta chave gerada não tem prazo de validade e sua renovação periódica não é obrigatória, embora seja recomendada. Para isso, basta clicar no botão Redefinir.
Simular a recepção da notificação
Para garantir que as notificaçÔes sejam configuradas corretamente, é necessårio simular sua recepção. Para isso, siga o passo a passo abaixo.
- Após configurar a URL e o evento, clique em Salvar configuração.
- Depois, clique em Simular para testar se a URL indicada estå recebendo as notificaçÔes corretamente.
- Na tela de simulação, selecione a URL que serå testada.
- Em seguida, selecione o tipo de evento e insira a identificação que serå enviada no corpo da notificação (Data ID).
- 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 conforme o exemplo abaixo, que representa o body da notificação recebida em seu 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 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 somente as notificaçÔes legĂtimas sejam processadas.
O Mercado Pago enviarå ao seu servidor uma notificação similar ao exemplo abaixo para um alerta do tema order
. 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=ORD01JQ4S4KY8HWQ6NA5PXB65B3D3
etype=order
. - Body: O corpo da notificação contém informaçÔes detalhadas sobre o evento, como
action
,api_version
,application_id
,date_created
,id
,live_mode
,type
,user_id
edata
. - Header: O cabeçalho contém metadados importantes, incluindo a assinatura secreta da notificação
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 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. Esta chave serĂĄ enviada no header x-signature
, que serĂĄ similar ao exemplo abaixo.
plain
ts=1742505638683,v1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b
Para confirmar a validação, é necessårio extrair a chave contida no cabeçalho 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.
- Para extrair o timestamp (
ts
) e a chave (v1
) do headerx-signature
, divida o conteĂșdo do header pelo caractere â,", o que resultarĂĄ em uma lista de elementos. O valor para o prefixots
é o timestamp (em milissegundos) da notificação ev1
Ă© a chave encriptada. Seguindo o exemplo apresentado anteriormente,ts=1742505638683
ev1=ced36ab6d33566bb1e16c125819b8d840d6b8ef136b0b9127c76064466f5229b
. - 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
provĂȘ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, odata.id_url
éORD01JQ4S4KY8HWQ6NA5PXB65B3D3
. - [
x-request-id_header
] deverĂĄ ser substituĂdo pelo valor recebido no headerx-request-id
. No exemplo de notificação mencionado anteriormente, ox-request-id
é2066ca19-c6f1-498a-be75-1923005edd06
. - [
ts_header
] serĂĄ o valorts
extraĂdo do headerx-signature
. No exemplo de notificação mencionado anteriormente, ots
é1742505638683
. - Ao aplicar os dados ao template, ficaria da seguinte forma:
id:ORD01JQ4S4KY8HWQ6NA5PXB65B3D3;request-id:2066ca19-c6f1-498a-be75-1923005edd06;ts:1742505638683;
- Em Suas integraçÔes, selecione a aplicação integrada, clique em Webhooks > Configurar notificação e revele a chave secreta gerada.
- Gere a contrachave para validação. Para fazer isso, calcule um HMAC com a função de
hash SHA256
em base hexadecimal, utilizando a assinatura 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()))
- Finalmente, compare a chave gerada com a chave extraĂda do header, assegurando-se de que tenham uma correspondĂȘncia exata. 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. Isso permite estabelecer uma margem de tolerĂąncia para atrasos no recebimento da mensagem.
Veja exemplos de cĂłdigos completos abaixo:
<?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")
}
})
}
AçÔes necessårias após receber a notificação
Quando vocĂȘ recebe uma notificação em 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 essa confirmação não for enviada, 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 Ă notificação e confirmar seu recebimento, vocĂȘ pode obter todas as informaçÔes sobre o recurso notificado enviando um GET para o endpoint /v1/orders/{id}API.
Com essa informação, vocĂȘ poderĂĄ realizar as atualizaçÔes necessĂĄrias em sua plataforma, como atualizar um pagamento aprovado.