OptionalcompleteRequired when the adapter reports requiresServerCompletion.
Failure paths — each must reject with PayFanoutError, raw PSP error preserved.
OptionalidempotencyIdempotency-replay: same key twice -> same result, exactly one side effect.
OptionalmoneyMoney-path fixtures against the adapter's fake backend. REQUIRED —
refunds, capture, and cancel are where broken adapters cost real money,
so they are proven at the contract level, not left to per-adapter
discipline: completedPayment whenever supportsRefunds,
authorizedPayment whenever supportsManualCapture, cancelablePayment
always (every PSP has a pre-completion state).
Optionalexpectations?: { idRoundTrip?: boolean; metadataEcho?: boolean }Honesty flags for documented PSP limitations (default true): set idRoundTrip false when the PSP has no field to carry the host id, metadataEcho false when metadata cannot be read back on retrieve.
An authorized, NOT yet captured payment of input.amount (manual capture PSPs).
A payment in a cancelable (pre-completion / pre-capture) state.
Creates a COMPLETED payment (money moved) of input.amount, carrying
the host input.id and input.metadata; resolves its pspPaymentId.
OptionalonboardingThe adapter's exported onboarding descriptor. When provided, the suite asserts it is well-formed and consistent with the adapter (pspName match, credential fields, webhook events, CSP hosts) via validateOnboardingDescriptor.
OptionalvaultRequired when the adapter reports supportsSavedPaymentMethods: drives the vault round-trip (create customer -> save -> list -> charge twice -> delete).
Fresh single-use clientToken for savePaymentMethod (tokenize-first PSPs).
Confirm-on-client PSPs (no savePaymentMethod method): given a customer id, produce a stored token by whatever save-during-checkout simulation the fake supports.
OptionalexpectedAmount?: numberAsserted against the parsed event's normalized amount, when the payload carries one.
OptionalunknownEvent?: { headers: Record<string, string>; rawBody: string }A correctly SIGNED delivery of an event type the adapter does not recognize.
Exact raw body bytes as the PSP would send them, signature-matching validHeaders.
Fresh, valid input for a 2-decimal-currency session (e.g. USD/EUR).
OptionalthreeProves three-decimal handling (e.g. BHD). Strongly recommended.
OptionalzeroProves zero-decimal handling (e.g. JPY). Strongly recommended.
The contract every ServerPaymentAdapter — present or future — must pass. This is what makes "extensible" verifiable rather than aspirational: a new PSP ships by writing an adapter package that passes this suite, with zero changes to core or to consuming applications.