Three lines

Uber

Developers

Order Integration

Access to These APIs May Require Written Approval From Uber

Uber’s APIs are always under development and as such are subject to changes according to our Versioning & Upgrade policy. As part of Uber’s ongoing privacy improvements, we’ve updated our Developer API program with new scope access policies for third party applications. For further information, please refer to our Getting Started guides.

Overview

Use the Order API to ingest and manage incoming orders from Uber Eats. The API includes a webhook for incoming order notifications from Uber Eats. Once you have successfully set up your webhook URL and menu, retrieve, accept, and deny orders with the Order API endpoints.

Understanding the Order Flow

Adherence to the Eats order integration flow, diagrammed below, is required for order integration. Please study the diagram and read through this page carefully. Note: all orders that are scheduled must be accepted twice, once during the orders.scheduled.notification and again at orders.notification.



Order Notifications

The Order API sends notifications to your app’s configured webhook when an order is placed or canceled. Each notification has a corresponding event_type. See the Order Notification and Order Cancelled reference pages for full details.

event_type Description
orders.notification Sent whenever an order is created.
orders.cancel Sent when an order is cancelled (e.g. by the user or by Uber).
orders.fulfillment_issues.resolved Sent whenever a customer has confirmed change on Resolve Order Fulfillment endpoint. (Only applies to stores on API version 1.0.0 or above)
orders.scheduled.notification Sent whenever an order is created. (Only application to stores on API version 1.0.0 or above)

Your service (a single webhook URL) can receive webhooks for multiple stores, as long as the developer is provisioned to each individual store.

Expected Response

For all webhooks:

  1. Your service should return a 200 response status code with an empty response body to acknowledge receipt of webhook events. If no acknowledgement is received, Uber will continue to retry the webhook according to the retry logic described below.

  2. Pull the order information using the resource_href, which corresponds to the Get Order endpoint. Use the user_id (which corresponds to store_id) from the webhook to map it to the right store for notifications and order injections.

For orders.notification only:

  1. After acknowledging receipt of an orders.notification webhook, you must explicitly POST Accept Order, POST Adjust Fulfillment Issues, or POST Deny Order within 11.5 minutes. Otherwise the order will time out and auto-cancel. Order acceptances should be posted as quickly as possible to minimize Eater cancellations. If your store is set up to receive robocalls for unaccepted orders, a robocall will be triggered if no Accept/Deny is posted after 90 seconds.
Order Webhook Retry Logic

Your service should return an HTTP 200 response code with an empty response body to acknowledge receipt of the webhook event. If Uber does not receive a 200 acknowledgement response, the webhook event will be resent based on an exponential backoff algorithm (i.e. starting at 1 second after the initial attempt, then 2 seconds, then 4 seconds etc.) until 7 total events were sent without a response.

Webhook Security

Webhook messages are signed so that your app can verify that the sender is Uber. Webhooks requests contain an X-Uber-Signature header. The value of this field is a lowercased hexadecimal HMAC signature of the webhook HTTP request body, using the client secret as a key and SHA256 as the hash function.

Python Example

digester = hmac.new(client_secret, webhook_body, hashlib.sha256)
return digester.hexdigest()
Accepting Orders

Once an order is successfully accepted through the Order Acceptance endpoint POST Accept Order, no further action is required through the API unless a cancellation occurs. Customers will see that the store is now preparing their order.

Apart from initiating order cancellations, there is no endpoint for stores to provide order updates after acceptance (e.g. to mark an order as ready for pickup or to delay an order). For delivery orders, a courier will be dispatched based on the Uber predicted order prep time. This number will vary depending on various historical and real-time factors. For pickup orders, customers will be notified that their order is ready for pickup after the predicted order prep time has elapsed.

Adjusting Order Fulfillment

If you can’t fulfill an entire order due to various reasons, you can use the Resolve Order Fulfillment endpoint. This lets your application inform the customer, via the Uber Eats app, that certain items or instructions can’t be met.

When this endpoint is triggered:

  • The customer receives a notification on their Uber Eats app.
  • They can choose to either:
    • Cancel the order, which triggers the orders.failure webhook.
    • Modify their cart based on the given feedback.
  • If the customer agrees to the adjustments, your integration will receive the order.fulfillment_issues.resolved webhook. You should then fetch the updated order details from the “Get Order Details” endpoint.

Please note: This feature is exclusive to the Uber Eats app on iOS and Android. It’s not available or testable on web browsers.

Denying Orders

Orders should be programmatically denied POST Deny Order if they are not able to be injected into the POS system. All denied orders for a location follow one of the two order injection error workflows below. This is configured when a store is provisioned. To switch between workflows, submit a POS Provision configuration request.

  1. (Default) For stores not using Uber Eats Orders, orders are immediately canceled when denied. No courier will be dispatched and the customer will be notified that the store was unable to fulfill the order.

  2. For stores actively using Uber Eats Orders to manage orders, POS-denied orders can be manually accepted on Uber Eats Orders by in-store staff. The dashboard will flash red and display instructions to manually enter order details into the POS. If no manual order acceptance is received within 11.5 minutes of the order placement time, the order will be canceled.

Testing Orders

After setting up your webhook URL, follow the steps below to test orders on Uber Eats using your test accounts.

  1. Eater (Customer) Setup: Sign in to the Uber Eats consumer website with your test developer account. Set the delivery address as the test store address. Your test store should show up, and you should be able to browse the menu. If your test store is not showing up as available on Uber Eats, make sure your menu’s service_availability is set to encompass the time of testing or you may need to change your store hours.

  2. Store Setup: In an incognito Chrome browser, log in to Uber Eats Orders using your test store credentials. Though integrated stores are not required to use Uber Eats Orders, it is helpful to view orders for testing purposes. Ensure that the store is set to Open.

  3. Place an Order: Request an order like a normal user. You do not need to enter any payment information and no couriers will be dispatched. The order should flow through on the store side to Uber Eats Orders. A webhook should be sent to your webhook URL. Note that orders will not be removed from the dashboard but they will expire after an hour and be marked as “Unable to Deliver”. Since this is a test store, this is normal expected behavior. If you’d like, you can re-order (as the eater) from the test store multiple times to test multiple webhooks.

  4. Check if the webhook was received: Your service should have received a notification request from Uber, with the request body similar to the example webhook on the orders.notification reference page. Acknowledge that your service received the webhook by sending a 200 status code response. If you did not receive a webhook notification, make sure you used a valid webhook URL and have enabled your service to receive requests.

  5. Test ACCEPT_pos_order and DENY_pos_order responses: Use the POST /eats/orders/{order_id}/accept_pos_order endpoint to accept the order from Uber. Then place another order and use the POST /eats/orders/{order_id}/deny_pos_order endpoint to deny the second order. Ensure the appropriate responses are being generated for each order.

Next Steps

The next step will be to prepare for launch in a production environment. Please finalize implementation and complete ALL testing in your test account for all Uber Eats Marketplace APIs before proceeding.

If you are finished with development and testing, congratulations! You have completed setting up your test account with your Eats Store, Menu and Order API implementation. See Going Live for steps to go live in a production environment.

Uber

Developers
© 2023 Uber Technologies Inc.