Added
PaymentStatusReasonvalue object (code,message);Payment::$statusReasonis now?PaymentStatusReasoninstead of an untypedstdClass.->code/->messagereads andjson_encode()keep working; updateinstanceof stdClasschecks, any mutation (the object is readonly), and array-only consumers by callingtoArray().PaymentMethodcasesBillink,Bizum,Mobilepay,Vipps, andVoucher. Existing cases are unchanged; the enum documents known SDK vocabulary, not an allow-list.CapabilityStatus::UnrequestedandCapability::isUnrequested().Balance::$pendingAmount(?Money), the amount field the Balance API returns.ResourceHydratableRequest::hydrateInto()and::wrapInto(). Both carry@phpstan-self-outand@psalm-this-outannotations that PHPStan honors sosend()infers the re-targeted class or wrapper.setHydratableResource()is unchanged but cannot narrow the type.
Changed
PaymentMethodStatusandTerminalPairingCodeStatusare string-backed enums. TheirSCREAMING_SNAKEconstants are gone, the same migration the other value sets took in beta.1.PaymentMethodStatus::NOT_REQUESTEDhas no case:Method::$statusisnullfor a method that was never requested.TerminalPairingCode::$statusis typedTerminalPairingCodeStatus|string.Method::$statusno longer has anulldefault. The API marks the field required (nullable), so an omitted field now stays uninitialized instead of reading as "not requested"; an explicitnullstill means the method was never requested.
Fixed
- Nullable enum unions now hydrate to enum cases.
Enum|string|nullproperties resolved asmixedand kept the raw API string. Affected:Payment::$method,Payment::$sequenceType,Refund::$status,Mandate::$status,Settlement::$status,Profile::$status,CurrentProfile::$status,Invoice::$status,Subscription::$status, and, after its enum migration,Method::$status. Code written against beta.2 that compares these to raw strings must compare with the case or->value, or useUtility::equals(), which accepts the case or raw value on either side.MandateCollection::whereStatus()accepts aMandateStatuscase or raw string. Unknown values still arrive as strings;nullis unchanged.Profile::$categoryCode(int|string|null) keeps the delivered scalar type. Organization::$address,$registrationNumber, and$vatNumberare nullable with anulldefault, matching the API contract. Beta.2 threwTypeErroronnullandErroron an omitted field.Organization::$localestays a required, non-nullstring.Capability::$statusReasonacceptsnull;Capability::$organizationIdis nullable with anulldefault because the field is not part of the Capability response.Balanceno longer fails on a conformant response:$incomingAmountand$outgoingAmount(both deprecated because they are not part of the Balance response),$transferFrequency, and$transferThresholdare nullable with anulldefault.- Fields the API contract marks nullable or optional no longer throw
TypeErroronnullorErrorwhen omitted:Terminal::$brand,$model,$serialNumber(?string);Terminal::$timezone,$locale(?string = null);Capture::$amount(?Money);PaymentLink::$profileId(?string);Webhook::$profileId(?string);Partner::$partnerType(?string);Partner::$partnerContractUpdateAvailable(?bool = null);BalanceTransaction::$deductions(?Money = null);BalanceTransaction::$mode(?string = null);Route::$releaseDate(?string = null);ConnectBalanceTransfer::$category(?string = null);SalesInvoice::$paymentTerm,$currency,$webhookUrl(?string = null); andSalesInvoice::$lines(?array = null). OtherSalesInvoicefields are unchanged pending further contract review. - UPGRADING.md no longer prints a Types class count and now documents enum reflection, rebuilding readonly value objects, uninitialized typed properties, wrapped-request inference, and caller-side
strict_typesbehavior.
For contributors
- A test asserts every file under
src/Types/is a backed enum except the query helpers andTypes\Method. - A PHPStan fixture under
tests/asserts the inferredsend()types on every analysis run.