---
title: "Order Workflow"
showtoc: true
---

# Order Workflow

An Order is a collection of one or more ProductVariants which can be purchased by a Customer. Orders are represented internally by the [Order entity]({{< relref "order" >}}) and in the GraphQL API by the [Order type]({{< relref "/docs/graphql-api/shop/object-types#order" >}}).

## Order State

Every Order has a `state` property of type [`OrderState`]({{< relref "order-state" >}}). The following diagram shows the default states and how an Order transitions from one to the next.

{{% alert %}}
Note that this default workflow can be modified to better fit your business processes. See the [Customizing the Order Process guide]({{< relref "customizing-the-order-process" >}}).
{{< /alert >}}

{{< figure src="./order_state_diagram.png" >}}

## Structure of an Order

In Vendure an [Order]({{< relref "order" >}}) consists of one or more [OrderLines]({{< relref "order-line" >}}) (representing a given quantity of a particular SKU), which in turn contain one or more [OrderItems]({{< relref "order-item" >}}) (which represent the individual physical units). 

Here is a simplified diagram illustrating this relationship:

{{< figure src="./order_class_diagram.png" >}}

So if the customer adds 2 *Widgets* to the Order, there will be **one OrderLine** containing **two OrderItems**, one for each of the added *Widgets*.

## Shop client order workflow

The [GraphQL Shop API Guide]({{< relref "/docs/storefront/shop-api-guide" >}}#order-flow) lists the GraphQL operations you will need to implement this workflow in your storefront client application.

In this section, we'll cover some examples of how these operations would look in your storefront.

### Manipulating the Order

First, let's define a fragment for our Order that we can re-use in subsequent operations:

```GraphQL
fragment ActiveOrder on Order {
  id
  code
  state
  couponCodes
  subTotalWithTax
  shippingWithTax
  totalWithTax
  totalQuantity
  lines {
    id
    productVariant {
      id
      name
    }
    featuredAsset {
      id
      preview
    }
    quantity
    linePriceWithTax
  }
}
```

Then we can add an item to the Order:

```GraphQL
mutation AddItemToOrder($productVariantId: ID! $quantity: Int!){
  addItemToOrder(productVariantId: $productVariantId, quantity: $quantity) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

To remove an item from the order

```GraphQL
mutation RemoveItemFromOrder($orderLineId: ID!){
  removeOrderLine(orderLineId: $orderLineId) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

To alter the quantity of an existing OrderLine

```GraphQL
mutation AdjustOrderLine($orderLineId: ID! $quantity: Int!){
  adjustOrderLine(orderLineId: $orderLineId, quantity: $quantity) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

At any time we can query the contents of the active Order:

```GraphQL
query ActiveOrder {
  activeOrder {
    ... ActiveOrder
  }  
}
```

### Checking out

During the checkout process, we'll need to make sure a Customer is assigned to the Order. If the Customer is already signed in, then this can be skipped since Vendure will have already assigned them. If not, then you'd execute:

```GraphQL
mutation SetCustomerForOrder($input: CreateCustomerInput!){
  setCustomerForOrder(input: $input) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

Then we need to set the shipping address:

```GraphQL
mutation SetShippingAddress($input: CreateAddressInput!){
  setOrderShippingAddress(input: $input) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

Once the shipping address is set, we can find out which ShippingMethods can be used on this Order:

```GraphQL
query GetShippingMethods{
  eligibleShippingMethods {
    id
    name
    code
    description
    priceWithTax
  }
}
```

The Customer can then choose one of the available ShippingMethods, and we then set it on the Order:

```GraphQL
mutation SetShippingMethod($shippingMethodId: ID!){
  setOrderShippingMethod(shippingMethodId: $shippingMethodId) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

We can now do the same for PaymentMethods:

```GraphQL
query GetPaymentMethods{
  eligiblePaymentMethods {
    id
    name
    code
    description
    isEligible
    eligibilityMessage
  }
}
```

Once the customer is ready to pay, we need to transition the Order to the `ArrangingPayment` state. In this state, no further modifications are permitted. If you _do_ need to modify the Order contents, you can always transition back to the `AddingItems` state:

```GraphQL
mutation TransitionOrder($state: String!){
  transitionOrderToState(state: $state) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

Finally, add a Payment to the Order:

```GraphQL
mutation AddPayment($input: PaymentInput!){
  addPaymentToOrder(input: $input) {
    ... ActiveOrder
    ... on ErrorResult {
      errorCode
      message
    }
  }
}
```

If the Payment is successful, the Order will now be complete. You can forward the Customer to a confirmation page using the Order's `code`:

```GraphQL
query OrderByCode($code: String!) {
  orderByCode(code: $code) {
    ...ActiveOrder
  }
}
```

## ActiveOrderStrategy

In the above examples, the active Order is always associated with the current session and is therefore implicit - which is why there is no need to pass an ID to each of the above operations.

Sometimes you _do_ want to be able to explicitly specify the Order you wish to operate on. In this case, you need to define a custom [ActiveOrderStrategy]({{< relref "active-order-strategy" >}}).
