Skip to content

Adopt setono/quickpay-php-sdk and harden the gateway (2.x)#44

Open
loevgaard wants to merge 4 commits into
2.xfrom
feature/quickpay-php-sdk
Open

Adopt setono/quickpay-php-sdk and harden the gateway (2.x)#44
loevgaard wants to merge 4 commits into
2.xfrom
feature/quickpay-php-sdk

Conversation

@loevgaard

Copy link
Copy Markdown
Member

Summary

Replaces the library's hand-rolled QuickPay API client with the external
setono/quickpay-php-sdk package and makes the gateway
significantly more robust and better tested. Targets 2.x (breaking changes allowed).

What changed

SDK adoption

  • Api is now a final, immutable value object wrapping the SDK ClientInterface + gateway
    options. It does no HTTP itself — Basic auth, the Accept-Version: v10 header, status→exception
    mapping and (de)serialization all live in the SDK.
  • Deleted src/Model/* in favour of the SDK's readonly response DTOs and PaymentState /
    OperationType enums. The surviving state logic moved into a stateless Operations helper.
  • All actions rewritten to the SDK's typed endpoints/DTOs (create, createLink, capture,
    refund, cancel, getById).

Robustness

  • Callbacks are now HMAC-verified. NotifyAction validates the QuickPay-Checksum-Sha256 signature
    (timing-safe, via the SDK CallbackValidator) and rejects invalid/unsigned callbacks with a 400
    before acting — previously the callback was processed with no verification.
  • ConvertPaymentAction persists only scalars (quickpayPaymentId is the source of truth); it no
    longer serializes a hydrated payment object into the Payum details.
  • Gateway options cleaned up: dropped the unused merchant; only apikey + privatekey required; added
    synchronized and branding_id; agreement now maps to the link agreement_id; a prebuilt SDK
    client can be injected via quickpay.client.

Testing

  • Suite is now fully offline/deterministic on a PSR-18 Http\Mock\Client (was previously live HTTP /
    flaky). Tests assert both Payum marks and the exact requests sent (method, path, auth, version).
  • New OperationsTest, ConvertPaymentActionTest, ConfirmPaymentActionTest; try/catch-without-fail
    anti-patterns replaced with expectException; notify valid/invalid/missing-checksum coverage.
  • Infection wired in (minMsi 65 / minCoveredMsi 70, currently 76% MSI / 77% covered) with a
    dedicated CI job.

Docs

  • Rewrote the stale CLAUDE.md (mocked suite, SDK-based Api, 8.1–8.5 matrix), documented the
    PSR-18/17 requirement and options in the README, and added docs/UPGRADE-2.0.md.

Notes

  • The SDK is currently 1.0.0-alpha.1, pinned as ^1.0@alpha. A stable SDK tag should land before
    2.0.0 is released.
  • php-http/message-factory is kept because payum/core's gateway wiring still needs it at construction
    time; the dependency-analyser carve-out is documented in composer-dependency-analyser.php.

Verification

Locally green on PHP 8.1 (and lowest/highest resolutions): composer all (PHPStan level 8 + ECS +
PHPUnit 159 tests), composer normalize --dry-run, composer-dependency-analyser, composer infection.

Adopt the setono/quickpay-php-sdk package as the QuickPay API client and rebuild
the gateway around it (2.x):

- Api is now a final, immutable value object wrapping the SDK ClientInterface and
  the gateway options; it performs no HTTP itself (Basic auth, Accept-Version: v10,
  error mapping and (de)serialization all live in the SDK).
- Delete the custom src/Model/* DTOs in favour of the SDK response DTOs/enums; move
  the surviving state logic into the stateless Operations helper.
- Rewrite every action to the SDK's typed endpoints/DTOs. ConvertPaymentAction now
  persists only scalars (quickpayPaymentId is the source of truth), and NotifyAction
  verifies the QuickPay-Checksum-Sha256 HMAC (timing-safe) before acting, rejecting
  invalid/unsigned callbacks with a 400.
- Gateway options: drop the unused 'merchant'; require only apikey + privatekey; add
  'synchronized' and 'branding_id'; map 'agreement' to the link agreement id; allow
  injecting a prebuilt SDK client via 'quickpay.client'.
- Rebuild the test suite offline on a PSR-18 Http\Mock\Client with request-shape
  assertions; add OperationsTest, ConvertPaymentActionTest and ConfirmPaymentActionTest.
- Keep php-http/message-factory (payum/core gateway wiring needs it) and document the
  carve-out in composer-dependency-analyser.php.
Add minMsi 65 / minCoveredMsi 70 gates to infection.json.dist and a dedicated
mutation-tests CI job (PHP 8.3, highest, pcov) running composer infection.
Rewrite the stale CLAUDE.md sections (the suite is mocked, not live; Api is an SDK
wrapper; models replaced by SDK DTOs + Operations helper; PHP 8.1-8.5 matrix),
document the PSR-18/17 requirement and gateway options in the README, and add
docs/UPGRADE-2.0.md.
@codecov

codecov Bot commented Jun 30, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 97.12644% with 5 lines in your changes missing coverage. Please review.
✅ Project coverage is 97.15%. Comparing base (c425531) to head (255ca44).

Files with missing lines Patch % Lines
src/Action/NotifyAction.php 81.25% 3 Missing ⚠️
src/Action/AuthorizeAction.php 93.33% 1 Missing ⚠️
src/Operations.php 93.75% 1 Missing ⚠️
Additional details and impacted files
@@             Coverage Diff              @@
##                2.x      #44      +/-   ##
============================================
+ Coverage     89.50%   97.15%   +7.65%     
+ Complexity      122       89      -33     
============================================
  Files            16       12       -4     
  Lines           362      246     -116     
============================================
- Hits            324      239      -85     
+ Misses           38        7      -31     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Rename the \Setono\Payum\Quickpay namespace, the QuickpayGatewayFactory class
(and its file), the 'Quickpay' factory title, and all prose to match the SDK's
\Setono\Quickpay convention. The 'QuickPay-Checksum-Sha256' callback header is
left as-is — it is QuickPay's actual wire header name (held by the SDK's
CallbackValidator::CHECKSUM_HEADER). Also drop the now-obsolete rector.php
ReadOnlyPropertyRector skip that referenced the deleted dynamically-hydrated models.
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.

1 participant