Per-operation callback URL on authorize/capture/refund/cancel; extra request headers; Link::$autoCapture - #26
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## 1.x #26 +/- ##
=========================================
Coverage 99.13% 99.14%
- Complexity 222 226 +4
=========================================
Files 27 27
Lines 576 582 +6
=========================================
+ Hits 571 577 +6
Misses 5 5 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
| string $action, | ||
| Payload|array $request, | ||
| ?bool $synchronized, | ||
| array $headers, |
There was a problem hiding this comment.
Why not just add $headers to postOperation?
There was a problem hiding this comment.
Done — postOperation() now takes array $headers = [] directly and postOperationWithHeaders() is gone (PaymentsEndpoint builds the header via a tiny private callbackUrlHeader()). The split only existed to keep the BC check green; with the red-once decision below there was no reason for it.
| @@ -0,0 +1,19 @@ | |||
| <?xml version="1.0" encoding="UTF-8" ?> | |||
There was a problem hiding this comment.
Remove this file again. Just allow this PR to be red this one time
There was a problem hiding this comment.
Removed (and the interface docblock no longer references it). The BC check will report the six optional-parameter additions (ClientInterface::get/post/put/patch/delete, ResourceEndpoint::postOperation) as breaks on this PR — accepted as red this once, per your call.
…request headers; Link::$autoCapture Quickpay POSTs the callback of an API-issued operation to the ACCOUNT-WIDE callback URL (empty by default), not to the payment link's callback_url — so integrations that only set the link's URL never hear about their captures, refunds and cancels. The swagger lists a QuickPay-Callback-Url request header on authorize/capture/refund/cancel (and renew/session/fraud-report) that routes that one operation's callback; verified live in #22. - PaymentsEndpoint::authorize()/capture()/refund()/cancel() take ?string $callbackUrl (after $synchronized); ResourceEndpoint::postOperation() turns it into the header. Client::CALLBACK_URL_HEADER names it. - ClientInterface/Client: get()/post()/put()/patch()/delete() accept an optional array<string,string> $headers (the SDK's own headers always win), so unmodeled operations can send it too. - Link::$autoCapture (?bool) and $autoCaptureAt (?string) typed. - README: "where does the callback for a capture/refund/cancel go"; callback best practices note. examples/e2e/operate.php passes the listener's /callback when QUICKPAY_CALLBACK_BASE (or --callback-base=) is set. Closes #22.
…ce header params The Roave check flagged the optional parameters added to ClientInterface's helpers and to the overridable ResourceEndpoint::postOperation(): - postOperation() keeps its signature and delegates to a new protected postOperationWithHeaders(); PaymentsEndpoint uses the latter (empty header values are skipped, so callers can pass the callback url unconditionally). - The ClientInterface additions stay: Client is its only implementation and consumers type-hint/mock it rather than implement it (now documented on the interface). .roave-backward-compatibility-check.xml baselines exactly those five parameter additions with the reasoning inline; export-ignored.
Keeps postOperation() on the hot path (and covered); the with-headers variant is only used when there is a header to send.
Per review: no separate postOperationWithHeaders() — postOperation() gains an optional array $headers. And no .roave-backward-compatibility-check.xml: the optional-parameter additions on ClientInterface / postOperation() are accepted as a one-time red BC check for this PR (they only affect implementors of the mock-only interface / subclassers of the internal base).
c071e81 to
2881758
Compare
Closes #22.
Why
Quickpay POSTs the callback of an API-issued operation to the account-wide callback URL (manager → Settings → Integration) — empty by default — not to the
callback_urlset on the payment link. So an integration that only ever set the link's URL never hears about its captures, refunds and cancels. The swagger lists aQuickPay-Callback-Urlrequest header onauthorize,capture,refund,cancel(andrenew/session/fraud-report) that routes that one operation's callback; #22 verified it live.What
PaymentsEndpoint::authorize()/capture()/refund()/cancel()take?string $callbackUrl = null(after$synchronized, so named args readcapture($id, $req, callbackUrl: $url)).Client::CALLBACK_URL_HEADERnames the header.ResourceEndpoint::postOperationWithHeaders()(new, protected) does the sending;postOperation()keeps its signature and delegates — so no change for the overridable method.get($uri, $query, $headers),post/put/patch($uri, $body, $headers),delete($uri, $headers)— so unmodeled operations (renew, …) can send it too. The SDK's own headers (Authorization,Accept-Version,Accept,User-Agent) always win.Link::$autoCapture(?bool) and$autoCaptureAt(?string) typed (swaggerPaymentLink: boolean / ISO-8601 string; kept as string to be safe with the strict mapper).examples/e2e/operate.phpnow passes the listener's/callbackas the per-operation URL whenQUICKPAY_CALLBACK_BASE(or--callback-base=) is set — which is what makes its "watch each callback land" claim actually true.BC — please look at this one
The new Roave check flagged the optional
$headersparameter on the fiveClientInterfacemethods (an implementor with the old signature would fatal). Rather than contort the plumbing, I kept the interface change and added.roave-backward-compatibility-check.xmlbaselining exactly those five lines, with the reasoning inline:Clientis the interface's only implementation, consumers type-hint/mock it and are not expected to implement it — now stated in the interface docblock ("may gain optional parameters in minor releases"). Nothing downstream implements it (checked payum-quickpay). If you'd rather keep the interface frozen, the alternative is a Client-only method +instanceofin the endpoints, which I think is worse — but it's your call, and this commit is separate (1f831e9).Tests: header sent on each of the four operations (data provider), absent by default, combined with
?synchronized, on all five low-level helpers, SDK headers winning,Linkfields present/absent.