Skip to main content

Implement pickup with an integrated shopper experience

Learn how to implement a basic pickup workflow that supports having an in-store shopper who uses the Instacart Shopper app. You can try out this tutorial in your development environment.

note

While this tutorial shows you how to create an order, the order you create is sent to a development version of the Fulfillment engine. The order is not batched for fulfillment.

To support your development efforts, this tutorial also includes tips to consider when you implement the workflow in a production environment.

  1. Before you begin
  2. Find store locations near the customer
  3. Create a user account
  4. Fill a cart
  5. Understand changes required in the checkout process
  6. Reserve a time slot for pickup
  7. Create a pickup order
  8. What happens to an order in a production environment?
  9. Summary

Before you begin#

For this tutorial, you need the following items:

If store locations, catalog items, or the Powered By Instacart page are not yet in your development environment, contact your Instacart Connect representative.

Variables used in this tutorial#

The following variables are used in requests in this tutorial. When you see a variable, substitute them with values that work in your development environment.

VariableDescription
<instacart_development_domain>The domain of your assigned Instacart development server, such as connect.dev.instacart.tools.
<token>The generated access token.
<item_upc>The UPC number of an item in your development store that you can add to a cart. You'll need this value when you list time slots and create the order.
<location_code>After you find stores, select one to use in this tutorial. You'll need this value when you reserve a time slot and create the order.
<service_option_id>After you find available time slots, select one to use in this tutorial. You'll need this value when you reserve a time slot.
<service_option_hold_id>After you reserve the time slot, note the ID. You'll need this value when you create the order.

The responses in this tutorial show sample values in place of the variables. The responses that are returned in your environment should have a similar format to the example responses. If you are interested in other possible responses including errors, see the API documentation.

Find store locations near the customer#

Stores that offer pickup have one or both of the flags pickup or pickup_only set to true. Any stores that have both flags set to false are omitted from the response.

Find the stores offering pickup near the specified address. In the request, substitute your values for the variables <instacart_development_domain> and <token>. If you don't have stores near this address, substitute an address that you know is close to one of your stores.

curl --request POST \  --url https://<instacart_development_domain>/v2/fulfillment/stores/pickup \  --header 'Accept: application/json' \  --header 'Authorization: Bearer <token>' \  --header 'Content-Type: application/json' \  --data '{  "find_by": {    "address_line_1": "50 Beale St",    "postal_code": "94105"  }}'

The response contains the array of store locations near the address.

{    "stores": [        {            "name": "Example Location 1",            "location_code": "2222-33333",            "flags": {                "alcohol": true,                "pickup": true,                "pickup_only": false            }        },        {            "name": "Example Location 2",            "location_code": "5555-11111",            "flags": {                "alcohol": true,                "pickup": true,                "pickup_only": false            }        },        {            "name": "Example Location 3",            "location_code": "7777-99999",            "flags": {                "alcohol": false,                "pickup": true,                "pickup_only": true            }        }    ],    "is_partial": false}

From the response returned in your development environment, choose a store to use in this tutorial. You'll substitute the location code for the variable <location_code> in requests.

Production environment tip

When you get the list of stores, you can either choose a store location for the customer or allow the customer to select a store location where they want to shop. You might want to match the returned store location to a store address so that you can display the store address to the customer.

Create a user account#

The user account contains the minimum information required by Instacart to create and fulfill an order. The account must have at least a unique user ID and the customer's first name. The user ID is defined by you, but it must be unique for all retailer customers. For example, you might choose user names or loyalty card IDs.

Create the user account. In the request, substitute your values for the variables <instacart_development_domain> and <token>.

curl --request POST \    --url https://<instacart_development_domain>/v2/fulfillment/users \    --header 'Accept: application/json' \    --header 'Authorization: Bearer <token>' \    --header 'Content-Type: application/json' \    --data '{    "user_id": "kamalsingh243aQW23234",    "first_name": "kamal",    "last_name": "singh",    "phone_number": "8005550101"}'

A successful JSON response has the status code 200 and the following fields:

{    "user_id": "kamalsingh1234",    "first_name": "Kamal",    "last_name": "Singh",    "phone_number": "8005550101"}

