Chop is a mobile commerce service for small and medium-sized businesses in San Francisco. Our initial focus was, and continues to be, SoMa and the Financial District. We assumed our customers in San Francisco would always have strong connectivity. That in the heart of the tech industry data connectivity would rarely be an issue. Then, during our private beta, we realized we had overlooked a very critical issue:
Connectivity issues on both sides of the ordering process, resulted in numerous errors. We were losing orders, duplicating orders, and some were simply not going through. It was an issue we had to address before public release.
Were a small startup with limited resources, so we started by examining various use cases, to help us to decide what we should focus on first.
There are two user groups with common commerce use cases:
At our current stage, our key focus is to grow the number of engaged users who can complete the core actions. I recommend reading Sarah Tavels excellent article on The Hierarchy of Engagement.
The core action for Chop is to complete an order which involves the following steps:
If you have 100 users at the first step, ideally you want to have 100 users at the last step. You do this by removing as much friction as possible. From the users perspective, the further along they are in the process, the more time and energy theyve invested. The more invested a customer is, the angrier theyll be if something goes wrong.
To better understand how to solve the issue of offline connectivity, I looked at similar apps to see how they were solving this problem.
Conducting offline research:
Heres what I discovered from my case studies:
Amazon is the number one commerce site in the world but the offline experience is unimpressive. When operating offline, users are not given any expectations as to what should and should not work.
(Case study: Starbucks)
Starbucks delivers a similar experience. Your network status is checked on every page, and when there is poor connectivity it displays a standard error message. However, if you dismiss the message, it allows you to navigate to other cached pages before showing the same error message again.
The message dialog feels like a foreign part of the UI, cold and unintuitive, but it does get the job donewhich is to confirm the network error and not to let users go any further.
(Case study: Doordash)
Doordash, even as a younger startup, delivers a delightful experience:
I researched a few more examples and found, in general, there are no established UX patterns for offline. Should users be able to browse the catalog? Should they be able to continue adding to their cart offline? How should network errors be displayed? Is it possible to design the offline experience, so users can continue even with poor connectivity?
Without much guidance from the more established commerce sites, we decided to follow our own design principles and be as thoughtful to the user as possible. That meant:
Here is what weve implemented so far:
Offline design atChop
In general, we leverage clients cached data as much as possible to ensure users have a seamless offline experience. We defer checking a users connection until they are ready to place an order. In our case, as a mobile commerce solution only available in San Francisco, most of our users have an intermittent connection rather than no access at all. Weve taken that into consideration. We now make several attempts to connect to a network before giving up and displaying the splash page.
We designed a splash page with a restaurant and food theme, with copy that says Gone Fishing. Your internet is off the hook mind trying again? Its displayed if a user is disconnected, or if they click on a page that doesnt have any cached data. Hopefully, it functions to lighten the mood for the user, so they are distracted from the disappointment of a failed order. At this point, we also let the user take control, and give them the option to try again.
While this article focuses on design, I do want to bring up a few points about development.
Flow chart: how to handle duplicated orders
When an order is first placed, the client generates a UUID for the order, and it is persisted to local storage on their iPhone, so if the app crashes, is killed, or otherwise needs to recover, an order in progress isnt lost. After committing to local storage, the phone makes a REST call to the server to place the order and charge the consumer. If an existing order is already in the system and has been successfully charged with the same UUID, the order is rejected as a duplicate.
The transition to a successfully charged order is two-phased. First, the order is persisted into an ACID database marked as UNPAID, then it is read and charged to Stripe and marked PAID. If the consumer has another order in progress at the same merchant with a different UUID within a defined time window, it is also rejected, because we do not allow more than one order in progress at the same merchant by design.
The user cannot be charged for the same order twice because it is guarded by UUID check and a database check. The client also cant submit the order twice if it has already been submitted.
(Flow chart: lost order detection and escalation path)
Our merchant tablets constantly ping heartbeats to the server. We have a Quartz Scheduler process that monitors the last time tablets have pinged the server, and how long orders at each merchant have been sitting unclaimed.
When idle time exceeds a threshold, an issue is automatically created in an internal issue tracker, and eventually escalated to Slack. If the merchant responds during this time window, the issue is automatically closed and reported to Slack as resolved.
Eventually, if the downtime persists and Slack messages do not elicit a response, it will be escalated to an SMS message.
What we have implemented so far is by no means perfect, but it is a good first step to ensure our customers can successfully make orders through intermittent connections. We are interested in delivering more. For example, on the splash page, rather than saying Try again, can we change it to Notify me when online? That way, when the phone is back online, we can send a friendly notification from which the user can preview their shopping cart and place their order without even opening the app.
Through this exercise, what I have realized is that users dont have any set expectations for offline experiences. It is in general, as shown through my case studies, a negative spectrum. There is so little information out there about offline UX best practices, whether on web apps or native apps. There are, however, some interesting technologies available now such as Service Workers which I am hoping to explore in 2017 when we start the web app.
Through this article, I hope to see more conversations around offline design and development practices from the community, lets make offline a positive experience.
I also found an Offline First! community which is pretty awesome.
Read Why Chop
Visit our website at getchop.io.
Download iOS app and share with a friend.
Follow me on Twitter.