Skip to content

Public key retrieval throws TypeError because HTTP client excludes string responses #18

Closed

Description

@jeshtan

Calling $chipApi->publicKey->get() throws a TypeError, preventing callback signature verification using the SDK.

Actual result
Chip\Http\GuzzleClient::request(): Return value must be of type stdClass|array, string returned

Expected result
Return the public key without throwing a type error, allowing it to be used with ChipApi::verify().

Activity

  1. wzul commented on Oct 23, 2026

    @wzul
    Collaborator

    Confirmed and fixed in #19.

    GET /public_key/ returns a JSON-encoded PEM string (quotes included), but GuzzleClient::request() declared \stdClass|array and did json_decode($body, true) ?? new stdClass(), so the decoded string violated the return type. Even without the type error, PublicKeyResource::get() did (array) $response / $arr["public_key"], which yields "" for a string body.

    #19 widens the HTTP client return type to \stdClass|array<string, mixed>|string, returns decoded string (and plain-text) bodies as-is, and makes PublicKeyResource::get() return the bare PEM so it can go straight into ChipApi::verify(). Regression tests cover the JSON-encoded PEM, a plain-text PEM body, and the legacy {"public_key": …} object body; the fetch → verify() round trip is asserted too. All CI checks pass.

  2. wzul commented on Oct 23, 2026

    @wzul
    Collaborator

    Fixed and released in v2.1.1 (merge commit fc0417, tagged today).

    Root cause: GET /public_key/ answers with a JSON-encoded PEM string ("-----BEGIN PUBLIC KEY-----\n…", quotes included), while GuzzleClient::request() declared \stdClass|array. The decoded string violated the return type, and PublicKeyResource::get() would additionally have read it as (array) $response[public_key] → "".

    What changed in v2.1.1:

    • ClientInterface/GuzzleClient/RetryClient::request() return type is now \stdClass|array<string, mixed>|string; decoded string bodies are returned as-is and plain-text bodies are no longer discarded (empty bodies still return stdClass). Implementations that keep the narrower \stdClass|array remain valid by covariance.
    • PublicKeyResource::get() returns the bare PEM (trimmed, ready for openssl_verify() / ChipApi::verify()), and still accepts the legacy {"public_key": …} object body.
    • Same bug class fixed alongside it: error bodies whose detail/message is a list or object, and JSON-scalar error bodies, now raise a catchable ChipApiException instead of a TypeError; paginated iterate() no longer passes next: false to the client (TypeError) or loops on next: "".

    Usage after upgrading — no code change needed:

    $publicKey = $chip->publicKey->get();
    $isValid   = ChipApi::verify($rawBody, $signatureHeader, $publicKey);

    Verified against the live gateway: get() returns a 3072-bit RSA PEM that the gateway accepts, and a real success_callback delivered for a test-mode purchase verifies as true (a tampered body returns false).

    Install: the package is not on Packagist, so add the repository explicitly:

    "repositories": [{ "type": "vcs", "url": "git@github.com:CHIPAsia/chip-php-sdk.git" }],
    "require": { "chip/chip-sdk-php": "^2.1.1" }

    Thanks for the clear report — it also surfaced three sibling TypeError shapes, all covered by regression tests in this release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions