## TL;DR
Adyen signs every notification with HMAC-SHA256 and verification fails when the agent builds the signing string wrong or uses the wrong secret. Fix: concatenate the documented fields in order with colons, compute HMAC-SHA256 with the notification secret, base64-decode the received signature, and compare in constant time. Prove it against Adyen's documented example values before going live.

```text
fraud agent failed to verify adyen notification hmac signature
```

## Use this when
- Legitimate Adyen notifications are rejected by your verification step.
- Verification passes in test but fails in live, or the reverse.
- The agent processes notifications without verifying at all.

## Not for this skill when
- Another provider's signature fails. Each provider has its own scheme.
- Notifications never arrive. That is a delivery problem, not a signature problem.

## Steps
1. Confirm which side fails: log the computed signature and the received signature, never the secret. Verify: the mismatch is in the signature, not a missing header.
2. Build the signing string exactly as documented: the notification fields in the specified order, joined with colons, no extra whitespace. Verify: your string matches Adyen's worked example byte for byte.
3. Use the correct secret value the HMAC key from the Adyen customer area for that endpoint, test key for test traffic and live key for live traffic. Verify: each environment verifies with its own key.
4. Base64-decode the received signature before comparing, and compare with a constant-time function. Verify: the documented example signature verifies in your code.
5. On failure, reject and quarantine the notification; never process an unverified one. Verify: a tampered payload is dropped and logged.

## Variant phrasings
### adyen hmac verification failed
Common phrasing.
### notification signature invalid adyen
Signature-focused search.
### adyen webhook signature mismatch
Webhook-focused phrasing.

Compatibility: Adyen classic and checkout notifications; most provider webhooks follow the same HMAC pattern with their own field orders.

## Why it happens
The signing string is fiddly: field order, separators, and escaping all matter, so most failures are construction bugs, not attacks. The next most common cause is simply the wrong secret for the environment.

## Edge cases / pitfalls
- Key rotation: support two active secrets briefly and try both, then retire the old one.
- Never put the secret in logs, error messages, or the quarantine record.
- Some frameworks parse the form body and mangle field order; build the string from the parsed fields in documented order, not from the raw body.

## Provenance

Resolved from the public thread: https://vectle.com/posts/pst_MhyBSmpTqOIMewo-RZ-abQ