If the user account already exists, for example if you or someone else has tried this tutorial on your development environment recently, the request returns the status code 400 User already created. You can continue the tutorial with this ID or call the method again with a different user ID.

Production environment tip

Save the generated user ID with your other customer account information and reuse it for all orders by that customer. It is up to you to ensure the user ID remains unique and associated with the correct customer. If the same ID is used for multiple customers, you risk introducing security and privacy concerns.

Fill a cart#

To create an order, you need a cart with some items in it. Use your development environment to add an item to the cart that is available at the selected store. Note the UPC number. You'll substitute this value for the variable <item_upc> in requests.

Understand changes required in the checkout process#

During the checkout process, your storefront needs to include prompts to collect the information necessary to create an order. For this tutorial, the Create a pickup order request contains sample values for these items.

The information to collect before you create an order includes:

  • Confirmation to opt in to receiving SMS notifications during order fulfillment. Default is false.
  • Confirmation if Electronic Benefits Transfer (EBT) is used as a payment method. Default is false.
  • Loyalty card number. (optional)
  • Special instructions. (optional)
  • If a cart contains alcohol, the customer's date of birth. The customer must be old enough to legally purchase alcohol in their region. Advise the customer that they must show identification with their date of birth when they pick up the order.

Near the end of the checkout process, your storefront needs to handle the following tasks:

  • Display the order details for review, and enable a customer to change items or update any of the collected information.
  • Prompt for payment. Reserve the payment amount but wait to process the payment until after your site receives a callback to confirm that the order was picked up. Refunds and replacements might affect the total cost of the order.
  • Prompt the user to select a time slot, as described in the next step.

Reserve a time slot for pickup#

Before you can reserve a time slot, you need to retrieve a list of available time slots. The Fulfillment engine assesses the cart items to determine if any items have restrictions that might affect order fulfillment, such as alcohol or weight, and returns suitable time slots. After the customer selects a time slot, you can reserve the time slot for 10 minutes.

Retrieve the list of available time slots. In the request, substitute your values for the variables <instacart_development_domain>, <token>, <item_upc>, and <location_code>.

curl --request POST \    --url 'https://<instacart_development_domain>/v2/fulfillment/users/kamalsingh1234/service_options/cart/pickup' \    --header 'Accept: application/json' \    --header 'Authorization: Bearer <token>' \    --header 'Content-Type: application/json' \    --data '{    "items": [        {            "line_num": "1",            "count": 10,            "weight": 1,            "item": {                "upc": "<item_upc>"            }        }    ],    "location_code": "<location_code>}'

The response contains a list of available time slots. Timestamps are returned in Coordinated Universal Time (UTC).

{    "service_options": [        {            "id": 3310259,            "date": "2021-06-04",            "window": {                "immediate_hour": 2            },            "availability": {                "available": true,                "reasons": [],                "item_codes": []            }        },        {            "id": 10358918,            "date": "2021-06-04",            "window": {                "immediate_hour": 5            },            "availability": {                "available": true,                "reasons": [],                "item_codes": []            }        },        {            "id": 418283417,            "date": "2021-06-04",            "window": {                "start_at": "2021-06-04T23:00:00Z",                "end_at": "2021-06-05T01:00:00Z"            },            "availability": {                "available": true,                "reasons": [],                "item_codes": []            }        },    ...  ]}

From your response, choose a time slot to use in this tutorial. You'll substitute the ID for the variable <service_option_id> in the next request.

Reserve the time slot. In the request, substitute your values for the variables <instacart_development_domain>, <token>, and <service_option_id>.

curl --request POST \    --url 'https://<instacart_development_domain>/v2/fulfillment/users/kamalsingh1234/service_options/<service_option_id>/reserve' \    --header 'Accept: application/json' \    --header 'Authorization: Bearer <token>' \    --header 'Content-Type: application/json'

The response contains details about the reserved time slot with the service option hold ID 21469029.

{    "service_option_hold": {        "id": 21469029,        "expires_at": "2021-06-04T18:50:50Z",        "service_option": {            "id": 418283417,            "date": "2021-06-04",            "window": {                "start_at": "2021-06-04T23:00:00Z",                "end_at": "2021-06-05T01:00:00Z"            },            "availability": {                "available": true,                "reasons": [],                "item_codes": []            }        }    }}

