w7corp/easywechat · error · DecryptException
The given payload is invalid.
Error message
The given payload is invalid.
What it means
MiniApp\Decryptor::decrypt() AES-128-CBC decrypts encryptedData with sessionKey/iv and json_decodes the plaintext; when the decrypted bytes are not a non-empty JSON array it throws this bare DecryptException. However that throw happens inside the try block, so the catch (Throwable) immediately re-wraps it — the bare message only ever surfaces nested inside [38] as 'The given payload is invalid: The given payload is invalid.'. Reaching this branch means AES succeeded yet the plaintext was not the expected JSON payload.
Source
Thrown at src/MiniApp/Decryptor.php:35
{
/**
* @return array<string, mixed>
*
* @throws DecryptException
*/
public static function decrypt(string $sessionKey, string $iv, string $ciphertext): array
{
try {
$decrypted = AesCbc::decrypt(
$ciphertext,
base64_decode($sessionKey, false),
base64_decode($iv, false)
);
$decrypted = json_decode($decrypted, true);
if (! $decrypted || ! is_array($decrypted)) {
throw new DecryptException('The given payload is invalid.');
}
} catch (Throwable $e) {
throw new DecryptException(sprintf('The given payload is invalid: %s', $e->getMessage()));
}
return $decrypted;
}
}
View on GitHub (pinned to f0cf0a8b83)
Solutions
- Ensure you decrypt with the session_key from the same code2Session exchange that produced encryptedData/iv.
- Pass encryptedData exactly as the client provided — no pre-decoding or double-decrypting.
- Confirm the appid matches the mini app that issued the data.
- Catch DecryptException and re-request the data with a fresh session (see [38]).
Defensive patterns
Strategy: try-catch
Validate before calling
if ($sessionKey === '' || $iv === '' || $ciphertext === '') { throw new InvalidArgumentException('sessionKey/iv/ciphertext are all required'); }
if (strlen((string) base64_decode($iv, true)) !== 16) { throw new InvalidArgumentException('iv must base64-decode to 16 bytes'); } Try / catch
try { $data = \EasyWeChat\MiniApp\Decryptor::decrypt($sessionKey, $iv, $encryptedData); } catch (\EasyWeChat\Kernel\Exceptions\DecryptException $e) { // nested message '...invalid: The given payload is invalid.' means AES worked but plaintext was not JSON: wrong session context or appid $session = $app->getUtils()->codeToSession($freshCode); $data = \EasyWeChat\MiniApp\Decryptor::decrypt($session['session_key'], $iv, $encryptedData); } Prevention
- Pair session_key and encryptedData from one login in storage keys
- Never cache session_key longer than its validity window
- Reject non-base64 iv early
When it happens
Trigger: sessionKey/iv decrypt without an OpenSSL padding error but belong to a different login round or appid (garbage that happens to unpad); encryptedData decrypted once already (double-decryption of an already-plaintext payload); a custom payload encrypted with the same scheme but containing non-JSON bytes.
Common situations: Mixing WeChat dev-tools appid and production appid; wrappers that pre-decode data; cached session_key reused across login rounds.
Related errors
- The given payload is invalid: %s
- -40012
- The type of `json` must be string or array.
- Decrypt AES CBC error.
- Decrypt AES ECB failed.
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/66f698b6ca386468.
Report an issue: GitHub.