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.
Payment and webhook-event lists, exports, and batch resends can now use a linked subscription's successful rebill count.
24 Aug 2026
Feature
Payments
Webhooks
Subscriptions
API
Payment and webhook-delivery reporting can now organize records by the number of successful renewal charges recorded
for each linked subscription. Merchants and operators can isolate activity for subscriptions that have not yet renewed,
compare more established subscriptions, and target webhook redelivery without combining separate datasets.
What changed
GET /v1/payments, GET /v1/admin/payments, GET /v1/webhooks/events, and
GET /v1/admin/webhooks/events now accept numeric subscription.rebillCount filters, such as
subscription.rebillCount[gte]=2, using eq, gt, gte, lt, and lte operators.
- Payment and webhook-event results can be ordered with
sort[asc]=subscription.rebillCount or
sort[desc]=subscription.rebillCount. Records without a linked subscription are placed last, and equal rebill
counts retain stable pagination.
POST /v1/payments/exports, POST /v1/admin/payments/exports, POST /v1/webhooks/events/exports, and
POST /v1/admin/webhooks/events/exports support the same filters and sorting, and can include
subscription.rebillCount as an opt-in numeric field in CSV or JSON output.
POST /v1/webhooks/events/resend accepts the same rebill-count filters, allowing a batch resend to target webhook
events linked to subscriptions within a selected renewal range.
Why it matters
- Payment and webhook-delivery reports can segment activity by subscription maturity without matching records across
separate exports.
- Support and operations teams can focus webhook redelivery on a relevant subscription cohort while retaining the
existing client-scoped resend behavior.
Developer notes
- Add
relation=subscription only when the nested subscription data is needed in a list response. Filtering or sorting
by subscription.rebillCount does not expand the relation automatically.
- The export field is opt-in and does not change the default payment or webhook-event export schema.
- This change is additive. Existing response fields, pagination envelopes, default ordering, relation loading, webhook
payloads, and automatic delivery behavior are unchanged; no SDK update, merchant configuration, or data migration is
required.