Skip to content

Support PHP 8 (installable on patched PHP 8.2.35+ releases) - #9

Closed
JulesNsenda wants to merge 3 commits into
PaystackHQ:masterfrom
JulesNsenda:feature/php8-support
Closed

JulesNsenda wants to merge 3 commits into
PaystackHQ:masterfrom
JulesNsenda:feature/php8-support

Conversation

@JulesNsenda

Copy link
Copy Markdown

Fixes #8

composer.json required "php": "^7.0", so this package couldn't be installed on any PHP release from the 21 Oct 2026 security update for critical remote code execution flaws (GHSA-w8hw-w9fx-j79w, GHSA-6wmf-4rv5-p3rp; php.net). The fixed releases are 8.2.35, 8.3.36, 8.4.27 and 8.5.12. PHP 7.x no longer gets security fixes.

Changes

Support PHP 8

  • "php": "^7.0" → "^7.2 || ^8.0". The floor moves to 7.2 because the explicit nullable type below and omnipay/tests ^4.1 need it. Composer keeps projects on 7.0/7.1 on the current release.
  • sendRequest(..., ?array $data = null): implicit nullable types are deprecated in PHP 8.4.
  • Response getters no longer raise PHP 8 "Undefined array key" warnings on error or partial payloads (?? null / !empty() / isset()). Return values are unchanged.
  • completePurchase() casts the reference before rawurlencode(), because passing null is deprecated in PHP 8.1.
  • omnipay/tests ~3.0 → ^4.1 (PHPUnit 8.5–11), setUp(): void, and a phpunit.xml.dist that PHPUnit 8–11 all accept.
  • Removed phpro/grumphp: 0.14 only installs with Composer 1, and current releases need PHP 8.2+.
  • config.allow-plugins: php-http/discovery disabled, because nothing here needs it.
  • New tests: completePurchase() success, declined, unknown reference, no reference and partial payload, plus failed purchase and failed refund. The previously empty failure mocks are filled in. 31 → 39 tests.
  • Fixed two pre-existing PSR-2 violations (missing final newline).

CI

  • Travis CI is replaced by GitHub Actions. The matrix runs PHP 7.2–8.5 with highest dependencies, plus lowest dependencies on 7.2 and 8.5.
  • On PHPUnit 10+ the tests run with --fail-on-deprecation --fail-on-warning --fail-on-notice. Without these flags PHPUnit only reports PHP deprecations, so CI wouldn't catch a regression like the 8.4 one fixed here.
  • Both actions are pinned to commit SHAs, the checkout uses persist-credentials: false, and the token is contents: read.
  • Removed Scrutinizer's external_code_coverage, because coverage came from Travis.

Docs: README requirement and CHANGELOG.

How it was verified

I tested this locally in Docker, using official php:*-cli images and Composer resolving for each exact version:

PHP Deps PHPUnit omnipay/common Result
7.2.34 highest 8.5.56 3.4.0 ✅ 39 tests, 3 skipped, phpcs clean
7.3.33 / 7.4.33 / 8.0.30 highest 9.6.38 3.4.0 / 3.4.0 / 3.5.1 ✅
8.1.33 highest 10.5.66 (strict) 3.5.1 ✅
8.2.35 / 8.3.36 / 8.4.27 / 8.5.12 highest 11.5.57 (strict) 3.5.1 ✅
7.2.34 lowest 8.5.52 3.0.3 ✅
8.5.12 lowest 8.5.52 3.1.0 ✅
  • Negative control: with the old array $data = null put back, PHP 8.4.27 + PHPUnit 11 exits 1 with the strict flags and 0 without them. So the strict CI flags do catch it.
  • Runtime check: on PHP 8.3.36, a fresh project ran composer require league/omnipay:^3 php-http/guzzle7-adapter paystackhq/omnipay-paystack from this branch. It then called purchase(), completePurchase() and refund() against the real api.paystack.co with a fake key. All three returned the right response classes with Paystack's Invalid key message, and the package raised no PHP warnings or deprecations (an error handler failed the run on any).

The three skipped tests (AuthorizeRequestTest, ResponseTest) were already marked "Must be revisited" and are unchanged apart from setUp(): void.

Related, not in this PR

CompletePurchaseResponse::isSuccessful() only checks data.status === 'success'. Callers who verify a payment should also compare data.amount and data.currency against the order. Otherwise a successful payment of a smaller amount, or a reused reference, could be accepted. This behaviour predates the PR and is worth tracking separately.

🤖 Generated with Claude Code

JulesNsenda and others added 3 commits October 26, 2026 09:54
composer.json only allowed PHP 7.x, so the package could not be
installed on any PHP release from the 21 Oct 2026 security update
(8.2.35, 8.3.36, 8.4.27, 8.5.12).

- Allow "^7.2 || ^8.0". The floor moves to 7.2 because the explicit
  nullable type and omnipay/tests ^4.1 need it; projects on 7.0/7.1
  stay on the previous release.
- Make sendRequest()'s $data explicitly nullable (implicit nullable
  types are deprecated in PHP 8.4).
- Guard response getters against missing keys so error and partial
  payloads don't raise "Undefined array key" warnings on PHP 8.
  Return values are unchanged.
- Cast the transaction reference before rawurlencode() (passing null
  is deprecated in PHP 8.1).
- omnipay/tests ~3.0 -> ^4.1 (PHPUnit 8.5-11), setUp(): void, and a
  phpunit.xml.dist those versions all accept.
- Drop phpro/grumphp: 0.14 only installs with Composer 1 and current
  releases need PHP 8.2+.
- Disallow the php-http/discovery Composer plugin; it isn't needed.
- Add tests for completePurchase() (success, declined, unknown
  reference, no reference, partial payload) and for failed purchase
  and refund responses, with the previously empty failure mocks filled.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Travis CI no longer runs for this repo. The new workflow tests PHP
7.2-8.5 with highest dependencies, plus lowest dependencies on 7.2 and
8.5. On PHPUnit 10+ it fails on PHP deprecations, warnings and
notices, which PHPUnit otherwise only reports. Actions are pinned to
commit SHAs, the checkout doesn't persist credentials, and the job
token is read-only.

Scrutinizer's external_code_coverage is removed: coverage was uploaded
from Travis, so inspections would wait for it and time out.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@JulesNsenda JulesNsenda closed this by deleting the head repository Oct 26, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Package can't be installed on any PHP release with the 21 Oct 2026 security fixes (composer.json requires php ^7.0)

2 participants