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

  1. Make each entry a PEM string or EasyWeChat PublicKey instance before constructing Merchant
  2. Check that file_get_contents() on each cert path returned a string starting with '-----BEGIN' and not false
  3. 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

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


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