From your response, note the service option hold ID. You'll substitute this value for the variable <service_option_id_hold> when you create the order. The reservation is held for 10 minutes. To book the time slot, create the order.

Production environment tips
  • Convert the UTC timestamps to the user's time zone before displaying the time slots.
  • To avoid disappointing your customers, make the reservation as close to the end of the checkout process as possible. If a reservation expires before the order is created, Connect still attempts to book the time. Generally speaking, time slots have capacity for more than one order. If, however, the time slot capacity is fully booked, your storefront needs to prompt your customer to select a different time slot.
  • If your retailer site enables customers to change a reserved time slot, send the request again with the new time slot. Connect expires the previous time slot and tries to book the new one. An order can have only one time slot reserved.

Create a pickup order#

Send a request to create an order as soon as possible after reserving the time slot. The order requires a retailer-generated order ID.

Create the order. In the request, substitute your values for the variables <instacart_development_domain>, <token>, <service_option_hold_id>, <location_code>, and <item_upc>.

curl --request POST \    --url 'https://<instacart_development_domain>/v2/fulfillment/users/kamalsingh1234/orders/pickup' \    --header 'Accept: application/json' \    --header 'Authorization: Bearer <token>' \    --header 'Content-Type: application/json' \    --data '{    "order_id": "1234xyz-5555,    "service_option_hold_id": "<service_option_hold_id>",    "special_instructions": "",    "location_code": "<location_code>",    "paid_with_ebt": true,    "locale": "en-US",    "user": {        "phone_number": "8005550101",        "sms_opt_in": true    },    "address": {        "address_line_1": "50 Beale St",        "postal_code": "94105"    },    "items": [        {            "line_num": "1",            "count": 10,            "weight": 1,            "replacement_policy": "no_replacements",            "item": {                "upc": "<item_upc>"            }        }    ]}'

The response contains details about the order with the order ID 1234xyz-5555.

{    "id": "1234xyz-5555",    "status": "brand_new",    "order_url": "https://customers.dev.instacart.tools/s/Y25Ud2M1RU5m",    "created_at": "2021-06-04T19:04:08Z",    "cancellation_reason": "",    "locale": "en_US",    "fulfillment_details": {        "window_starts_at": "2021-06-04T19:04:07Z",        "window_ends_at": "2021-06-04T21:04:07Z"    },    "items": [        {            "line_num": "1",            "qty": 10.0,            "qty_unit": "each",            "replaced": false,            "replacement_policy": "no_replacements",            "item": {                "upc": "0078735917701",                "rrc": ""            }        }    ]}
Production environment tip

It can take several seconds to receive confirmation that the order is created. For your storefront, consider what you want to show to the customer while they wait for confirmation.

What happens to an order in a production environment?#

As previously mentioned, an order created in a development environment is not fulfilled. To complete this tutorial, let's review what happens to orders created in a production environment.

In a production environment, the order is added to a fulfillment batch for the requested store and time slot. Until the order is assigned to a shopper, you can provide a way for your customers to update an order or cancel an order.

If your retailer site is set up to receive callbacks, your site receives information about events as the order is fulfilled. For example, you are notified when a shopper starts shopping and when the order is staged for pickup. Your site can use these events to keep your customer up to date and to let them know when the order is ready for pick up. For a list of the available events that you can track, see Event callbacks.

A shopper receives the order and begins shopping. The shopper records items as they are picked from the shelf. If the customer opted in for SMS notifications, the customer receives status messages and can chat with the shopper about replacements and refunds. For more insight into shopper communications, see the Pickup user journey.

When the order is ready for pickup, the shopper brings the order to a staging area. The customer is notified by SMS message that the order is ready. When the customer arrives at the store, they click a link in their SMS message which takes them to the Powered by Instacart page that was set up for the retailer site. The customer is prompted to provide details about how to find their vehicle. A retailer employee runs the order to the vehicle and delivers the order to the customer.

tip

You can get all orders for the user account, including the order status, with the Get orders method.

Summary#

In this tutorial, we found stores near a customer that offered pickup and created a user account. Then we filled a cart and learned what information needs to be collected during checkout. We reserved a time slot and created an order. Finally, we discussed what happens in a production environment while the order is in the fulfillment process.