diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 3d83d67..dd5fa7c 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -7,7 +7,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-versions: ['8.0', '8.1', '8.2', '8.3', 'nightly'] + php-versions: ['8.5', 'nightly'] steps: - name: Checkout repository diff --git a/composer.json b/composer.json index e9965ac..0a0897a 100644 --- a/composer.json +++ b/composer.json @@ -18,8 +18,11 @@ "psr-4": {"Utopia\\Tests\\": "tests/Pay"} }, "require": { - "php": ">=8.1", - "utopia-php/fetch": "^1.1" + "php": ">=8.5", + "psr/http-client": "^1.0", + "psr/http-message": "^2.0", + "utopia-php/client": "^0.3", + "utopia-php/psr7": "^0.2" }, "require-dev": { "phpunit/phpunit": "^9.4", diff --git a/composer.lock b/composer.lock index 7930aa4..fa5f481 100644 --- a/composer.lock +++ b/composer.lock @@ -4,47 +4,2128 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "70bb4494892fa58ef903d956afd42e66", + "content-hash": "b3c2a29c4d562c8e77bdbdaf1a127098", "packages": [ { - "name": "utopia-php/fetch", - "version": "1.1.2", + "name": "brick/math", + "version": "0.18.0", "source": { "type": "git", - "url": "https://github.com/utopia-php/fetch.git", - "reference": "64f2b3a789480f1deb102ce684dac4217d8e98d5" + "url": "https://github.com/brick/math.git", + "reference": "82944324d1c1bdb2c2618e89978d4e2ad78d69ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/fetch/zipball/64f2b3a789480f1deb102ce684dac4217d8e98d5", - "reference": "64f2b3a789480f1deb102ce684dac4217d8e98d5", + "url": "https://api.github.com/repos/brick/math/zipball/82944324d1c1bdb2c2618e89978d4e2ad78d69ad", + "reference": "82944324d1c1bdb2c2618e89978d4e2ad78d69ad", + "shasum": "" + }, + "require": { + "php": "^8.2" + }, + "require-dev": { + "phpstan/phpstan": "2.1.22", + "phpunit/phpunit": "^11.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Brick\\Math\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Arbitrary-precision arithmetic library", + "keywords": [ + "Arbitrary-precision", + "BigInteger", + "BigRational", + "arithmetic", + "bigdecimal", + "bignum", + "bignumber", + "brick", + "decimal", + "integer", + "math", + "mathematics", + "rational" + ], + "support": { + "issues": "https://github.com/brick/math/issues", + "source": "https://github.com/brick/math/tree/0.18.0" + }, + "funding": [ + { + "url": "https://github.com/BenMorel", + "type": "github" + } + ], + "time": "2026-06-14T18:21:03+00:00" + }, + { + "name": "composer/semver", + "version": "3.4.4", + "source": { + "type": "git", + "url": "https://github.com/composer/semver.git", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/semver/zipball/198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "reference": "198166618906cb2de69b95d7d47e5fa8aa1b2b95", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Semver\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nils Adermann", + "email": "naderman@naderman.de", + "homepage": "http://www.naderman.de" + }, + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + }, + { + "name": "Rob Bast", + "email": "rob.bast@gmail.com", + "homepage": "http://robbast.nl" + } + ], + "description": "Semver library that offers utilities, version constraint parsing and validation.", + "keywords": [ + "semantic", + "semver", + "validation", + "versioning" + ], + "support": { + "irc": "ircs://irc.libera.chat:6697/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.4.4" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + } + ], + "time": "2025-08-20T19:15:30+00:00" + }, + { + "name": "google/protobuf", + "version": "v5.35.1", + "source": { + "type": "git", + "url": "https://github.com/protocolbuffers/protobuf-php.git", + "reference": "55bb4a7d6739b5af0927b96213c1371a3afb7cfb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/protocolbuffers/protobuf-php/zipball/55bb4a7d6739b5af0927b96213c1371a3afb7cfb", + "reference": "55bb4a7d6739b5af0927b96213c1371a3afb7cfb", + "shasum": "" + }, + "require": { + "php": ">=8.2.0" + }, + "require-dev": { + "phpunit/phpunit": ">=11.5.0 <12.0.0" + }, + "suggest": { + "ext-bcmath": "Need to support JSON deserialization" + }, + "type": "library", + "autoload": { + "psr-4": { + "Google\\Protobuf\\": "src/Google/Protobuf", + "GPBMetadata\\Google\\Protobuf\\": "src/GPBMetadata/Google/Protobuf" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "proto library for PHP", + "homepage": "https://developers.google.com/protocol-buffers/", + "keywords": [ + "proto" + ], + "support": { + "source": "https://github.com/protocolbuffers/protobuf-php/tree/v5.35.1" + }, + "time": "2026-06-11T21:19:23+00:00" + }, + { + "name": "nyholm/psr7", + "version": "1.8.2", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7.git", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7/zipball/a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "reference": "a71f2b11690f4b24d099d6b16690a90ae14fc6f3", + "shasum": "" + }, + "require": { + "php": ">=7.2", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "provide": { + "php-http/message-factory-implementation": "1.0", + "psr/http-factory-implementation": "1.0", + "psr/http-message-implementation": "1.0" + }, + "require-dev": { + "http-interop/http-factory-tests": "^0.9", + "php-http/message-factory": "^1.0", + "php-http/psr7-integration-tests": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "symfony/error-handler": "^4.4" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.8-dev" + } + }, + "autoload": { + "psr-4": { + "Nyholm\\Psr7\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "A fast PHP7 implementation of PSR-7", + "homepage": "https://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7/issues", + "source": "https://github.com/Nyholm/psr7/tree/1.8.2" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2024-09-09T07:06:30+00:00" + }, + { + "name": "nyholm/psr7-server", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/Nyholm/psr7-server.git", + "reference": "4335801d851f554ca43fa6e7d2602141538854dc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nyholm/psr7-server/zipball/4335801d851f554ca43fa6e7d2602141538854dc", + "reference": "4335801d851f554ca43fa6e7d2602141538854dc", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "require-dev": { + "nyholm/nsa": "^1.1", + "nyholm/psr7": "^1.3", + "phpunit/phpunit": "^7.0 || ^8.5 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Nyholm\\Psr7Server\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Tobias Nyholm", + "email": "tobias.nyholm@gmail.com" + }, + { + "name": "Martijn van der Ven", + "email": "martijn@vanderven.se" + } + ], + "description": "Helper classes to handle PSR-7 server requests", + "homepage": "http://tnyholm.se", + "keywords": [ + "psr-17", + "psr-7" + ], + "support": { + "issues": "https://github.com/Nyholm/psr7-server/issues", + "source": "https://github.com/Nyholm/psr7-server/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/Zegnat", + "type": "github" + }, + { + "url": "https://github.com/nyholm", + "type": "github" + } + ], + "time": "2023-11-08T09:30:43+00:00" + }, + { + "name": "open-telemetry/api", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/api.git", + "reference": "7c029c4a6fd457094a20569bf98f93d95e9a7559" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/api/zipball/7c029c4a6fd457094a20569bf98f93d95e9a7559", + "reference": "7c029c4a6fd457094a20569bf98f93d95e9a7559", + "shasum": "" + }, + "require": { + "open-telemetry/context": "^1.4", + "php": "^8.1", + "psr/log": "^1.1|^2.0|^3.0", + "symfony/polyfill-php82": "^1.26" + }, + "conflict": { + "open-telemetry/sdk": "<=1.11" + }, + "type": "library", + "extra": { + "spi": { + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" + ] + }, + "branch-alias": { + "dev-main": "1.8.x-dev" + } + }, + "autoload": { + "files": [ + "Trace/functions.php" + ], + "psr-4": { + "OpenTelemetry\\API\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "API for OpenTelemetry PHP.", + "keywords": [ + "Metrics", + "api", + "apm", + "logging", + "opentelemetry", + "otel", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2026-07-06T12:28:04+00:00" + }, + { + "name": "open-telemetry/context", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/context.git", + "reference": "3c414b246e0dabb7d6145404e6a5e4536ca18d07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/context/zipball/3c414b246e0dabb7d6145404e6a5e4536ca18d07", + "reference": "3c414b246e0dabb7d6145404e6a5e4536ca18d07", + "shasum": "" + }, + "require": { + "php": "^8.1", + "symfony/polyfill-php82": "^1.26" + }, + "suggest": { + "ext-ffi": "To allow context switching in Fibers" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0.x-dev" + } + }, + "autoload": { + "files": [ + "fiber/initialize_fiber_handler.php" + ], + "psr-4": { + "OpenTelemetry\\Context\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "Context implementation for OpenTelemetry PHP.", + "keywords": [ + "Context", + "opentelemetry", + "otel" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2025-10-19T06:44:33+00:00" + }, + { + "name": "open-telemetry/exporter-otlp", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/exporter-otlp.git", + "reference": "283a0d66522f2adc6d8d7debfd7686be91c282be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/exporter-otlp/zipball/283a0d66522f2adc6d8d7debfd7686be91c282be", + "reference": "283a0d66522f2adc6d8d7debfd7686be91c282be", + "shasum": "" + }, + "require": { + "open-telemetry/api": "^1.0", + "open-telemetry/gen-otlp-protobuf": "^1.1", + "open-telemetry/sdk": "^1.0", + "php": "^8.1", + "php-http/discovery": "^1.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.0.x-dev" + } + }, + "autoload": { + "files": [ + "_register.php" + ], + "psr-4": { + "OpenTelemetry\\Contrib\\Otlp\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "OTLP exporter for OpenTelemetry.", + "keywords": [ + "Metrics", + "exporter", + "gRPC", + "http", + "opentelemetry", + "otel", + "otlp", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2026-02-05T09:44:52+00:00" + }, + { + "name": "open-telemetry/gen-otlp-protobuf", + "version": "1.10.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/gen-otlp-protobuf.git", + "reference": "66f04d0e448ad333033bfc7baae1aa56330be088" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/gen-otlp-protobuf/zipball/66f04d0e448ad333033bfc7baae1aa56330be088", + "reference": "66f04d0e448ad333033bfc7baae1aa56330be088", + "shasum": "" + }, + "require": { + "google/protobuf": "^3.22 || ^4.0 || ^5.0", + "php": "^8.0" + }, + "suggest": { + "ext-protobuf": "For better performance, when dealing with the protobuf format" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Opentelemetry\\Proto\\": "Opentelemetry/Proto/", + "GPBMetadata\\Opentelemetry\\": "GPBMetadata/Opentelemetry/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "PHP protobuf files for communication with OpenTelemetry OTLP collectors/servers.", + "keywords": [ + "Metrics", + "apm", + "gRPC", + "logging", + "opentelemetry", + "otel", + "otlp", + "protobuf", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2026-06-17T12:06:32+00:00" + }, + { + "name": "open-telemetry/sdk", + "version": "1.15.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/sdk.git", + "reference": "77e1aa73850154abb86937d52a70883edc3b4547" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/sdk/zipball/77e1aa73850154abb86937d52a70883edc3b4547", + "reference": "77e1aa73850154abb86937d52a70883edc3b4547", + "shasum": "" + }, + "require": { + "ext-json": "*", + "nyholm/psr7-server": "^1.1", + "open-telemetry/api": "^1.8", + "open-telemetry/context": "^1.4", + "open-telemetry/sem-conv": "^1.38.0", + "php": "^8.1", + "php-http/discovery": "^1.14", + "psr/http-client": "^1.0", + "psr/http-client-implementation": "^1.0", + "psr/http-factory-implementation": "^1.0", + "psr/http-message": "^1.0.1|^2.0", + "psr/log": "^1.1|^2.0|^3.0", + "ramsey/uuid": "^3.0 || ^4.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php82": "^1.26", + "tbachert/spi": "^1.0.5" + }, + "suggest": { + "ext-gmp": "To support unlimited number of synchronous metric readers", + "ext-mbstring": "To increase performance of string operations", + "open-telemetry/sdk-configuration": "File-based OpenTelemetry SDK configuration" + }, + "type": "library", + "extra": { + "spi": { + "OpenTelemetry\\API\\Configuration\\ConfigEnv\\EnvComponentLoader": [ + "OpenTelemetry\\API\\Instrumentation\\Configuration\\General\\ConfigEnv\\EnvComponentLoaderHttpConfig", + "OpenTelemetry\\API\\Instrumentation\\Configuration\\General\\ConfigEnv\\EnvComponentLoaderPeerConfig", + "OpenTelemetry\\SDK\\ConfigEnv\\Trace\\SpanSuppressionStrategySemConv", + "OpenTelemetry\\SDK\\ConfigEnv\\Trace\\SpanSuppressionStrategySpanKind", + "OpenTelemetry\\SDK\\ConfigEnv\\Distribution\\DistributionConfigurationSdk" + ], + "OpenTelemetry\\SDK\\Common\\Configuration\\Resolver\\ResolverInterface": [ + "OpenTelemetry\\SDK\\Common\\Configuration\\Resolver\\SdkConfigurationResolver" + ], + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\HookManagerInterface": [ + "OpenTelemetry\\API\\Instrumentation\\AutoInstrumentation\\ExtensionHookManager" + ] + }, + "branch-alias": { + "dev-main": "1.14.x-dev" + } + }, + "autoload": { + "files": [ + "Common/Util/functions.php", + "Logs/Exporter/_register.php", + "Metrics/MetricExporter/_register.php", + "Propagation/_register.php", + "Trace/SpanExporter/_register.php", + "Common/Dev/Compatibility/_load.php", + "_autoload.php" + ], + "psr-4": { + "OpenTelemetry\\SDK\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "SDK for OpenTelemetry PHP.", + "keywords": [ + "Metrics", + "apm", + "logging", + "opentelemetry", + "otel", + "sdk", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2026-07-14T13:09:54+00:00" + }, + { + "name": "open-telemetry/sem-conv", + "version": "1.38.0", + "source": { + "type": "git", + "url": "https://github.com/opentelemetry-php/sem-conv.git", + "reference": "e613bc640a407def4991b8a936a9b27edd9a3240" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/opentelemetry-php/sem-conv/zipball/e613bc640a407def4991b8a936a9b27edd9a3240", + "reference": "e613bc640a407def4991b8a936a9b27edd9a3240", + "shasum": "" + }, + "require": { + "php": "^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "OpenTelemetry\\SemConv\\": "." + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "opentelemetry-php contributors", + "homepage": "https://github.com/open-telemetry/opentelemetry-php/graphs/contributors" + } + ], + "description": "Semantic conventions for OpenTelemetry PHP.", + "keywords": [ + "Metrics", + "apm", + "logging", + "opentelemetry", + "otel", + "semantic conventions", + "semconv", + "tracing" + ], + "support": { + "chat": "https://app.slack.com/client/T08PSQ7BQ/C01NFPCV44V", + "docs": "https://opentelemetry.io/docs/languages/php", + "issues": "https://github.com/open-telemetry/opentelemetry-php/issues", + "source": "https://github.com/open-telemetry/opentelemetry-php" + }, + "time": "2026-01-21T04:14:03+00:00" + }, + { + "name": "php-http/discovery", + "version": "1.20.0", + "source": { + "type": "git", + "url": "https://github.com/php-http/discovery.git", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-http/discovery/zipball/82fe4c73ef3363caed49ff8dd1539ba06044910d", + "reference": "82fe4c73ef3363caed49ff8dd1539ba06044910d", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.0|^2.0", + "php": "^7.1 || ^8.0" + }, + "conflict": { + "nyholm/psr7": "<1.0", + "zendframework/zend-diactoros": "*" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "*", + "psr/http-factory-implementation": "*", + "psr/http-message-implementation": "*" + }, + "require-dev": { + "composer/composer": "^1.0.2|^2.0", + "graham-campbell/phpspec-skip-example-extension": "^5.0", + "php-http/httplug": "^1.0 || ^2.0", + "php-http/message-factory": "^1.0", + "phpspec/phpspec": "^5.1 || ^6.1 || ^7.3", + "sebastian/comparator": "^3.0.5 || ^4.0.8", + "symfony/phpunit-bridge": "^6.4.4 || ^7.0.1" + }, + "type": "composer-plugin", + "extra": { + "class": "Http\\Discovery\\Composer\\Plugin", + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Http\\Discovery\\": "src/" + }, + "exclude-from-classmap": [ + "src/Composer/Plugin.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Márk Sági-Kazár", + "email": "mark.sagikazar@gmail.com" + } + ], + "description": "Finds and installs PSR-7, PSR-17, PSR-18 and HTTPlug implementations", + "homepage": "http://php-http.org", + "keywords": [ + "adapter", + "client", + "discovery", + "factory", + "http", + "message", + "psr17", + "psr7" + ], + "support": { + "issues": "https://github.com/php-http/discovery/issues", + "source": "https://github.com/php-http/discovery/tree/1.20.0" + }, + "time": "2024-10-02T11:20:13+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.2" + }, + "time": "2024-09-11T13:17:53+00:00" + }, + { + "name": "ramsey/collection", + "version": "2.1.1", + "source": { + "type": "git", + "url": "https://github.com/ramsey/collection.git", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/collection/zipball/344572933ad0181accbf4ba763e85a0306a8c5e2", + "reference": "344572933ad0181accbf4ba763e85a0306a8c5e2", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "captainhook/plugin-composer": "^5.3", + "ergebnis/composer-normalize": "^2.45", + "fakerphp/faker": "^1.24", + "hamcrest/hamcrest-php": "^2.0", + "jangregor/phpstan-prophecy": "^2.1", + "mockery/mockery": "^1.6", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.4", + "phpspec/prophecy-phpunit": "^2.3", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^10.5", + "ramsey/coding-standard": "^2.3", + "ramsey/conventional-commits": "^1.6", + "roave/security-advisories": "dev-latest" + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + }, + "ramsey/conventional-commits": { + "configFile": "conventional-commits.json" + } + }, + "autoload": { + "psr-4": { + "Ramsey\\Collection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ben Ramsey", + "email": "ben@benramsey.com", + "homepage": "https://benramsey.com" + } + ], + "description": "A PHP library for representing and manipulating collections.", + "keywords": [ + "array", + "collection", + "hash", + "map", + "queue", + "set" + ], + "support": { + "issues": "https://github.com/ramsey/collection/issues", + "source": "https://github.com/ramsey/collection/tree/2.1.1" + }, + "time": "2025-03-22T05:38:12+00:00" + }, + { + "name": "ramsey/uuid", + "version": "4.9.3", + "source": { + "type": "git", + "url": "https://github.com/ramsey/uuid.git", + "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ramsey/uuid/zipball/1df15849d00943a67d677dc9cfd80795f038c9f8", + "reference": "1df15849d00943a67d677dc9cfd80795f038c9f8", + "shasum": "" + }, + "require": { + "brick/math": ">=0.8.16 <=0.18", + "php": "^8.0", + "ramsey/collection": "^1.2 || ^2.0" + }, + "replace": { + "rhumsaa/uuid": "self.version" + }, + "require-dev": { + "captainhook/captainhook": "^5.25", + "captainhook/plugin-composer": "^5.3", + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "ergebnis/composer-normalize": "^2.47", + "mockery/mockery": "^1.6", + "paragonie/random-lib": "^2", + "php-mock/php-mock": "^2.6", + "php-mock/php-mock-mockery": "^1.5", + "php-parallel-lint/php-parallel-lint": "^1.4.0", + "phpbench/phpbench": "^1.2.14", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "^2.1", + "phpstan/phpstan-mockery": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpunit/phpunit": "^9.6", + "slevomat/coding-standard": "^8.18", + "squizlabs/php_codesniffer": "^3.13" + }, + "suggest": { + "ext-bcmath": "Enables faster math with arbitrary-precision integers using BCMath.", + "ext-gmp": "Enables faster math with arbitrary-precision integers using GMP.", + "ext-uuid": "Enables the use of PeclUuidTimeGenerator and PeclUuidRandomGenerator.", + "paragonie/random-lib": "Provides RandomLib for use with the RandomLibAdapter", + "ramsey/uuid-doctrine": "Allows the use of Ramsey\\Uuid\\Uuid as Doctrine field type." + }, + "type": "library", + "extra": { + "captainhook": { + "force-install": true + } + }, + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Ramsey\\Uuid\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A PHP library for generating and working with universally unique identifiers (UUIDs).", + "keywords": [ + "guid", + "identifier", + "uuid" + ], + "support": { + "issues": "https://github.com/ramsey/uuid/issues", + "source": "https://github.com/ramsey/uuid/tree/4.9.3" + }, + "time": "2026-06-18T03:57:49+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-05T06:23:12+00:00" + }, + { + "name": "symfony/http-client", + "version": "v7.4.15", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client.git", + "reference": "817bb83ef06717f67ab72a3f03e3b63fbe138de1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client/zipball/817bb83ef06717f67ab72a3f03e3b63fbe138de1", + "reference": "817bb83ef06717f67ab72a3f03e3b63fbe138de1", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/http-client-contracts": "~3.4.4|^3.5.2", + "symfony/polyfill-php83": "^1.29", + "symfony/service-contracts": "^2.5|^3" + }, + "conflict": { + "amphp/amp": "<2.5", + "amphp/socket": "<1.1", + "php-http/discovery": "<1.15", + "symfony/http-foundation": "<6.4" + }, + "provide": { + "php-http/async-client-implementation": "*", + "php-http/client-implementation": "*", + "psr/http-client-implementation": "1.0", + "symfony/http-client-implementation": "3.0" + }, + "require-dev": { + "amphp/http-client": "^4.2.1|^5.0", + "amphp/http-tunnel": "^1.0|^2.0", + "guzzlehttp/promises": "^1.4|^2.0", + "nyholm/psr7": "^1.0", + "php-http/httplug": "^1.0|^2.0", + "psr/http-client": "^1.0", + "symfony/amphp-http-client-meta": "^1.0|^2.0", + "symfony/cache": "^6.4|^7.0|^8.0", + "symfony/dependency-injection": "^6.4|^7.0|^8.0", + "symfony/http-kernel": "^6.4|^7.0|^8.0", + "symfony/messenger": "^6.4|^7.0|^8.0", + "symfony/process": "^6.4|^7.0|^8.0", + "symfony/rate-limiter": "^6.4|^7.0|^8.0", + "symfony/stopwatch": "^6.4|^7.0|^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Provides powerful methods to fetch HTTP resources synchronously or asynchronously", + "homepage": "https://symfony.com", + "keywords": [ + "http" + ], + "support": { + "source": "https://github.com/symfony/http-client/tree/v7.4.15" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-07-29T07:12:33+00:00" + }, + { + "name": "symfony/http-client-contracts", + "version": "v3.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/http-client-contracts.git", + "reference": "41fc42d276aeff21192465331ebbab7d83a743c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/41fc42d276aeff21192465331ebbab7d83a743c0", + "reference": "41fc42d276aeff21192465331ebbab7d83a743c0", "shasum": "" }, "require": { "php": ">=8.1" }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\HttpClient\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to HTTP clients", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v3.7.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-05T06:23:12+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.38.2", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "shasum": "" + }, + "require": { + "ext-iconv": "*", + "php": ">=7.2" + }, + "provide": { + "ext-mbstring": "*" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-27T06:59:30+00:00" + }, + { + "name": "symfony/polyfill-php82", + "version": "v1.38.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php82.git", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php82\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.2+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php82/tree/v1.38.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-05-26T12:45:58+00:00" + }, + { + "name": "symfony/polyfill-php83", + "version": "v1.41.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "5ea99087fb99c273a9b9236ed4c31e78b16103c6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/5ea99087fb99c273a9b9236ed4c31e78b16103c6", + "reference": "5ea99087fb99c273a9b9236ed4c31e78b16103c6", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.41.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-07-01T12:47:55+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v3.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/c0a284bab1ed8aa0417e3d69250ab437739563a0", + "reference": "c0a284bab1ed8aa0417e3d69250ab437739563a0", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" + }, + "conflict": { + "ext-psr": "<1.1|>=2" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + }, + "exclude-from-classmap": [ + "/Test/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.7.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-16T09:55:08+00:00" + }, + { + "name": "tbachert/spi", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/Nevay/spi.git", + "reference": "e7078767866d0a9e0f91d3f9d42a832df5e39002" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Nevay/spi/zipball/e7078767866d0a9e0f91d3f9d42a832df5e39002", + "reference": "e7078767866d0a9e0f91d3f9d42a832df5e39002", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^2.0", + "composer/semver": "^1.0 || ^2.0 || ^3.0", + "php": "^8.1" + }, + "require-dev": { + "composer/composer": "^2.0", + "infection/infection": "^0.27.9", + "phpunit/phpunit": "^10.5", + "psalm/phar": "^5.18" + }, + "type": "composer-plugin", + "extra": { + "class": "Nevay\\SPI\\Composer\\Plugin", + "branch-alias": { + "dev-main": "1.0.x-dev" + }, + "plugin-optional": true + }, + "autoload": { + "psr-4": { + "Nevay\\SPI\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "description": "Service provider loading facility", + "keywords": [ + "service provider" + ], + "support": { + "issues": "https://github.com/Nevay/spi/issues", + "source": "https://github.com/Nevay/spi/tree/v1.0.5" + }, + "time": "2025-06-29T15:42:06+00:00" + }, + { + "name": "utopia-php/client", + "version": "0.3.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/client.git", + "reference": "ee4c3429634f84c175e45f2a0c1836eaf78c2528" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/client/zipball/ee4c3429634f84c175e45f2a0c1836eaf78c2528", + "reference": "ee4c3429634f84c175e45f2a0c1836eaf78c2528", + "shasum": "" + }, + "require": { + "php": ">=8.5", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0", + "utopia-php/pools": "^2.0", + "utopia-php/psr7": "^0.2", + "utopia-php/span": "^1.1 || ^3.0 || ^4.0" + }, "require-dev": { - "laravel/pint": "^1.5.0", - "phpstan/phpstan": "^1.10", - "phpunit/phpunit": "^9.5", "swoole/ide-helper": "^6.0" }, + "suggest": { + "ext-curl": "Required to use the cURL HTTP client adapter.", + "ext-simplexml": "Required to decode XML responses with Response::xml().", + "ext-swoole": "Required to use the Swoole coroutine HTTP client adapter." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A lightweight PSR-18 HTTP client with cURL and Swoole coroutine backends", + "keywords": [ + "client", + "curl", + "http", + "php", + "psr-18", + "swoole", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/client/issues", + "source": "https://github.com/utopia-php/client/tree/0.3.0" + }, + "time": "2026-07-31T08:38:16+00:00" + }, + { + "name": "utopia-php/pools", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/pools.git", + "reference": "48905dac1b8f8050c2e07bdda32a018ca33982fc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/pools/zipball/48905dac1b8f8050c2e07bdda32a018ca33982fc", + "reference": "48905dac1b8f8050c2e07bdda32a018ca33982fc", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "utopia-php/telemetry": "^0.4" + }, + "require-dev": { + "swoole/ide-helper": "6.*" + }, + "suggest": { + "ext-mongodb": "Needed to support MongoDB database pools", + "ext-pdo": "Needed to support MariaDB, MySQL or SQLite database pools", + "ext-redis": "Needed to support Redis cache pools", + "ext-swoole": "Needed to support Swoole based pool adapter" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Pools\\": "src/Pools" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Team Appwrite", + "email": "team@appwrite.io" + } + ], + "description": "A simple library to manage connection pools", + "keywords": [ + "framework", + "php", + "pools", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/pools/issues", + "source": "https://github.com/utopia-php/pools/tree/2.0.1" + }, + "time": "2026-07-31T12:19:18+00:00" + }, + { + "name": "utopia-php/psr7", + "version": "0.2.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/psr7.git", + "reference": "115753c36194d53abe5587d383810724ac3a782d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/psr7/zipball/115753c36194d53abe5587d383810724ac3a782d", + "reference": "115753c36194d53abe5587d383810724ac3a782d", + "shasum": "" + }, + "require": { + "php": ">=8.4", + "psr/http-factory": "^1.0", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-simplexml": "Required to decode XML responses with Response::xml()." + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Psr7\\": "src/Psr7/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PSR-7 HTTP message implementations and PSR-17 factories for Utopia", + "keywords": [ + "http", + "php", + "psr-17", + "psr-7", + "utopia" + ], + "support": { + "issues": "https://github.com/utopia-php/psr7/issues", + "source": "https://github.com/utopia-php/psr7/tree/0.2.0" + }, + "time": "2026-07-06T12:40:23+00:00" + }, + { + "name": "utopia-php/span", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/span.git", + "reference": "7969d920044c1e106d9eede414e2d6e8df206ff5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/span/zipball/7969d920044c1e106d9eede414e2d6e8df206ff5", + "reference": "7969d920044c1e106d9eede414e2d6e8df206ff5", + "shasum": "" + }, + "require": { + "php": ">=8.3" + }, + "require-dev": { + "swoole/ide-helper": "^5.0" + }, + "suggest": { + "ext-swoole": "Required for coroutine-based storage" + }, + "type": "library", + "autoload": { + "psr-4": { + "Utopia\\Span\\": "src/Span/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Simple span tracing library for PHP with coroutine support", + "support": { + "issues": "https://github.com/utopia-php/span/issues", + "source": "https://github.com/utopia-php/span/tree/4.1.0" + }, + "time": "2026-07-24T08:46:29+00:00" + }, + { + "name": "utopia-php/telemetry", + "version": "0.4.5", + "source": { + "type": "git", + "url": "https://github.com/utopia-php/telemetry.git", + "reference": "139943bffcd4f6dd8fb9ed247f946a1d151b006a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/utopia-php/telemetry/zipball/139943bffcd4f6dd8fb9ed247f946a1d151b006a", + "reference": "139943bffcd4f6dd8fb9ed247f946a1d151b006a", + "shasum": "" + }, + "require": { + "ext-protobuf": "*", + "nyholm/psr7": "1.*", + "open-telemetry/exporter-otlp": "1.*", + "open-telemetry/sdk": "1.*", + "php": ">=8.0", + "symfony/http-client": "7.*" + }, + "require-dev": { + "swoole/ide-helper": "6.*" + }, + "suggest": { + "ext-sockets": "Required for the Swoole transport implementation", + "ext-swoole": "Required for the Swoole transport implementation" + }, "type": "library", "autoload": { "psr-4": { - "Utopia\\Fetch\\": "src/" + "Utopia\\Telemetry\\": "src/Telemetry" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "description": "A simple library that provides an interface for making HTTP Requests.", + "description": "A lite & fast telemetry library, with adapters for OpenTelemetry", + "keywords": [ + "framework", + "php", + "upf" + ], "support": { - "issues": "https://github.com/utopia-php/fetch/issues", - "source": "https://github.com/utopia-php/fetch/tree/1.1.2" + "issues": "https://github.com/utopia-php/telemetry/issues", + "source": "https://github.com/utopia-php/telemetry/tree/0.4.5" }, - "time": "2026-04-29T11:19:19+00:00" + "time": "2026-07-08T11:07:25+00:00" } ], "packages-dev": [ @@ -245,20 +2326,19 @@ }, { "name": "nikic/php-parser", - "version": "v5.7.0", + "version": "v5.8.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82" + "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/dca41cd15c2ac9d055ad70dbfd011130757d1f82", - "reference": "dca41cd15c2ac9d055ad70dbfd011130757d1f82", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f", + "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f", "shasum": "" }, "require": { - "ext-ctype": "*", "ext-json": "*", "ext-tokenizer": "*", "php": ">=7.4" @@ -297,9 +2377,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.7.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0" }, - "time": "2025-12-06T11:56:16+00:00" + "time": "2026-07-04T14:30:18+00:00" }, { "name": "phar-io/manifest", @@ -799,25 +2879,25 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.34", + "version": "9.6.35", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "b36f02317466907a230d3aa1d34467041271ef4a" + "reference": "0edba2f3a0c48df3553cb9b640810b30df60302b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b36f02317466907a230d3aa1d34467041271ef4a", - "reference": "b36f02317466907a230d3aa1d34467041271ef4a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0edba2f3a0c48df3553cb9b640810b30df60302b", + "reference": "0edba2f3a0c48df3553cb9b640810b30df60302b", "shasum": "" }, "require": { "doctrine/instantiator": "^1.5.0 || ^2", "ext-dom": "*", + "ext-filter": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", - "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.13.4", "phar-io/manifest": "^2.0.4", @@ -882,31 +2962,15 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.34" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.35" }, "funding": [ { - "url": "https://phpunit.de/sponsors.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - }, - { - "url": "https://liberapay.com/sebastianbergmann", - "type": "liberapay" - }, - { - "url": "https://thanks.dev/u/gh/sebastianbergmann", - "type": "thanks_dev" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", - "type": "tidelift" + "url": "https://phpunit.de/sponsoring.html", + "type": "other" } ], - "time": "2026-01-27T05:45:00+00:00" + "time": "2026-07-06T14:48:07+00:00" }, { "name": "sebastian/cli-parser", @@ -1978,7 +4042,7 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=8.1" + "php": ">=8.5" }, "platform-dev": {}, "plugin-api-version": "2.9.0" diff --git a/src/Pay/Adapter.php b/src/Pay/Adapter.php index 763fc9c..8912cdf 100644 --- a/src/Pay/Adapter.php +++ b/src/Pay/Adapter.php @@ -2,29 +2,8 @@ namespace Utopia\Pay; -use Utopia\Fetch\Client; -use Utopia\Fetch\Exception as FetchException; - abstract class Adapter { - protected const METHOD_GET = 'GET'; - - protected const METHOD_POST = 'POST'; - - protected const METHOD_PUT = 'PUT'; - - protected const METHOD_PATCH = 'PATCH'; - - protected const METHOD_DELETE = 'DELETE'; - - protected const METHOD_HEAD = 'HEAD'; - - protected const METHOD_OPTIONS = 'OPTIONS'; - - protected const METHOD_CONNECT = 'CONNECT'; - - protected const METHOD_TRACE = 'TRACE'; - /** * @var bool */ @@ -318,92 +297,4 @@ abstract public function getMandate(string $id): array; * @return array */ abstract public function listDisputes(?int $limit = null, ?string $paymentIntentId = null, ?string $chargeId = null, ?int $createdAfter = null): array; - - /** - * Call - * Make a request - * - * @param string $method - * @param string $url - * @param array $params - * @param array $headers - * @return array - */ - protected function call(string $method, string $url, array $params = [], array $headers = []): array - { - $query = match ($headers['content-type'] ?? null) { - 'application/json' => json_encode($params), - 'multipart/form-data' => $this->flatten($params), - default => \http_build_query($params), - }; - - $client = (new Client()) - ->setUserAgent(php_uname('s').'-'.php_uname('r').':php-'.phpversion()) - ->setAllowRedirects(true); - - foreach ($headers as $key => $value) { - $client->addHeader($key, $value); - } - - $response = null; - try { - $response = $client->fetch( - url: $url, - method: $method, - body: empty($query) ? null : $query, - query: [], - ); - } catch (FetchException $e) { - $this->handleError(0, $e->getMessage()); - } - - $responseHeaders = $response->getHeaders(); - $responseBody = $response->text(); - $responseType = $responseHeaders['content-type'] ?? ''; - $responseStatus = $response->getStatusCode(); - - if (str_contains($responseType, 'application/json')) { - $responseBody = json_decode($responseBody, true); - } - - if ($responseStatus >= 400) { - $this->handleError($responseStatus, $responseBody); - } - - return $responseBody; - } - - protected function handleError(int $code, mixed $response) - { - if (is_array($response)) { - /** @phpstan-ignore-next-line */ - throw new \Exception(json_encode($response), $code); - } - - throw new \Exception($response, $code); - } - - /** - * Flatten params array to PHP multiple format - * - * @param array $data - * @param string $prefix - * @return array - */ - protected function flatten(array $data, $prefix = ''): array - { - $output = []; - - foreach ($data as $key => $value) { - $finalKey = $prefix ? "{$prefix}[{$key}]" : $key; - - if (is_array($value)) { - $output += $this->flatten($value, $finalKey); // @todo: handle name collision here if needed - } else { - $output[$finalKey] = $value; - } - } - - return $output; - } } diff --git a/src/Pay/Adapter/Stripe.php b/src/Pay/Adapter/Stripe.php index 72e8365..7cd5f1a 100644 --- a/src/Pay/Adapter/Stripe.php +++ b/src/Pay/Adapter/Stripe.php @@ -2,9 +2,17 @@ namespace Utopia\Pay\Adapter; +use Psr\Http\Client\ClientExceptionInterface; +use Psr\Http\Client\ClientInterface; +use Utopia\Client; +use Utopia\Client\Adapter\Curl\Client as Curl; use Utopia\Pay\Adapter; use Utopia\Pay\Address; use Utopia\Pay\Exception; +use Utopia\Psr7\ContentType; +use Utopia\Psr7\Header; +use Utopia\Psr7\Method; +use Utopia\Psr7\Request\Factory as RequestFactory; class Stripe extends Adapter { @@ -12,10 +20,27 @@ class Stripe extends Adapter private string $secretKey; - public function __construct(string $secretKey, string $currency = 'USD') + private readonly ClientInterface $client; + + private readonly RequestFactory $requests; + + /** + * The default client keeps one cURL handle for the lifetime of the adapter + * and reuses its connection across calls. Pass your own to control the + * transport — a pool, a retry decorator, timeouts, a test double. + */ + public function __construct(string $secretKey, string $currency = 'USD', ?ClientInterface $client = null) { $this->secretKey = $secretKey; $this->currency = $currency; + + $this->client = $client ?? new Client(new Curl) + ->withConnectionReuse() + ->withHeaders([ + Header::USER_AGENT => php_uname('s').'-'.php_uname('r').':php-'.phpversion(), + ]); + + $this->requests = new RequestFactory; } /** @@ -42,7 +67,7 @@ public function purchase(int $amount, string $customerId, ?string $paymentMethod ]; $requestBody = array_merge($requestBody, $additionalParams); - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -65,7 +90,7 @@ public function authorize(int $amount, string $customerId, ?string $paymentMetho ]; $requestBody = array_merge($requestBody, $additionalParams); - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -83,7 +108,7 @@ public function capture(string $paymentId, ?int $amount = null, array $additiona } $requestBody = array_merge($requestBody, $additionalParams); - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -94,7 +119,7 @@ public function capture(string $paymentId, ?int $amount = null, array $additiona public function cancelAuthorization(string $paymentId, array $additionalParams = []): array { $path = '/payment_intents/'.$paymentId.'/cancel'; - $result = $this->execute(self::METHOD_POST, $path, $additionalParams); + $result = $this->execute(Method::POST, $path, $additionalParams); return $result; } @@ -118,7 +143,7 @@ public function retryPurchase(string $paymentId, ?string $paymentMethodId = null } $requestBody = array_merge($requestBody, $additionalParams); - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -138,7 +163,7 @@ public function refund(string $paymentId, ?int $amount = null, ?string $reason = $requestBody['reason'] = $reason; } - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } /** @@ -151,7 +176,7 @@ public function getPayment(string $paymentId): array { $path = '/payment_intents/'.$paymentId; - return $this->execute(self::METHOD_GET, $path); + return $this->execute(Method::GET, $path); } /** @@ -181,7 +206,7 @@ public function updatePayment(string $paymentId, ?string $paymentMethodId = null $requestBody = array_merge($requestBody, $additionalParams); - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } /** @@ -197,13 +222,13 @@ public function createPaymentMethod(string $customerId, string $type, array $pay ]; // Create payment method - $paymentMethod = $this->execute(self::METHOD_POST, $path, $requestBody); + $paymentMethod = $this->execute(Method::POST, $path, $requestBody); $paymentMethodId = $paymentMethod['id']; // attach payment method to the customer $path .= '/'.$paymentMethodId.'/attach'; - return $this->execute(self::METHOD_POST, $path, ['customer' => $customerId]); + return $this->execute(Method::POST, $path, ['customer' => $customerId]); } /** @@ -213,7 +238,7 @@ public function listPaymentMethods(string $customerId): array { $path = '/customers/'.$customerId.'/payment_methods'; - return $this->execute(self::METHOD_GET, $path); + return $this->execute(Method::GET, $path); } /** @@ -223,7 +248,7 @@ public function getPaymentMethod(string $customerId, string $paymentMethodId): a { $path = '/customers/'.$customerId.'/payment_methods/'.$paymentMethodId; - return $this->execute(self::METHOD_GET, $path); + return $this->execute(Method::GET, $path); } /** @@ -254,7 +279,7 @@ public function updatePaymentMethodBillingDetails(string $paymentMethodId, ?stri $requestBody['billing_details']['address'] = $address; } - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } public function updatePaymentMethod(string $paymentMethodId, string $type, array $details): array @@ -265,7 +290,7 @@ public function updatePaymentMethod(string $paymentMethodId, string $type, array $type => $details, ]; - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } /** @@ -274,7 +299,7 @@ public function updatePaymentMethod(string $paymentMethodId, string $type, array public function deletePaymentMethod(string $paymentMethodId): bool { $path = '/payment_methods/'.$paymentMethodId.'/detach'; - $this->execute(self::METHOD_POST, $path); + $this->execute(Method::POST, $path); return true; } @@ -298,7 +323,7 @@ public function createCustomer(string $name, string $email, array $address = [], if (! empty($address)) { $requestBody['address'] = $address; } - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -308,7 +333,7 @@ public function createCustomer(string $name, string $email, array $address = [], */ public function listCustomers(): array { - return $this->execute(self::METHOD_GET, '/customers'); + return $this->execute(Method::GET, '/customers'); } /** @@ -317,7 +342,7 @@ public function listCustomers(): array public function getCustomer(string $customerId): array { $path = '/customers/'.$customerId; - $result = $this->execute(self::METHOD_GET, $path); + $result = $this->execute(Method::GET, $path); return $result; } @@ -339,7 +364,7 @@ public function updateCustomer(string $customerId, string $name, string $email, $requestBody['address'] = $address->asArray(); } - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } /** @@ -348,7 +373,7 @@ public function updateCustomer(string $customerId, string $name, string $email, public function deleteCustomer(string $customerId): bool { $path = '/customers/'.$customerId; - $result = $this->execute(self::METHOD_DELETE, $path); + $result = $this->execute(Method::DELETE, $path); return $result['deleted'] ?? false; } @@ -377,7 +402,7 @@ public function createFuturePayment(string $customerId, ?string $paymentMethod = $requestBody['payment_method_options'] = $paymentMethodOptions; } - $result = $this->execute(self::METHOD_POST, $path, $requestBody); + $result = $this->execute(Method::POST, $path, $requestBody); return $result; } @@ -386,7 +411,7 @@ public function getFuturePayment(string $id): array { $path = '/setup_intents/'.$id; - return $this->execute(self::METHOD_GET, $path); + return $this->execute(Method::GET, $path); } public function listFuturePayments(?string $customerId = null, ?string $pyamentMethodId = null): array @@ -400,7 +425,7 @@ public function listFuturePayments(?string $customerId = null, ?string $pyamentM if ($pyamentMethodId != null) { $requestBody['payment_method'] = $pyamentMethodId; } - $result = $this->execute(self::METHOD_GET, $path, $requestBody); + $result = $this->execute(Method::GET, $path, $requestBody); return $result['data']; } @@ -422,7 +447,7 @@ public function updateFuturePayment(string $id, ?string $customerId = null, ?str $requestBody['payment_method_options'] = $paymentMethodOptions; } - return $this->execute(self::METHOD_POST, $path, $requestBody); + return $this->execute(Method::POST, $path, $requestBody); } /** @@ -435,7 +460,7 @@ public function getMandate(string $id): array { $path = '/mandates/'.$id; - return $this->execute(self::METHOD_GET, $path); + return $this->execute(Method::GET, $path); } /** @@ -468,7 +493,7 @@ public function listDisputes(?int $limit = null, ?string $paymentIntentId = null ]; } - $result = $this->execute(self::METHOD_GET, $path, $requestBody); + $result = $this->execute(Method::GET, $path, $requestBody); return $result['data']; } @@ -476,6 +501,9 @@ public function listDisputes(?int $limit = null, ?string $paymentIntentId = null /** * Execute * + * Stripe reads GET filters from the query string and every other body as + * form-urlencoded, with nested params in PHP's bracket notation. + * * @param string $method * @param string $path * @param array $requestBody @@ -484,14 +512,37 @@ public function listDisputes(?int $limit = null, ?string $paymentIntentId = null */ private function execute(string $method, string $path, array $requestBody = [], array $headers = []): array { - $defaultHeaders = ['Authorization' => 'Bearer '.$this->secretKey]; + $url = $this->baseUrl.$path; + + $request = $method === Method::GET + ? $this->requests->query($method, $url, $requestBody) + : $this->requests->form($method, $url, $requestBody); + + $request = $request->withHeader(Header::AUTHORIZATION, 'Bearer '.$this->secretKey); + + foreach ($headers as $key => $value) { + $request = $request->withHeader($key, $value); + } + + try { + $response = $this->client->sendRequest($request); + } catch (ClientExceptionInterface $e) { + $this->handleError(0, $e->getMessage()); + + throw $e; + } + + $body = (string) $response->getBody(); + + if (str_contains($response->getHeaderLine(Header::CONTENT_TYPE), ContentType::JSON)) { + $body = json_decode($body, true); + } - if ($method !== self::METHOD_GET) { - $defaultHeaders['content-type'] = 'application/x-www-form-urlencoded'; + if ($response->getStatusCode() >= 400) { + $this->handleError($response->getStatusCode(), $body); } - $headers = array_merge($defaultHeaders, $headers); - return $this->call($method, $this->baseUrl.$path, $requestBody, $headers); + return $body; } protected function handleError(int $code, mixed $response)