1. Show Float at checkout
Before offering Float as a payment option, make sure the cart total is inside your configured range. Fetch your config once and cache it (it rarely changes — and the endpoint is rate-limited to 5 requests/hour):rules to decide when to show the Float option and to render instalment messaging (e.g. cart total ÷ max term).
2. Create the checkout
When the shopper picks Float, create a checkout server-side:POST /api/checkouts
client_reference_idis your reconciliation key — use your order ID or cart session ID. It’s echoed back verbatim in the callback.notify_urlmust be a publicly reachable HTTPS endpoint. It receives the payment result server-to-server.success_url/cancel_urlare browser redirect targets only — treat them as UX, not truth.customer.emailis required; pre-filling the rest reduces friction on Float’s page.line_itemsappear on the shopper’s payment summary — include them for a better checkout experience.- Sign the request with
X-Signature.
id on your order before redirecting.
3. Redirect the shopper
Send the browser to the returnedpayment_url with a plain HTTP redirect. Don’t iframe it unless Float has explicitly enabled iframe integration for your account (this requires domain allowlisting on Float’s side).
4. Handle the callback
Float POSTs the result to yournotify_url the moment the payment reaches a terminal state. This is the authoritative signal — implement it per the callbacks guide:
- Verify the
X-Signatureheader. - Look up the order by
client_reference_id. - If
successful: mark paid, fulfil. Ifcancelled: release the order. - Respond
2xx— optionally with{ "redirect_url": "..." }to send the shopper to an order-specific confirmation page.
5. Handle the browser return
The shopper lands on yoursuccess_url or cancel_url (or the redirect_url you returned from the callback). Because the callback usually arrives first, the order state should already be settled — render it. If the callback hasn’t arrived yet (rare, but possible), poll your own order state briefly or call GET /api/checkouts/:id rather than showing an error.
6. Reconcile
For robustness, run a periodic reconciliation for orders stuck in a pending state older than ~1 hour:received after its ~30-minute payment session has lapsed will never complete — treat it as abandoned and create a new checkout if the shopper returns.
Edge cases worth handling
Shopper closes the browser after paying
Shopper closes the browser after paying
The callback still fires — your
notify_url is server-to-server. This is exactly why fulfilment must key off the callback, not the success_url.Duplicate callbacks
Duplicate callbacks
Callbacks can be retried and duplicated. Make your handler idempotent: if the order is already marked paid, acknowledge with a
2xx and do nothing.Amount changed after checkout creation
Amount changed after checkout creation
A Float checkout is fixed-amount. If the cart changes, abandon the old checkout and create a new one — never reuse a
payment_url for a different total.Shopper clicks back and pays twice
Shopper clicks back and pays twice
Guard on your side: if an order is already paid, don’t create another checkout for it. Use one
client_reference_id per payable order state.