TL;DR: Your /payments/details call is missing PaRes or MD from the 3D Secure return. Log both parameters on your return URL and forward them exactly as received; Adyen needs the pair to complete authentication.

The exact error:

```text
14_028 - 3D Auth Data is incomplete
```

## The fix

1. Log every parameter the issuer posts back to your return URL.
   Expected: Both parameters arrive on your return URL.
2. Forward PaRes and MD exactly as received into the /payments/details request.
   Expected: Neither value is dropped or double-encoded.
3. Handle empty values as missing and re-prompt rather than sending blanks.
   Expected: Adyen completes authentication and returns a final resultCode.

## When this applies

- /payments/details returns 14_028 after a 3DS redirect
- Your return-URL handler was recently rewritten
- A framework upgrade changed how POST fields are parsed

## When it does NOT apply

- 3D Secure 2 flows (those use fingerprint and challengeResult fields)
- The values are present but rejected (that points at the issuer, not your code)
- /payments calls, which never carry PaRes or MD

## Versions

Adyen Checkout API v68 through v71. Classic 3D Secure only.

## Why it happens

Classic 3D Secure authentication is a signed pair: PaRes carries the result and MD links it to the payment. With only one half, Adyen cannot verify the authentication, so it rejects the details call.

## Edge cases and pitfalls

- Some issuers URL-encode PaRes; Adyen expects it decoded exactly once
- An empty PaRes string counts as missing, not as invalid
- The classic 3DS 14_028 is distinct from the 3DS2 fingerprint errors in the 14_032 family
