From 8dc36c7354bc7bf553520e8f4ccc04da9eac3981 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Joachim=20L=C3=B8vgaard?= Date: Mon, 17 Aug 2026 14:47:07 +0200 Subject: [PATCH] Prepare the 1.2.0 changelog Move the #26 / #27 entries out of 1.1.0 into a 1.2.0 section (Added / Changed / BC notes) and add the compare links. 1.1.0 stays the DX-review release (tagged before #27/#26 landed); 1.2.0 is the two payum-quickpay follow-ups. --- CHANGELOG.md | 72 ++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 58 insertions(+), 14 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c9e0cdd..7612429 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,62 @@ narrative. ## [Unreleased] +## [1.2.0] — 2026-08-17 + +Two follow-ups from reviewing `setono/payum-quickpay` against 1.1 — Quickpay knowledge every +integration re-derives ([#22](https://github.com/Setono/quickpay-php-sdk/issues/22), +[#25](https://github.com/Setono/quickpay-php-sdk/issues/25)). Additive; see "BC notes". + +### Added + +- **Per-operation callback URL.** `authorize()` / `capture()` / `refund()` / `cancel()` take a + `callbackUrl` argument, sent as the `QuickPay-Callback-Url` header (`Client::CALLBACK_URL_HEADER`) + so Quickpay POSTs *that operation's* callback there — by default API-issued operations notify only + the account-wide callback URL (empty by default), not the payment link's `callback_url`. The + low-level `get()` / `post()` / `put()` / `patch()` / `delete()` accept extra request headers, and + `ResourceEndpoint::postOperation()` takes `$headers` + ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26)). +- `Link::$autoCapture` (`?bool`) and `Link::$autoCaptureAt` (`?string`) + ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26)). +- Outcome predicates on `Operation`: `hasOutcome()` (no longer pending) and `isDeclined()` + (completed without being approved — a *synchronized* decline is a `2xx` with the decline on the + operation) ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- Status views on `Payment`: `latestOperationOfType()`, `latestApprovedOperation()`, + `hasApprovedOperation(?type)`; `hasPendingOperation()` takes an optional type. "Latest" is always + the highest operation id ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- `CreatePaymentRequest::ORDER_ID_PATTERN` / `assertValidOrderId()`, and + `CreateLinkRequest::$paymentMethods` accepts a list (`['creditcard', '!amex']`) and joins it the + way Quickpay expects ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- `Setono\Quickpay\Exception\InvalidArgumentException` — an SPL `\InvalidArgumentException` that + is also a `QuickpayException`, thrown for request values the API is known to reject + ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- README: where operation callbacks go; `state` reads `pending` during *any* asynchronous operation + (with the pre-operation `balance`); Quickpay does not retry a declined operation; synchronized + declines are `2xx`; the `orderId` rule; the new helpers with a decline-check snippet + ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26), [#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). + +### Changed + +- `CreatePaymentRequest` now validates `orderId` **at construction** — 4–20 characters of letters, + digits, space, `.`, `_`, `-`, verified against the live API, which rejects everything else under a + misleading "must have length between 4 and 20" message — and throws + `Setono\Quickpay\Exception\InvalidArgumentException` before any request is made. Code that relied + on the API's `ValidationException` for a bad `order_id` now fails earlier, with a message naming the + actual rule ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- `CollectionRequestOptions` throws `Setono\Quickpay\Exception\InvalidArgumentException` (a subclass + of the SPL exception it threw before) ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). +- `examples/e2e/operate.php` passes the listener's `/callback` as the per-operation callback URL + when `QUICKPAY_CALLBACK_BASE` is set ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26)). + +### BC notes + +- `ClientInterface::get()/post()/put()/patch()/delete()` and the protected + `ResourceEndpoint::postOperation()` gained an optional `$headers` parameter — a change only for + code that *implements* the interface (a mock-only interface; `Client` is its sole implementation) + or *subclasses* the SDK's endpoint base (unsupported). Callers are unaffected. The Roave BC check + reported these and was knowingly accepted red for #26 + ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26)). + ## [1.1.0] — 2026-08-17 Developer-experience follow-ups from the v1.0.0 review ([#10](https://github.com/Setono/quickpay-php-sdk/issues/10)). @@ -37,19 +93,6 @@ All additive; see "BC notes" for the two things that could touch unusual code. - `Payment::variables()`, `Payment::$deadlineAt`, `Payment::$acquirer`; `CreatePaymentRequest::$shopsystem` (`Shopsystem` payload); the SDK version in the `User-Agent` (`Client::version()`) ([#19](https://github.com/Setono/quickpay-php-sdk/pull/19)). -- Per-operation callback URL: `authorize()`/`capture()`/`refund()`/`cancel()` take a `callbackUrl` - argument, sent as the `QuickPay-Callback-Url` header (`Client::CALLBACK_URL_HEADER`) so Quickpay - notifies that URL for the operation instead of the account-wide callback URL; the low-level - `get()`/`post()`/`put()`/`patch()`/`delete()` accept extra request headers; `Link::$autoCapture` / - `$autoCaptureAt` are typed ([#26](https://github.com/Setono/quickpay-php-sdk/pull/26), closes #22). -- Outcome predicates and status views: `Operation::hasOutcome()` / `isDeclined()`; - `Payment::latestOperationOfType()`, `latestApprovedOperation()`, `hasApprovedOperation(?type)`, - and `hasPendingOperation()` now takes an optional type ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27), closes #25). -- `CreatePaymentRequest` validates `orderId` at construction (`ORDER_ID_PATTERN`: 4–20 characters - of letters, digits, space, `.`, `_`, `-` — verified live) and throws the new - `Setono\Quickpay\Exception\InvalidArgumentException` (an SPL `InvalidArgumentException` that is - also a `QuickpayException`; `CollectionRequestOptions` now throws it too); - `CreateLinkRequest::$paymentMethods` accepts a list and joins it ([#27](https://github.com/Setono/quickpay-php-sdk/pull/27)). - README: table of contents, "Concepts", callback best practices, framework snippets, recipes, and sections on the escape hatch and error handling ([#12](https://github.com/Setono/quickpay-php-sdk/pull/12)–[#20](https://github.com/Setono/quickpay-php-sdk/pull/20)). @@ -160,7 +203,8 @@ First alpha: payments (create/get/list/update/authorize/capture/refund/cancel), link flow, signed callback verification, `/ping`, typed DTOs with a `$raw` fallback, a typed exception hierarchy under `QuickpayException`, and host pinning. -[Unreleased]: https://github.com/Setono/quickpay-php-sdk/compare/v1.1.0...1.x +[Unreleased]: https://github.com/Setono/quickpay-php-sdk/compare/v1.2.0...1.x +[1.2.0]: https://github.com/Setono/quickpay-php-sdk/compare/v1.1.0...v1.2.0 [1.1.0]: https://github.com/Setono/quickpay-php-sdk/compare/v1.0.0...v1.1.0 [1.0.0]: https://github.com/Setono/quickpay-php-sdk/compare/v1.0.0-beta.2...v1.0.0 [1.0.0-beta.2]: https://github.com/Setono/quickpay-php-sdk/compare/v1.0.0-beta.1...v1.0.0-beta.2