w7corp/easywechat · error · InvalidArgumentException
Invalid platform certficate.
Error message
Invalid platform certficate.
What it means
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.
Source
Thrown at src/Pay/Merchant.php:88
}
/**
* @param array<array-key, mixed> $platformCerts
* @return array<string, PublicKey>
*
* @throws InvalidArgumentException
*/
protected function normalizePlatformCerts(array $platformCerts): array
{
$certs = [];
$isList = array_is_list($platformCerts);
foreach ($platformCerts as $index => $publicKey) {
if (is_string($publicKey)) {
$publicKey = new PublicKey($publicKey);
}
if (! $publicKey instanceof PublicKey) {
throw new InvalidArgumentException('Invalid platform certficate.');
}
$certs[$isList ? $publicKey->getSerialNo() : $index] = $publicKey;
}
return $certs;
}
}
View on GitHub (pinned to f0cf0a8b83)
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
Example fix
// before
new Merchant($mchId, $privKey, $cert, $secretKey, null, [
['pem' => file_get_contents('/certs/platform.pem')], // nested array -> throws
]);
// after
new Merchant($mchId, $privKey, $cert, $secretKey, null, [
file_get_contents('/certs/platform.pem'), // plain PEM string
]); Defensive patterns
Strategy: type-guard
Validate before calling
foreach ($platformCerts as $i => $c) {
if (! ($c instanceof \EasyWeChat\Kernel\Support\PublicKey || (is_string($c) && str_starts_with(trim($c), '-----BEGIN')))) {
unset($platformCerts[$i]); // or fail fast
}
}
$merchant = new Merchant($mchId, $priv, $cert, $key, $v2, $platformCerts); Type guard
/**
* @param mixed $cert
*/
function isPlatformCertInput(mixed $cert): bool
{
return $cert instanceof \EasyWeChat\Kernel\Support\PublicKey
|| (is_string($cert) && str_contains($cert, '-----BEGIN'));
} Try / catch
try {
new Merchant(..., $platformCerts);
} catch (\EasyWeChat\Kernel\Exceptions\InvalidArgumentException $e) {
if ($e->getMessage() === 'Invalid platform certficate.') {
// sanitize entries to PEM strings and retry construction
}
} Prevention
- 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
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Missing platform certificate.
- Missing platform certificate.
- Missing V2 API key.
- V2 secret key is required.
- Encrypt failed.
AI-assisted analysis of w7corp/easywechat@f0cf0a8b83 (2026-08-21).
Data as JSON: /api/errors/c0b0ded4e521b573.
Report an issue: GitHub.