Skip to main content

About split carts in checkout

With split carts in checkout, each order a customer completes can contain more than one delivery group. A delivery group might represent a separate shipment, a different shipping option, or a pickup group.

Split carts support two related checkout experiences:

  • Split shipping, where items ship in separate packages such as those from different locations or those that ship with different rates.
  • Ship and pickup in one order, where some items ship to the customer and other items are picked up from a location.

After checkout, Shopify represents each group as a fulfillment order. The same order can have one or many fulfillment orders. To support split carts, use fulfillment orders as the source of truth for fulfillment work, and read each fulfillment order's deliveryMethod to understand whether it represents shipping, or another delivery method type.


Anchor to How split carts affect appsHow split carts affect apps

A single order can generate more than one FulfillmentOrder for the same location. This doesn't require API schema changes, because delivery and fulfillment data is already modeled as collections.

This can happen when a checkout includes:

  • Multiple shipments with different delivery promises, shipping profiles, or fulfillment locations.
  • Multiple delivery method types, such as a shipping group and a pickup group in the same order.

If your app already reads fulfillment data from the FulfillmentOrder object and processes each fulfillment order independently, then you might not need to make changes. If your app reads line item information from the Order object or assumes a one-to-one mapping between an order, location, and fulfillment order, then update it to read fulfillment order data and the fulfillment order deliveryMethod.


Anchor to Split cart scenariosSplit cart scenarios

The following scenarios show how a checkout can split into multiple delivery groups and fulfillment orders. In each scenario, process fulfillment orders independently and use fulfillment order delivery method data instead of order-level assumptions.

An order can split into multiple fulfillment orders when it includes any of the following:

  • Preorders and one-time purchase products.
  • Subscriptions and one-time purchase products.
  • Products shipping from different locations.
  • Products from different shipping profiles.

When a cart meets any of these conditions, Shopify creates multiple fulfillment orders, one per delivery group.

Anchor to Ship and pickup in one orderShip and pickup in one order

Ship and pickup in one order is a split cart scenario where a customer chooses to ship some items and pick up other items during the same checkout. Shopify creates separate fulfillment orders for the shipping and pickup groups.

For apps, the key difference from split shipping is that fulfillment orders can have different deliveryMethod.methodType values. For example:

  • SHIPPING identifies a fulfillment order that ships to the customer.
  • PICK_UP identifies a fulfillment order that the customer picks up from a location.

Don't infer the delivery method from shippingLines, delivery profile names, location count, or the presence of a shipping address. Use the fulfillment order deliveryMethod field instead.


Anchor to How split carts work with APIsHow split carts work with APIs

After a customer completes checkout and Shopify creates an order, order routing creates one or more fulfillment orders. Each fulfillment order represents work for a specific group of items at a specific location, and includes the deliveryMethod that describes how those items reach the customer.

For split shipping, multiple fulfillment orders might all use the SHIPPING delivery method type, but have different shipping options, delivery promises, shipping profiles, or assigned locations. For ship and pickup in one order, fulfillment orders for the same order can use different delivery method types, such as SHIPPING and PICK_UP.

Fulfillment order data is available in the GraphQL Admin API and REST Admin API.

Anchor to Get notified after order routing is completeGet notified after order routing is complete

Your app can subscribe to the fulfillment_orders/order_routing_complete webhook to be notified after Shopify finishes order routing and creates the related fulfillment orders. You can also refer to the API documentation for creating a webhook subscription and fetching existing webhook subscriptions.


Anchor to Fetch relevant data using existing APIsFetch relevant data using existing APIs

While you can integrate with Shopify APIs in different ways, we recommend that you fetch order details that include line items, shipping lines, fulfillment orders, fulfillment order line items, and delivery method information.

You can fetch a first page of order details, such as the order ID, line items, shipping lines, fulfillment orders, fulfillment order line items, and delivery methods, in a single GraphQL query on the Order object.

For example, you might want to fetch the following information:

  • Line items: You can fetch details about the items in an order, such as the product variant, its price, and more, using the lineItems connection on the Order object. Each connection edge exposes a LineItem.

  • Shipping lines: You can fetch a summary of shipping costs for an order using the shippingLines connection on the Order object. Don't use shipping lines as the only source of delivery groups, because pickup fulfillment orders might not have a matching shipping line.

  • Fulfillment orders: You can access fulfillment orders using the fulfillmentOrders connection on the Order object. Use fulfillment order line items to map the fulfillment order back to order line items. Use the deliveryMethod.methodType field on the FulfillmentOrder object to identify whether a fulfillment order is for shipping, pickup, local delivery, or another delivery method type.

    The GraphQL connection types are paginated. For orders with many line items, shipping lines, or fulfillment orders, paginate each connection and keep nested connection page sizes small to stay within GraphQL Admin API query cost limits.

    The following example fetches the information listed above:

POST https://{shop}.myshopify.com/api/{api_version}/graphql.json

Query

