Payment processing with Stripe, Square, and SumUp.

A provider-agnostic payment interface with adapters for all three providers. Handles checkout sessions, webhook verification, refunds, and idempotent payment processing.

Checkout uses one tax assessment for the full booking. Added VAT raises the total. Included VAT keeps the listed total. Booking fees stay outside VAT. Percentage deposits use the total with tax. Fixed deposits keep their stated amount. The unpaid assessment remains owed. Signed metadata retains the charged tax policy. Later settings changes do not change a checkout in progress. Old sessions without that field use No tax. Balance payments settle saved debt without another tax assessment. An attendee save applies current settings to the original price basis. It adds correction entries and a new assessment revision. It never charges or refunds money. Refunds reverse all physical events in the assessment chain.

Provider Interface

PaymentProvider defines the common contract:

  • Create single and multi-listing checkout sessions
  • Validate incoming webhooks using each provider's checks
  • Retrieve session details and process refunds

Classes

c
PaymentUserError

Error subclass for user-facing payment validation errors (e.g. invalid phone number). These propagate to the user through the guarded runners.

Functions

f
assembleCheckoutMetadata

Build a checkout's signed metadata the way the given provider needs it, with the caps read from the provider registry: build the logical shape within the per-value and entry caps, pack the small fields into one entry when the provider needs that to fit, and enforce the caps on the shape that reaches the wire. SumUp's caps are unbounded (its metadata is stored locally, never sent to the provider), which makes the enforcement a no-op for it.

f
buildItemsMetadata
No documentation available
f
buildMetadata

Build checkout session metadata from booking data (items already compact).

f
buildProviderLineItems

Render ticket and extra charges in the same order for every provider.

f
cachedClientFactory

Cache a provider API client keyed on its config. Reuses the cached client while the config is unchanged and recreates it when the config changes; returns null when the provider is unconfigured.

f
checkoutItem

Build a CheckoutItem for one listing — the one constructor every real-listing checkout line is built from. purchase carries the purchase context that decides the unit (a renewal prices the same tier by its months per unit); absent means an ordinary purchase. Package provenance is not a listing fact, so a member line spreads its packageGroupId over the result.

f
createdBookingEntries

The notification entries for the booking rows a create just wrote: one per real booking line, each paired with its listing. A quantity-0 ghost line books nothing, so it never notifies.

f
createWithClient

Create a withClient helper that runs an operation with a lazily-resolved client. Returns null if the client is not available or the operation fails.

f
enforceMetadataLimits

Only the fields that grow with what the buyer selected can realistically exceed the per-value limit. Form validation already holds every other field well below the smallest provider limit of 255.

f
extractSessionMetadata

Normalize validated session metadata into the canonical SessionMetadata shape.

f
getActivePaymentProvider
No documentation available
f
getPaymentProviderForExistingPayments

Resolve the provider for callbacks and completion of payments that already exist. New sales use getActivePaymentProvider.

f
hasRequiredSessionMetadata

Validate that every metadata value is text and required fields are present.

f
listingHasSpots

True when the listing still has spots for this quantity on this date (no date for a date-less listing, whose capacity is one running total).

f
loadPaymentProvider

Load one explicitly named provider implementation.

f
packMetadata

Collapse the packable small fields into one JSON b entry, dropping them from the top level. Falsy values are omitted (the "" = absent convention), so the b entry only appears when at least one packed field is actually present.

f
parseWebhookPayload

The one door every webhook body comes through. A body that is not JSON is refused the same way for every provider. What the body then means differs — a signed provider posts the event itself, SumUp posts two fields we build one from — so each provider passes its own reading, run outside the catch so a bug in it never reads as bad JSON. A reading that answers nothing means the body is JSON this provider cannot read, which earns the same refusal.

f
processBooking

Process a single-listing booking.

f
singleListingAnswerIds

Convert single-listing answerIds to the per-listing format used in metadata

f
toBookingItems

Convert registration line items to compact, edge-tagged booking items (v2). Each package member line carries ITS OWN package edge (k:"p", r=its group id) so the webhook can revalidate each line's nodeKey — an order can book several packages, so the edge is per line, never order-wide; folded children (in allocations) and standalone lines stay untagged. See signed-metadata.ts.

f
toCanonicalIso

Normalise a provider timestamp to the ledger's canonical ISO 8601 form (YYYY-MM-DDTHH:mm:ss.sssZ), or undefined when it's absent or unparseable.

f
toModifierRefs

Compact the resolved modifier specs to id/quantity references for metadata.

f
withCheckoutError

Wrap a checkout operation, converting PaymentUserError to { error } and letting unexpected failures propagate. Used by both provider adapters.

Interfaces

Type Aliases

T
BookingResult

Booking result — callers map this to their response format

T
CheckoutIntent

Registration intent for checkout (one or more listings)

T
CheckoutItem

Single item within a checkout — one bookable PATH. A listing booked through two overlapping packages (or a package plus its own standalone row) in one order is one item per path, each with its own quantity and price.

T
CheckoutSessionResult

Result of creating a checkout session: success carries the session id and checkout URL, a user-facing error carries error, and null means the provider is not configured. Unexpected failures throw.

T
ClientRunner

Run an operation with the lazily-resolved client. Returns null when the client is unconfigured or the operation fails (unless the error should propagate). The named type keeps the contract visible to callers of the widely-used provider runners so a signature drift fails at the definition instead of leaking to callers.

T
CredentialCheck

Shared shape for a provider credential check in connection-test results.

T
ExistingPaymentProvider

Provider implementation for work on an existing payment.

T
ModifierSpec

A modifier resolved for a specific checkout — the input the pricing pipeline applies. Eligibility (scope, stock, codes) is decided upstream; by the time a spec reaches pricing it is known to apply. value is the signed calc value (see modifierDelta); listingIds scopes which items it is charged on (null = the whole order); quantity is how many the buyer took (1 for an automatic or code modifier, more for an opt-in add-on).

T
PaymentProviderType

Supported payment provider identifiers

T
PaymentStatus

Valid payment status value

T
RetrieveSessionResult

Everything retrieving a checkout session by id can come back as.

T
SessionMetadata

Validated logical metadata. Missing wire values are represented by ""; provider-specific packing is removed at extraction.

T
SetupWebhookEndpoint

Set up a webhook endpoint for a provider. Some providers (e.g. Stripe) support programmatic creation; recreating any existing endpoint returns a fresh signing secret. Shared by the provider interface and each provider's own implementation so the signature can't drift.

T
T
WebhookEvent

Provider-agnostic webhook event

T
WebhookSessionResult

Everything resolving a webhook's session can come back as: the session; "skip" to acknowledge without processing; "retry" to answer with the fixed retryable refusal; a rejection carrying a paid charge the boundary could not read; or null for an event that is provably not ours.

T
WebhookSetupResult

Result of webhook endpoint setup

T
WebhookVerifyResult

Result of webhook signature verification

Variables

v
paymentsApi

Stubbable API for internal calls (testable via spyOn, like stripeApi/squareApi)

v
PaymentStatusSchema

Schema for valid payment status values. "failed" is a terminal non-payment (declined or expired checkout) — distinct from "unpaid", which may still complete.