When Mercado Pago delivers a webhook notification to your endpoint, it signs the request with an HMAC-SHA256 digest so you can confirm the event genuinely originated from Mercado Pago and was not tampered with in transit. TheDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/mercadopago/sdk-java/llms.txt
Use this file to discover all available pages before exploring further.
WebhookSignatureValidator class in the SDK reconstructs that digest locally using your application’s secret and performs a constant-time comparison (via MessageDigest.isEqual) against the value in the incoming x-signature header — protecting against both forgery and timing attacks. This guide explains the signature scheme, all three validator overloads, error handling, and a complete Spring Boot example.
How Mercado Pago webhook signatures work
Every signed webhook request carries three pieces of data you need for validation:| Source | Key | Description |
|---|---|---|
| HTTP header | x-signature | Contains the timestamp (ts) and the HMAC hash (v1), e.g. ts=1719000000000,v1=abc123... |
| HTTP header | x-request-id | A unique request correlation identifier provided by Mercado Pago. |
| Query parameter | data.id | The identifier of the resource that triggered the notification (e.g., a payment ID). |
HMAC-SHA256(secret, manifest) and compares the hex result against the v1 hash from the header. If they match and the optional timestamp tolerance check passes, the request is considered authentic.
Getting your webhook secret
Open Tus Integraciones
Log in to the Mercado Pago Developer Panel and navigate to Tus Integraciones.
Go to Webhooks configuration
In the left-hand menu, click Webhooks. You will see the Secret signature field — copy this value.
Validation overloads
WebhookSignatureValidator is a stateless utility class with three static validate(...) overloads. All of them throw MPInvalidWebhookSignatureException on failure and return void on success.
1. Basic validation
The simplest overload — validates signature and hash, no replay-attack window:2. With replay-attack tolerance
Supply aDuration tolerance window. If the timestamp in x-signature is older than now ± tolerance, the validator throws SignatureFailureReason.TIMESTAMP_OUT_OF_TOLERANCE. This protects against replay attacks where a genuine but old notification is replayed by an attacker.
3. Full overload — custom versions and clock
The seven-argument overload exposes every knob, primarily for advanced use cases and testing:| Parameter | Type | Description |
|---|---|---|
xSignature | String | Raw value of the x-signature header. |
xRequestId | String | Value of the x-request-id header; may be null. |
dataId | String | Value of the data.id query parameter; may be null. |
secret | String | Your application’s webhook secret from Tus Integraciones. Must not be null. |
tolerance | Duration | Maximum allowed age of the notification; null disables the check. |
supportedVersions | List<String> | Ordered list of signature versions to accept. Defaults to ["v1"]. |
clock | Supplier<Instant> | Clock for the tolerance check. Defaults to Instant::now. |
Error handling
On any validation failure,WebhookSignatureValidator throws MPInvalidWebhookSignatureException. Inspect getReason() to understand why it failed:
SignatureFailureReason values
View all failure reasons
View all failure reasons
| Reason | Meaning |
|---|---|
MISSING_SIGNATURE_HEADER | The x-signature header was absent, empty, or whitespace-only. |
MALFORMED_SIGNATURE_HEADER | The header did not conform to the expected ts=...,v1=... format. |
MISSING_TIMESTAMP | The header parsed correctly but no ts= component was present. |
MISSING_HASH | No hash was found for any of the supported versions. This may indicate Mercado Pago has introduced a new signature version — update the SDK. |
SIGNATURE_MISMATCH | The computed HMAC did not match the value in the header. Most often caused by an incorrect secret or a forged/tampered request. |
TIMESTAMP_OUT_OF_TOLERANCE | The timestamp fell outside the configured tolerance window. May indicate clock drift or a replay attack. |
Complete Spring Boot example
The following example shows a production-ready webhook endpoint that validates the signature, processes the event asynchronously, and always responds HTTP 200 within the timeout window:Mercado Pago expects your endpoint to respond with HTTP 200 quickly (within a few seconds). If it times out, the notification will be retried. Offload any database writes, downstream API calls, or heavy processing to an async executor or message queue — as shown above.
QR Code notifications
Security notes
- Constant-time comparison — the validator uses
MessageDigest.isEqualinternally, which runs in time proportional only to the length of the strings, not their content. This prevents timing attacks that could otherwise reveal information about the correct signature. - Replay protection — enable the
Durationtolerance overload in production to reject replayed legitimate notifications. - Secret rotation — if you rotate your webhook secret in Tus Integraciones, update your environment variable before the old secret expires. During the rotation window you may receive notifications signed with either key; handle this by trying both secrets and accepting if either passes.