NotificaçÔes
As notificaçÔes são mensagens enviadas pelo servidor do Mercado Pago a partir de eventos realizados em sua aplicação.
Webhooks (também conhecido como retorno de chamada web) utiliza HTTP REST para notificar instantaneamente as atualizaçÔes e oferece maior segurança na integração por meio de uma assinatura secreta. Este método de validação garante que as notificaçÔes recebidas são enviadas pelo Mercado Pago.
Uma vez configuradas, as notificaçÔes Webhooks serĂŁo enviadas sempre que ocorrer um ou mais eventos cadastrados. Isso evita a necessidade de verificaçÔes constantes, prevenindo a sobrecarga do sistema e a perda de dados em situaçÔes crĂticas.
Configurar notificaçÔes Webhooks
As notificaçÔes Webhooks podem ser configuradas para cada uma das aplicaçÔes criadas em Suas integraçÔes. VocĂȘ tambĂ©m poderĂĄ configurar uma URL de teste que, junto com suas credenciais de teste, permitirĂĄ testar o funcionamento correto das suas notificaçÔes antes de sair Ă produção.
Uma vez configuradas, as notificaçÔes Webhooks serĂŁo enviadas sempre que ocorrer um ou mais eventos cadastrados. Isso evita a necessidade de verificaçÔes constantes, prevenindo a sobrecarga do sistema e a perda de dados em situaçÔes crĂticas.
Para configurar as notificaçÔes Webhooks de Order, siga as etapas descritas abaixo.
- Acesse Suas integraçÔes e selecione a aplicação para a qual deseja ativar as notificaçÔes. Caso ainda não tenha criado uma aplicação, acesse a documentação Painel do Desenvolvedor e siga as instruçÔes.
- No menu à esquerda, vå até Webhooks > Configurar notificaçÔes e configure as URLs que serão usadas para receber as notificaçÔes. Recomendamos utilizar uma URL diferente para o modo de teste e o modo produção:
- URL modo teste: fornece uma URL que permite testar o correto funcionamento das notificaçÔes dessa aplicação durante a fase de teste ou desenvolvimento.
- URL modo produção: fornece uma URL para receber notificaçÔes com sua integração produtiva. Essas notificaçÔes deverão ser configuradas com credenciais produtivas.
- Selecione o evento Order (Mercado Pago) para receber as notificaçÔes em formato
json
através de umHTTP POST
para a URL especificada anteriormente. Um evento pode ser qualquer atualização no objeto relatado, incluindo criação e atualização de orders e processamento de transaçÔes. - Por fim, clique em Salvar para gerar uma assinatura secreta exclusiva para a sua aplicação, permitindo validar a autenticidade das notificaçÔes recebidas e garantir que tenham sido enviadas pelo Mercado Pago. A assinatura gerada não tem prazo de validade e sua renovação periódica não é obrigatória, embora seja altamente recomendåvel. Para renovå-la, clique no botão de Redefinição ao lado da assinatura.
Validar origem da notificação
As notificaçÔes enviadas pelo Mercado Pago serão semelhantes ao exemplo abaixo para um alerta do tópico order
:
json
{
"action": "processed",
"type": "order",
"user_id": "123456",
"application_id": "789012",
"live_mode": true,
"api_version": "v1",
"date_created": "2024-01-01T00:00:00Z",
"data": {
"id": "01J35M8KHVFY0GQGDZJ94QXKMJ",
"type": "online",
"external_reference": "ext_ref_1234",
"status": "processed",
"version": 1,
"transactions": {
"payments": [
{
"id": "pay_01J3E4R55CTGYCEXCKSQB6RKDE",
"status": "processed",
"payment_method": {
"id": "visa",
"type": "credit_card",
"installments": 1
}
}
]
}
}
}
O Mercado Pago sempre incluirĂĄ a assinatura secreta nas notificaçÔes Webhooks recebidas na URL cadastrada. Isso permitirĂĄ validar a sua autenticidade, proporcionando maior segurança e prevenindo possĂveis fraudes.
Esta assinatura serĂĄ enviada no header x-signature
, conforme o exemplo abaixo.
x-signature
`ts=1704908010,v1=618c85345248dd820d5fd456117c2ab2ef8eda45a0282ff693eac24131a5e839`
Para configurar essa 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 as etapas abaixo.
- Para extrair o timestamp (
ts
) e a assinatura do headerx-signature
, divida o conteĂșdo do header pelo caractere,
, o que resultarĂĄ em uma lista de 2 elementos. O valor para o prefixots
é o timestamp (em milissegundos) da notificação, ev1
Ă© a assinatura encriptada. Seguindo o exemplo apresentado acima,ts=1704908010
ev1=618c85345248dd820d5fd456117c2ab2ef8eda45a0282ff693eac24131a5e839
. - Utilizando o template e as descriçÔes abaixo, substitua os parùmetros pelos dados recebidos na sua notificação.
template
id:[data.id_url];request-id:[x-request-id_header];ts:[ts_header];
- ParĂąmetros com sufixo
_url
sĂŁo provenientes de query params. Exemplo:[data.id_url]
. Deve ser substituĂdo pelo valor correspondente ao ID do evento (data.id
). Essequery param
poderå ser encontrado na notificação recebida. [ts_header]
representa o valorts
extraĂdo do headerx-signature
.[x-request-id_header]
deve ser substituĂdo pelo valor recebido no headerx-request-id
.
- Em Suas integraçÔes, selecione a aplicação integrada e navegue até a seção de Webhooks para visualizar a assinatura secreta gerada.
- Crie a contra chave para validação. Para isso, calcule um HMAC (Código de Autenticação de Mensagem Baseado em Hash) utilizando a função de
hash SHA256
em base hexadecimal. Utilize a assinatura secreta como chave e o template preenchido com os respectivos 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()))
- Por fim, compare a chave gerada com a chave extraĂda do header, assegurando que correspondam exatamente. AlĂ©m disso, Ă© possĂvel usar o timestamp extraĂdo do header para comparĂĄ-lo com um timestamp gerado no momento do recebimento 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")
}
})
}
Simular o recebimento da notificação
Para garantir que as notificaçÔes estejam configuradas corretamente, é necessårio simular o recebimento delas. Para isso, siga os seguintes passos:
- Após configurar as URLs e os eventos desejados, clique em Salvar para salvar a configuração.
- Após isso, clique em Simular para testar se a URL indicada estå recebendo as notificaçÔes corretamente.
- Na tela de simulação, selecione a URL a ser testada, podendo ser uma URL de teste ou de produção.
- Em seguida, selecione o evento Order (Mercado Pago) e insira a identificação que serå enviada no corpo da notificação.
- Por fim, clique em Enviar teste para verificar a solicitação, a resposta dada pelo servidor e a descrição do evento.
AçÔes necessårias após receber uma notificação
Ao receber uma notificação em sua plataforma, o Mercado Pago aguarda uma resposta para validar se vocĂȘ a recebeu corretamente. Para isso, Ă© necessĂĄrio retornar um status HTTP STATUS 200 (OK)
ou 201 (CREATED)
.
O tempo de espera para a confirmação da recepção das notificaçÔes 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å novas tentativas de envio a cada 15 minutos, até receber uma 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, Ă© possĂvel obter as informaçÔes completas do recurso notificado enviando um GET ao endpoint /v1/orders/{id}.
Com essas informaçÔes, vocĂȘ poderĂĄ realizar as atualizaçÔes necessĂĄrias na sua plataforma como, por exemplo, atualizar um pagamento aprovado.