You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Public key retrieval throws TypeError because HTTP client excludes string responses #18
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.
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: "".
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:
Activity
wzul commentedon Oct 23, 2026
Confirmed and fixed in #19.
GET /public_key/returns a JSON-encoded PEM string (quotes included), butGuzzleClient::request()declared\stdClass|arrayand didjson_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 makesPublicKeyResource::get()return the bare PEM so it can go straight intoChipApi::verify(). Regression tests cover the JSON-encoded PEM, a plain-text PEM body, and the legacy{"public_key": …}object body; thefetch → verify()round trip is asserted too. All CI checks pass.wzul commentedon Oct 23, 2026
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), whileGuzzleClient::request()declared\stdClass|array. The decoded string violated the return type, andPublicKeyResource::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 returnstdClass). Implementations that keep the narrower\stdClass|arrayremain valid by covariance.PublicKeyResource::get()returns the bare PEM (trimmed, ready foropenssl_verify()/ChipApi::verify()), and still accepts the legacy{"public_key": …}object body.detail/messageis a list or object, and JSON-scalar error bodies, now raise a catchableChipApiExceptioninstead of aTypeError; paginatediterate()no longer passesnext: falseto the client (TypeError) or loops onnext: "".Usage after upgrading — no code change needed:
Verified against the live gateway:
get()returns a 3072-bit RSA PEM that the gateway accepts, and a realsuccess_callbackdelivered for a test-mode purchase verifies astrue(a tampered body returnsfalse).Install: the package is not on Packagist, so add the repository explicitly:
Thanks for the clear report — it also surfaced three sibling
TypeErrorshapes, all covered by regression tests in this release.