Production releases now wait for comprehensive end-to-end verification, reducing the risk of unverified changes reaching merchants.
This release strengthens the final verification step before backend changes become available in
production. When comprehensive end-to-end checks identify a problem, the release is held until a
corrected version has passed verification.
What changed
- Production releases now wait for the complete end-to-end test result before proceeding.
- A failed or incomplete result prevents the affected version from being released.
- Releases can still proceed when no additional verification result is expected, preserving support for
exceptional maintenance releases.
Why it matters
- Merchants benefit from an additional reliability safeguard between a merged backend change and its
production release.
- Failed verification no longer depends on manual intervention to prevent the affected version from
being deployed.
Developer notes
- No public API, SDK, webhook payload, status-code, or configuration contract has changed.
- No SDK update, payload migration, configuration change, or merchant action is required. This release
contains no breaking changes or removed public APIs.
Pre-release end-to-end verification now concentrates on the areas a change can affect, shortening the path from fix to production without changing public product behavior.
This release improves how Flopay validates backend changes before they ship. Existing integrations
continue to work unchanged; no public API, SDK, checkout flow, or webhook behavior has been modified.
What changed
- End-to-end verification before a release now targets the tests that a change can actually reach, based
on which parts of the platform the change touches, instead of always re-running the entire suite.
- Changes that affect shared foundations, such as test infrastructure, build configuration, or database
schema, continue to trigger the complete end-to-end suite.
- When no change scope is known, the full suite still runs, so validation coverage is never reduced by
default.
Why it matters
- Fixes and improvements spend less time waiting on release verification, so they reach merchants sooner.
- Focused verification does not lower the bar: any change with broad reach is still validated in full.
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.
Customer timeline responses now identify completed and upcoming subscription rebills with a consistent 1-based sequence.
29 Aug 2026
Improvement
Subscriptions
API
Customer timelines now identify each completed subscription rebill by its chronological sequence. Merchants,
developers, and operators can label renewal activity consistently without inferring rebills from event titles,
amounts, timestamps, or provider-specific details.
What changed
- Every historical event in
events and projected event in futureEvents now includes the additive, nullable
rebillSequence field.
- A completed subscription rebill and its directly linked invoice expose the same 1-based sequence. Other historical
activity, including opening payments, one-time payments, recovery retries, and non-completed authorization events,
returns
null.
- A future
subscription.rebill event exposes the next expected sequence. Other future event types return null.
- Sequence numbers remain consistent as ordinary new rebills occur. Genuinely older imported activity may correct the
chronological sequence in a later response.
Developer notes
GET /v1/timelines/record?userUuid=<uuid> and GET /v1/timelines include rebillSequence on historical and future
events. No request changes are required.
- Use
rebillSequence for display and classification, but do not treat it as an immutable event or ledger identifier.
- This release is backward compatible. No SDK update, payload migration, configuration change, or merchant action is
required.
Successful and failed opening charges for Flo-owned subscriptions now stay tied to the correct subscription and opening billing cycle across payment retries.
28 Aug 2026
Fix
Subscriptions
Invoices
Reliability
Opening invoices for Flo-owned subscriptions now remain associated with the correct subscription and
original billing cycle throughout payment recovery. This keeps subscription invoice history consistent
from the first positive-charge attempt onward.
What changed
- Successful and failed opening charges are associated with the corresponding Flo-owned subscription
and its original opening billing cycle.
- Retries across payment providers converge on the same opening invoice. A later failed result cannot
replace an invoice that has already been paid.
- When a retry succeeds through another provider, future renewals use the successful provider and
payment method while retaining the original billing-cycle boundary.
- Existing opening invoices that can be matched unambiguously are corrected automatically. This
reporting correction does not alter subscription schedules or initiate charges.
Developer notes
- No public API, SDK, webhook payload, status-code, or configuration contract has changed.
- No SDK update, payload migration, configuration change, or merchant action is required. This release
contains no breaking changes or removed public APIs.
Completes the v1.7.29 fix for invoices - provider invoices whose customer was never attached to a Flo user were recorded without a client and hidden from client views; they now adopt the owning gateway's client.
v1.7.29 made purchases from provider customers that Flo has never linked to a user book under the
client that owns the gateway. Invoices for the same customers still arrived without a client, so they
were missing from client-scoped invoice lists and exports. The invoice ledger now applies the same rule.
What changed
- Provider invoices (including pending one-time invoices created before the gateway invoice exists)
that reach the ledger without a client adopt the client of the gateway they were issued through.
A client supplied by the caller, or already on the row, is never overridden.
Developer notes
- Applies to every invoice ledger path (Stripe and PayPal webhooks, API checkout, scheduler renewals).
- Invoices recorded before this release keep their previous client value.
- No schema change and no change to any SDK-facing contract.
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.