Field note · 21 April 2026
What backgrounding does to a half-paid basket
A shopper who opens a banking app to approve a payment did not abandon you. The operating system may still treat your process as disposable. On Android especially, the hop is a common way to lose in-memory cart state. Teams then read an empty basket on return as “low intent”.
Freeze is not the same as wipe
iOS will often snapshot the UI. That can look fine until the snapshot is stale: the sheet succeeded, your UI still shows a spinner, and a second tap creates a duplicate authorisation. Android may kill the process outright. Restoring from a local snapshot without a server cart id is how you get ghost lines that cannot be paid.
What to persist
Persist a server-side draft order id as soon as the sheet is likely, not after confirmation. Keep line items and the chosen fulfilment option with that id. Do not persist raw card data. Do persist a flag that a wallet was presented, so recovery copy can say “we still have your order” instead of “you left something”. Guest shoppers need this more than logged-in ones, which is the opposite of how many codebases are built.
Timeouts that lie
If your draft expires in five minutes because a web team copied a session TTL, you will punish anyone who reads an SMS slowly. Align expiry with the PSP’s authorisation window, then say the remaining time in the UI. Cart Persistence for Mobile spends an entire session on this alignment because it is boring and expensive when wrong.
Related studio work lives in programmes under Cart Persistence for Mobile.