{"record":{"id":"c0b0ded4e521b573","repo":"w7corp/easywechat","slug":"invalid-platform-certficate","errorCode":null,"errorMessage":"Invalid platform certficate.","messagePattern":"Invalid platform certficate\\.","errorType":"exception","errorClass":"InvalidArgumentException","httpStatus":null,"severity":"error","filePath":"src/Pay/Merchant.php","lineNumber":88,"sourceCode":"    }\n\n    /**\n     * @param  array<array-key, mixed>  $platformCerts\n     * @return array<string, PublicKey>\n     *\n     * @throws InvalidArgumentException\n     */\n    protected function normalizePlatformCerts(array $platformCerts): array\n    {\n        $certs = [];\n        $isList = array_is_list($platformCerts);\n        foreach ($platformCerts as $index => $publicKey) {\n            if (is_string($publicKey)) {\n                $publicKey = new PublicKey($publicKey);\n            }\n\n            if (! $publicKey instanceof PublicKey) {\n                throw new InvalidArgumentException('Invalid platform certficate.');\n            }\n\n            $certs[$isList ? $publicKey->getSerialNo() : $index] = $publicKey;\n        }\n\n        return $certs;\n    }\n}\n","sourceCodeStart":70,"sourceCodeEnd":97,"githubUrl":"https://github.com/w7corp/easywechat/blob/f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8/src/Pay/Merchant.php#L70-L97","documentation":"Thrown by Merchant::normalizePlatformCerts() during construction when a platformCerts entry is neither a PEM string nor a PublicKey instance. (The message contains a library typo: 'certficate'.) Each entry must be a string (auto-wrapped into PublicKey) or a PublicKey object; anything else — int keys with wrong values, resources, SimpleXMLElement, null — is rejected.","triggerScenarios":"Constructing Merchant with platformCerts values that are not string|PublicKey: e.g. an array of [serial => filename-path?] where the value is an object like \\OpenSSLCertificate, a null from failed file_get_contents, or a nested array from bad config parsing.","commonSituations":"Config loader returning nested arrays instead of strings; file_get_contents returning false (then cast) for a missing cert file; passing certificate handles obtained from openssl_x509_parse instead of PEM text; empty-string entries after env interpolation.","solutions":["Make each entry a PEM string or EasyWeChat PublicKey instance before constructing Merchant","Check that file_get_contents() on each cert path returned a string starting with '-----BEGIN' and not false","Normalize config: map over your config array and fail fast if any entry is not is_string / PublicKey"],"exampleFix":"// before\nnew Merchant($mchId, $privKey, $cert, $secretKey, null, [\n    ['pem' => file_get_contents('/certs/platform.pem')], // nested array -> throws\n]);\n// after\nnew Merchant($mchId, $privKey, $cert, $secretKey, null, [\n    file_get_contents('/certs/platform.pem'), // plain PEM string\n]);","handlingStrategy":"type-guard","validationCode":"foreach ($platformCerts as $i => $c) {\n    if (! ($c instanceof \\EasyWeChat\\Kernel\\Support\\PublicKey || (is_string($c) && str_starts_with(trim($c), '-----BEGIN')))) {\n        unset($platformCerts[$i]); // or fail fast\n    }\n}\n$merchant = new Merchant($mchId, $priv, $cert, $key, $v2, $platformCerts);","typeGuard":"/**\n * @param mixed $cert\n */\nfunction isPlatformCertInput(mixed $cert): bool\n{\n    return $cert instanceof \\EasyWeChat\\Kernel\\Support\\PublicKey\n        || (is_string($cert) && str_contains($cert, '-----BEGIN'));\n}","tryCatchPattern":"try {\n    new Merchant(..., $platformCerts);\n} catch (\\EasyWeChat\\Kernel\\Exceptions\\InvalidArgumentException $e) {\n    if ($e->getMessage() === 'Invalid platform certficate.') {\n        // sanitize entries to PEM strings and retry construction\n    }\n}","preventionTips":["Load certs from files and check file_get_contents() !== false before passing","Keep config sources flat: array of PEM strings only","Add a startup smoke test constructing Merchant with production config"],"tags":["wechat-pay","platform-certificate","invalid-argument","merchant-config"],"backgroundTag":"invalid-certificate-format","analyzedSha":"f0cf0a8b8361417ed683b8246d0ecbaf0aafcaa8","analyzedAt":"2026-08-21T05:29:19.565Z","schemaVersion":2},"datasetVersion":"2026-08-21T11:28:35.574Z"}