## TL;DR
Adyen signs each notification with HMAC-SHA256 over a colon-joined string of specific fields, keyed by the HMAC key in your Customer Area. A mismatch usually means the wrong key (test vs live) or fields joined in the wrong order. Rebuild the signing string per the docs and compare with a constant-time check.

```text
adyen notification signature invalid on dispute webhook
```

## Use this when
- Every Adyen notification fails signature verification.
- Dispute notifications fail while payment notifications pass.
- Verification worked before a key rotation.

## Not for this skill when
- Notifications never arrive. That is a configuration or endpoint problem.
- Verification passes but your handler misreads the payload.

## Steps
1. Copy the current HMAC key from the Customer Area for the matching environment. Verify: the key label matches test or live exactly.
2. Build the signing string by joining the documented fields with colons, in the documented order, with no extra whitespace. Verify: a known-good sample notification from the docs verifies with your code.
3. Compute HMAC-SHA256 over the signing string with the HMAC key. Verify: your digest is hex and the same length as the signature in the notification.
4. Compare the two with a constant-time comparison. Verify: the sample passes and a tampered field fails.
5. If it still fails, print the signing string field by field against the received notification and find the divergence. Verify: every field in your string matches the payload exactly.

## Variant phrasings
### adyen hmac signature invalid notification
Common shorthand.
### adyen webhook signature verification failed
Webhook-wording search.
### adyen notification hmac mismatch
Log-line wording.

Compatibility: Adyen notifications. The HMAC key is per environment and lives in the Customer Area; the signed fields and their order are fixed by Adyen's spec.

## Why it happens
The signing string is order-sensitive and unforgiving. One field out of place, one extra space, or the test key verifying live traffic all produce the same invalid signature. Key rotations are the other classic: the new key is live in Adyen before your config is updated.

## Edge cases / pitfalls
- Some fields can be empty strings and still must appear in the join. Dropping empty fields breaks the signature.
- Do not URL-decode or re-encode fields before joining. Sign what arrived.
- Keep the old key active during rotation until the new one verifies on live traffic.
- Log signatures and digests, never the HMAC key.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_V8UWJLTLfO5FY2KO_xAv6A
