Purchases whose provider customer was never attached to a Flo user were recorded without a client, hiding them from client views and leaving the Flo fee unresolved; they now adopt the owning gateway's client.
28 Aug 2026
Fix
Transactions
Billing
Reliability
When a provider webhook books a purchase for a customer that Flo has never linked to a user, the
transaction previously arrived without a client. Those rows were invisible in client-scoped
transaction lists and exports, and the Flo transaction fee could not be resolved for them — every
replay of the same webhook repeated the failure.
What changed
- The transaction ledger now books such purchases under the client that owns the gateway the
movement was signed by. A client supplied by the caller, or already present on the row, is never
overridden.
- Flo fee resolution reports a purchase with no client link as
missing_client_id (with the
gateway) instead of as missing billing terms, so the two conditions are distinguishable.
Developer notes
- Applies to every ledger path (Stripe and PayPal webhooks, API checkout, scheduler renewals).
- Rows recorded before this release keep their empty client until repaired; a repair runbook follows
separately.
- No schema change and no change to any SDK-facing contract.
Fixes a v1.7.27 regression in which client webhook deliveries stalled as pending, webhook event detail reads failed, and invoice synchronisation errored on canonical invoice lookups.
28 Aug 2026
Fix
Webhooks
Invoices
Reliability
Version 1.7.27 introduced canonical invoice and transaction resolution for financial records. A raw SQL
fragment in that change referenced the query alias in a form PostgreSQL could not resolve, which stopped
client webhook deliveries from progressing past pending, broke reading a single webhook event, and made
invoice synchronisation fail on canonical lookups. This release corrects the SQL.
What changed
- Client webhook fan-out again writes a delivery row for every configured endpoint and delivers them;
deliveries that were stuck in
pending are picked up by the outbox retry ladder without a manual replay.
GET /v1/webhooks/events/{id} and its admin mirror return the event again instead of a server error.
- Invoice synchronisation from provider webhooks, one-time invoice creation and renewal invoice lookups no
longer fail on the canonical invoice check.
Developer notes
- Raw SQL fragments that embed a TypeORM alias now quote each identifier segment explicitly via the shared
quoteTypeormAliasPath helper instead of relying on TypeORM's property-name rewrite, which does not
reach these fragments.
- No schema change and no change to any SDK-facing contract.
PayPal payment and vaulted setup intents now handle incompatible checkout destinations safely, reducing avoidable failures while preserving existing integrations.
28 Aug 2026
Fix
Checkout
PayPal
Reliability
PayPal payment and vaulted setup intents are now more resilient when a checkout session contains a successUrl or
cancelUrl that PayPal cannot accept. Flo substitutes its standard checkout destination only for the incompatible
value, while valid merchant destinations continue to be used.
What changed
- For direct PayPal payments and vaulted setup flows, relative, malformed, non-HTTP(S), or credential-bearing success
and cancellation destinations are replaced before the intent is created.
- Success and cancellation destinations are handled independently, so a valid merchant URL remains in place when only
the other value is incompatible.
Why it matters
- Existing checkout sessions with older relative or otherwise incompatible destinations are no longer rejected by
PayPal solely because of those URL formats.
- Merchants retain their custom approval destinations whenever those values are valid for PayPal.
Developer notes
- For custom PayPal approval destinations, continue supplying absolute HTTP(S) URLs without embedded credentials in
successUrl and cancelUrl.
- The request and response contract for
POST /v1/checkouts/sessions/:id/intents, including its existing generic 500
response for provider failures, is unchanged.
- No SDK update, payload migration, configuration change, or merchant action is required. This release contains no
breaking changes or removed public APIs.
PayPal subscription checkouts now retain one opening invoice, keeping payment records, merchant events, and later refunds aligned.
28 Aug 2026
Fix
PayPal
Billing
Subscriptions
Webhooks
PayPal subscription checkouts now retain the purchase and invoice created during checkout when PayPal confirms the
opening charge. Merchants see one opening payment and invoice across reporting, customer timelines, and webhook
delivery, including when confirmations are repeated or arrive concurrently.
What changed
- The opening PayPal charge remains associated with the original checkout purchase and invoice instead of producing a
second billing record, and it is not counted as a subscription renewal.
- Mixed checkouts keep the correct amounts assigned to the subscription and any one-time items, so later refunds,
reversals, and chargebacks remain associated with the affected purchases and opening invoice.
- Repeated or concurrent confirmations produce one complete set of the existing
invoice.created, invoice.paid, and
applicable item.purchased events. Opening charges do not emit subscription.renewed.
- When a confirmed historical duplicate is reconciled, reporting excludes the duplicate while previously issued
payment and invoice identifiers remain usable.
Why it matters
- Payment, invoice, timeline, and reporting views no longer overstate PayPal opening activity with duplicate records.
- Finance teams and webhook consumers can reconcile the opening charge and later financial adjustments against the
same checkout invoice.
Developer notes
- Public API routes, request and response schemas, SDK exports, webhook event names, and webhook payload schemas are
unchanged.
- No SDK update, payload migration, merchant configuration, or operational action is required. Webhook consumers
should continue to process events idempotently.
Authorized operators can now manage checkout links for one explicitly selected client without changing merchant-facing checkout APIs.
Authorized Flo operators can now create, list, retrieve, update, and deactivate checkout links on behalf of one
explicitly selected client. Existing merchant-managed checkout links and buyer-facing link resolution continue to work
without changes.
What changed
- The operator API now provides
GET, POST, PATCH, and DELETE routes under
/v1/admin/checkout-links, including single-link operations at /v1/admin/checkout-links/:uuid.
- Every operator request requires one valid
clientId, keeping reads and changes restricted to the selected client.
- List requests use the same pagination, filtering, searching, and sorting contract as
GET /v1/checkout-links.
- Read-only admin credentials can use the
GET routes, while write credentials can create, update, and deactivate
links. The legacy admin scope remains supported for all operations.
Why it matters
- Authorized operators can assist merchants with checkout-link management without switching client credentials.
- Explicit client selection prevents an operation from falling back to another client or returning an all-client list.
Developer notes
- Operator integrations must include exactly one
clientId query parameter on every admin checkout-link request.
- The admin routes are intentionally omitted from the generated OpenAPI specification.
- Existing
/v1/checkout-links management and resolve contracts are unchanged. No SDK update, payload migration,
merchant configuration, or operational action is required, and this release contains no breaking changes.
Customer timelines no longer show a trial ending after a Flo-managed subscription is already scheduled to cancel or pause.
Customer timelines now reflect the actual lifecycle of Flo-managed trials when a cancellation or pause is scheduled
near the trial boundary. Customers and support teams see the action that will take effect, without an additional trial-end
step that will not occur.
What changed
- The
subscription.trial_end future event is omitted when a scheduled cancellation or pause takes effect on or before
the trial boundary.
- The scheduled cancellation or pause remains visible in the timeline.
- When the cancellation or pause is scheduled after the trial boundary, the trial-end event remains visible before it.
Why it matters
- Customer journeys no longer suggest that a canceled or paused trial will continue through a separate trial-end step.
- Merchants and operators receive a clearer, chronologically accurate view of upcoming subscription activity.
Developer notes
- Timeline request and response schemas are unchanged. Integrations should continue to treat
futureEvents as the
current projected schedule rather than assuming that every trial includes a subscription.trial_end event.
- No SDK update, payload migration, merchant configuration, or operational action is required.
Merchants can now page, filter, search, and sort checkout links through a consistent API contract.
Checkout link management now supports bounded pagination and documented query controls, making large link catalogs
easier to browse and integrate with operational tooling.
What changed
GET /v1/checkout-links now returns { data, page, limit, pages, total } instead of a bare array.
- Results can be filtered, searched, and sorted using the query fields and operators published in the OpenAPI
specification. The existing default order remains newest first.
- Pagination is 1-based, with a default
limit of 20 and a maximum of 100.
- Unknown parameters, malformed values, unsupported operators, limits above
100, and non-empty relation values
now return 400 instead of being ignored.
Why it matters
- Merchants and operators can work with large checkout-link catalogs without requesting every link at once.
- API clients can use the returned totals and page counts to build predictable navigation, exports, and management
views.
Developer notes
- Breaking change: consumers of
GET /v1/checkout-links must read checkout-link records from the data field and
use page, limit, pages, and total for pagination. Integrations that relied on receiving every link in one
request must paginate through the result set.
- Review existing query parameters against the published OpenAPI contract before upgrading; unsupported or invalid
list queries now receive a
400 response.
- Other checkout-link endpoints and their request and response payloads are unchanged. No merchant configuration or
data migration is required.
Authorized operators can now manage a merchant's customer-facing branding while each action remains scoped to one explicitly selected client.
Authorized operators can now read, replace, or clear branding on behalf of one explicitly selected client. Existing
client-managed branding behavior remains unchanged.
What changed
- Operator-assisted branding management is restricted to one selected client for each action, with no implicit or
cross-client fallback.
- The same whole-replacement and idempotent clear behavior now applies whether branding is managed by the client or
by an authorized operator.
- The OpenAPI schemas for
GET /v1/branding and PUT /v1/branding now describe nested SDK button styles and custom
appearance rules more precisely.
Why it matters
- Operators can help merchants maintain consistent branding across SDK embeds, hosted checkout, branded emails, and
other white-label experiences without affecting another client's configuration.
- Developers generating clients or forms from the OpenAPI specification receive more accurate branding types.
Developer notes
- Existing branding payloads and client authentication continue to work without changes.
- No SDK update, payload migration, or merchant action is required. This release contains no breaking changes or
removed public APIs.
Hosted payment and card-setup forms now explain secure card storage and link buyers to the Card Storage Policy without interrupting their progress.
25 Aug 2026
Improvement
Checkout
Accessibility
Buyers entering a new card now see a consistent notice directly below the payment or card-setup button explaining that
their card is stored securely in a PCI DSS-compliant vault. The notice links to the Card Storage Policy so buyers can
learn more before submitting their details.
What changed
- Hosted payment and card-setup forms that collect a new card now display the card-storage disclosure automatically.
- The Card Storage Policy opens in a new tab, preserving the in-progress form and any details already entered.
- The notice adapts to the form theme and available screen width, and its link supports keyboard and screen-reader use.
- Saved-card and non-card payment flows are unchanged because they do not display the new-card form.
Why it matters
- Buyers receive clear, consistent information about card storage at the point where they enter their card details.
- Merchants receive one centrally maintained disclosure across hosted card flows without adding or synchronizing their
own copy.
Developer notes
- The hosted form supplies the notice automatically, and it cannot be hidden or replaced. Do not render a duplicate
card-storage notice around the form; review any custom copy already placed there.
- No public API, SDK, or configuration changes are required. There are no breaking changes, migrations, or other
operational actions for standard integrations.
Flopay's backend dependencies have been refreshed, including a security update for API documentation support, while preserving existing integration behavior.
24 Aug 2026
Security
Maintenance
Reliability
Existing integrations continue to work unchanged after this platform maintenance release. Backend dependencies and
development tooling have been refreshed without changing public product behavior.
What changed
- Updated runtime dependencies and development tooling to their targeted compatible versions.
- Addressed a reported dependency security advisory in the tooling that supports Flopay's API documentation.
- Public APIs, request and response payloads, checkout flows, SDK contracts, and webhook delivery remain unchanged.
Why it matters
- The refresh incorporates current upstream fixes while preserving compatibility for existing integrations.
Developer notes
- No SDK update, payload change, merchant configuration, migration, or operational action is required.
- This release contains no breaking changes or removed public APIs.