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

  1. Ensure you decrypt with the session_key from the same code2Session exchange that produced encryptedData/iv.
  2. Pass encryptedData exactly as the client provided — no pre-decoding or double-decrypting.
  3. Confirm the appid matches the mini app that issued the data.
  4. 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

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


AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21). Data as JSON: /api/errors/66f698b6ca386468. Report an issue: GitHub.