# The query fetches order details, such as the order ID, status, line items, shipping lines, fulfillment orders, and delivery methods.
query OrderDetailsComplete {
order(id: "gid://shopify/Order/3") {
id
lineItems(first: 50) {
edges {
node {
id
name
product {
id
}
variant {
title
id
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
shippingLines(first: 10) {
edges {
node {
id
custom
title
code
source
originalPriceSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
currentDiscountedPriceSet {
presentmentMoney {
amount
currencyCode
}
shopMoney {
amount
currencyCode
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
fulfillmentOrders(first: 10) {
edges {
node {
id
status
requiresShipping
fulfillAt
lineItems(first: 10) {
edges {
node {
id
totalQuantity
remainingQuantity
lineItem {
id
name
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
assignedLocation {
name
}
deliveryMethod {
methodType
presentedName
serviceCode
minDeliveryDateTime
maxDeliveryDateTime
additionalInformation {
instructions
phone
}
brandedPromise {
name
handle
}
}
}
}
pageInfo {
hasNextPage
endCursor
}
}
}
}

JSON response

HTTP/1.1 200 OK
{
"data": {
"order": {
"id": "gid://shopify/Order/3",
"lineItems": {
"edges": [
{
"node": {
"id": "gid://shopify/LineItem/5",
"name": "Fragile product",
"product": {
"id": "gid://shopify/Product/4"
},
"variant": {
"title": "Default Title",
"id": "gid://shopify/ProductVariant/9"
}
}
},
{
"node": {
"id": "gid://shopify/LineItem/6",
"name": "Black boots",
"product": {
"id": "gid://shopify/Product/3"
},
"variant": {
"title": "Default Title",
"id": "gid://shopify/ProductVariant/7"
}
}
}
],
"pageInfo": {
"hasNextPage": false,

Anchor to Interpret delivery methodsInterpret delivery methods

Each fulfillment order has its own deliveryMethod. For split shipping, multiple fulfillment orders can have methodType: "SHIPPING", but different presentedName, serviceCode, or delivery promise dates. For ship and pickup in one order, use methodType to separate shipping and pickup work.

Example fulfillment order delivery methods

{
"fulfillmentOrders": {
"edges": [
{
"node": {
"id": "gid://shopify/FulfillmentOrder/101",
"deliveryMethod": {
"methodType": "SHIPPING",
"presentedName": "Standard",
"serviceCode": "Standard"
}
}
},
{
"node": {
"id": "gid://shopify/FulfillmentOrder/102",
"deliveryMethod": {
"methodType": "PICK_UP",
"presentedName": "Pickup in store",
"additionalInformation": {
"instructions": "Ready for pickup tomorrow",
"phone": "+1 555 555 5555"
}
}
}
}
]
}
}

Use methodType to choose fulfillment behavior:

  • SHIPPING: Ship items to the fulfillment order destination.
  • PICK_UP: Prepare items at the assigned location for customer pickup. Use additionalInformation.instructions and additionalInformation.phone when they're present.
  • Other values, such as LOCAL, PICKUP_POINT, RETAIL, and NONE: Handle or ignore these values explicitly, depending on what your app supports.
Note

GraphQL methodType values are uppercase enums, such as SHIPPING and PICK_UP. In the REST Admin API FulfillmentOrder resource, delivery_method.method_type is documented as lowercase strings: shipping, pick_up, local, none, and retail. Branch on those REST literals, including pick_up for pickup, not on GraphQL enum spellings.

Delivery information can also be fetched using the REST Admin API Order and FulfillmentOrder resources. In REST responses, use delivery_method.method_type for the same decision that you make with deliveryMethod.methodType in GraphQL Admin API responses.

You can fetch order details, such as the order ID, status, line items, and shipping lines, using the Order resource.

GET https://{shop}.myshopify.com/admin/api/{api_version}/orders/{order_id}.json

Response

# Response includes order details, including order ID, status, line items, and shipping lines.
HTTP/1.1 200 OK
{
"order": {
"id": 3,
"cancel_reason": null,
"checkout_id": 3,
"closed_at": null,
"confirmation_number": "HYXXAJK3G",
"confirmed": true,
"contact_email": "abc@example.com",
"created_at": "2024-07-08T19:06:30-04:00",
"currency": "CAD",
"current_subtotal_price": "57.00",
"line_items": [
{
"id": 5,
"admin_graphql_api_id": "gid://shopify/LineItem/5",
"attributed_staffs": [],
"current_quantity": 1,
"fulfillable_quantity": 1,
"fulfillment_service": "manual",
"fulfillment_status": null,
"gift_card": false,
"grams": 0,
"name": "Fragile product",
"price": "15.00",
"price_set": {
"shop_money": {
"amount": "15.00",
"currency_code": "CAD"
},
"presentment_money": {
"amount": "15.00",
"currency_code": "CAD"
}

Anchor to Fetch fulfillment order detailsFetch fulfillment order details

Use the Fulfillment Order REST resource to fetch fulfillment order details, such as the fulfillment order ID, status, fulfill_at date, assigned location, line items, and delivery method.

GET https://{shop}.myshopify.com/admin/api/{api_version}/orders/{order_id}/fulfillment_orders.json

Response

# Response includes fulfillment order details, such as fulfillment order ID, status, fulfill_at date, assigned location details, and delivery method details.
HTTP/1.1 200 OK
{
"fulfillment_orders": [
{
"id": 5,
"shop_id": 1,
"order_id": 3,
"assigned_location_id": 1,
"request_status": "unsubmitted",
"status": "open",
"supported_actions": [
"create_fulfillment",
"hold",
"merge"
],
"destination": {
"id": 5,
"address1": "150 Elgin Street",
"address2": null,
"city": "Ottawa",
"company": null,
"country": "Canada",
"email": "abc@example.com",
"first_name": null,
"last_name": "Lname",
"phone": null,
"province": "Ontario",
"zip": "K2P 1L4"
},
"line_items": [
{
"id": 5,
"shop_id": 1,
"fulfillment_order_id": 5,
"quantity": 1,

Was this page helpful?