Checkout API Guide
Creating a Checkout Session
A Checkout object can be created for logged-in users and for anonymous (guest) users.
To create a Checkout object, use the checkoutCreate mutation.
- 
if Authorization header with a valid auth token is provided, the created checkout will be assigned to the user who is authenticated by this token. 
- 
If no authentication token is provided, the checkout is created for an anonymous user, and an email address is used to identify such a Checkoutobject, linking it with the anonymous user. User email is not required at this stage but must be provided before adding a promo code, creating a payment or completing checkout.
checkout.channel.countries provides a list of countries to which shipping is available, which is derived from all shipping methods assigned to a channel of the checkout. This can be useful to render country picker at the checkout view.
- GraphQL
- Result
mutation {
  checkoutCreate(
    input: {
      channel: "default-channel"
      email: "customer@example.com"
      lines: [{ quantity: 1, variantId: "UHJvZHVjdFZhcmlhbnQ6Mjk3" }]
      shippingAddress: {
        firstName: "John"
        lastName: "Doe"
        streetAddress1: "1470  Pinewood Avenue"
        city: "Michigan"
        postalCode: "49855"
        country: US
        countryArea: "MI"
      }
      billingAddress: {
        firstName: "John"
        lastName: "Doe"
        streetAddress1: "1470  Pinewood Avenue"
        city: "Michigan"
        postalCode: "49855"
        country: US
        countryArea: "MI"
      }
    }
  ) {
    checkout {
      id
      totalPrice {
        gross {
          amount
          currency
        }
      }
      isShippingRequired
      shippingMethods {
        id
        name
        active
        message
      }
      availableCollectionPoints {
        id
        name
        clickAndCollectOption
      }
      availablePaymentGateways {
        id
        name
        config {
          field
          value
        }
      }
    }
    errors {
      field
      code
    }
  }
}
{
  "data": {
    "checkoutCreate": {
      "checkout": {
        "id": "Q2hlY2tvdXQ6ZmE5ZjBkMjYtMWM3NC00MDgyLTk3MzktYTIxOGE2NzVjMDZk",
        "totalPrice": {
          "gross": {
            "amount": 20,
            "currency": "USD"
          }
        },
        "isShippingRequired": true,
        "shippingMethods": [
          {
            "id": "U2hpcHBpbmdNZXRob2Q6MTM=",
            "name": "UPS",
            "active": true,
            "message": ""
          },
          {
            "id": "U2hpcHBpbmdNZXRob2Q6MTI=",
            "name": "DHL",
            "active": false,
            "message": "Not available."
          }
        ],
        "availableCollectionPoints": [
          {
            "id": "V2FyZWhvdXNlOjU0NjliNWQ3LThmOGUtNGVmOS1iMGQxLWNhYWZmYTg4MjI1OQ==",
            "name": "Local Store"
            "clickAndCollectOption": "LOCAL"
          },
          {
            "id": "=V2FyZWhvdXNlOjU0NjliNWQ3LThmOGUtNGVmOS1iMGQxLWNhYWZmYTg4MjI1OA==",
            "name": "Company HQ"
            "clickAndCollectOption": "ALL"
          }
        ],
        "availablePaymentGateways": [
          {
            "id": "app.saleor.adyen",
            "name": "Adyen",
            "config": []
          }
        ]
      },
      "errors": []
    }
  }
}
Set Email
When an anonymous checkout has been created without an email, the email must be set using CheckoutEmailUpdate before creating payment and completing the checkout.
- GraphQL
- Result
mutation {
  checkoutEmailUpdate(
    id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
    email: "test_customer@example.com"
  ) {
    checkout {
      id
      email
    }
    errors {
      field
      message
    }
  }
}
{
  "data": {
    "checkoutDeliveryMethodUpdate": {
      "checkout": {
        "id": "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw",
        "email": "test_customer@example.com"
      },
      "errors": []
    }
  }
}
Managing Lines
To add an item to the cart, use checkoutLinesAdd. The total price will be updated automatically.
See also checkoutLinesDelete and checkoutLinesUpdate.
If the quantity is changed to 0, it wll be removed from checkout.
- GraphQL
- Response
mutation {
  checkoutLinesAdd(
    id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
    lines: [{ quantity: 1, variantId: "UHJvZHVjdFZhcmlhbnQ6Mjc0" }]
  ) {
    checkout {
      lines {
        id
        variant {
          name
        }
        quantity
      }
      totalPrice {
        gross {
          currency
          amount
        }
      }
    }
  }
}
{
  "data": {
    "checkoutLinesAdd": {
      "checkout": {
        "lines": [
          {
            "id": "Q2hlY2tvdXRMaW5lOjI1Mw=="
            "variant": {
              "name": "XL"
            },
            "quantity": 1
          }
        ],
        "totalPrice": {
          "gross": {
            "currency": "USD",
            "amount": 5
          }
        }
      }
    }
  }
}
Creating Two Lines Using a Single Variant
By default if a single variant is added multiple times, the quantity of the variant is increased without adding a new line.
To add the same variant as a separate line, use the forceNewLine flag.
When forceNewLine is not used and the variant exists in multiple lines - Saleor will create a new line with provided quantity
- GraphQL
- Response
mutation {
  checkoutLinesAdd(
    id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
    lines: [
      { quantity: 1, variantId: "UHJvZHVjdFZhcmlhbnQ6Mjc0", forceNewLine: true }
      { quantity: 2, variantId: "UHJvZHVjdFZhcmlhbnQ6Mjc0" }
    ]
  ) {
    checkout {
      lines {
        id
        variant {
          name
        }
        quantity
      }
      totalPrice {
        gross {
          currency
          amount
        }
      }
    }
  }
}
{
 "data": {
   "checkoutLinesAdd": {
     "checkout": {
       "lines": [
         {
           "id": "Q2hlY2tvdXRMaW5lOjI1Mw==",
           "variant": {
             "name": "XL"
           },
           "quantity": 1
         },
         {
           "id": "Q2hlY2tvdXRMaW5lOjI1Mw==",
           "variant": {
             "name": "XL"
           },
           "quantity": 2
         }
       ],
       "totalPrice": {
         "gross": {
           "currency": "USD",
           "amount": 15
         }
       }
     }
   }
 }
}
Setting Custom Line Prices
This feature is only available for apps with HANDLE_CHECKOUTS permission.
The variant price of any item in checkout can be overridden. The provided price will be treated as the base price of the variant. Applying a voucher or sale in checkout will be used on top of the overridden price.
The custom price can be set with the price field in the
CheckoutLineInput
in the following mutations:
- checkoutCreate,
- checkoutLinesAdd– when adding a variant that already exists in the checkout, the corresponding line gets overridden – the quantity is incremented and the price is updated.
- checkoutLinesUpdate– overrides the existing line with the price provided in the mutation.
- GraphQL
- Response
mutation {
  checkoutLinesAdd(
    id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
    lines: [
      { quantity: 1, variantId: "UHJvZHVjdFZhcmlhbnQ6MzA2", price: 16.22 }
    ]
  ) {
    checkout {
      id
      lines {
        variant {
          id
        }
        quantity
        totalPrice {
          gross {
            amount
            currency
          }
          net {
            amount
            currency
          }
        }
      }
    }
    errors {
      field
      message
    }
  }
}
{
  "data": {
    "checkoutLinesAdd": {
      "checkout": {
        "id": "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw",
        "lines": [
          {
            "variant": {
              "id": "UHJvZHVjdFZhcmlhbnQ6MzA2"
            },
            "quantity": 2,
            "totalPrice": {
              "gross": {
                "amount": 32.44,
                "currency": "USD"
              },
              "net": {
                "amount": 32.44,
                "currency": "USD"
              }
            }
          }
        ]
      },
      "errors": []
    }
  }
}
Update Shipping Address
Use checkoutShippingAddressUpdate and checkoutBillingAddressUpdate mutations to set the destination address.
Keep in mind that address affects the availability of the products.
- Mutation
- Variables
- Response
mutation checkoutShippingAddressUpdate($checkoutId: ID!, $shippingAddress: AddressInput!) {
  checkoutShippingAddressUpdate(
    id: $checkoutId
    shippingAddress: $shippingAddress
  ) {
    checkout {
      id
      shippingAddress {
        ...AddressFragment
      }
      billingAddress {
        ...AddressFragment
      }
    }
  }
}
fragment AddressFragment on Address {
    id
    city
    phone
    postalCode
    companyName
    cityArea
    streetAddress1
    streetAddress2
    countryArea
    country {
        country
        code
    }
    firstName
    lastName
}
{
  "checkoutId": "Q2hlY2tvdXQ6MDk1MmNiNWUtMzZkYi00YTQ5LThhN2MtZjAyNGE2M2Y1NzNj",
  "shippingAddress": {
    "city": "New York",
    "cityArea": "",
    "companyName": "",
    "country": "US",
    "countryArea": "NY",
    "firstName": "First Name",
    "lastName": "Last Name",
    "phone": "",
    "postalCode": "10019",
    "streetAddress1": "11 W 53rd St, New York, NY",
    "streetAddress2": ""
  }
}
{
  "data": {
    "checkoutShippingAddressUpdate": {
      "checkout": {
        "id": "Q2hlY2tvdXQ6MDk1MmNiNWUtMzZkYi00YTQ5LThhN2MtZjAyNGE2M2Y1NzNj",
        "shippingAddress": {
          "id": "QWRkcmVzczoxMjc=",
          "city": "NEW YORK",
          "phone": "",
          "postalCode": "10019",
          "companyName": "",
          "cityArea": "",
          "streetAddress1": "11 W 53rd St, New York, NY",
          "streetAddress2": "",
          "countryArea": "NY",
          "country": {
            "country": "United States of America",
            "code": "US",
            "__typename": "CountryDisplay"
          },
          "firstName": "First Name",
          "lastName": "Last Name",
          "__typename": "Address"
        },
        "billingAddress": {
          "id": "QWRkcmVzczoxMjg=",
          "city": "NEW YORK",
          "phone": "",
          "postalCode": "10019",
          "companyName": "",
          "cityArea": "",
          "streetAddress1": "11 W 53rd St, New York, NY",
          "streetAddress2": "",
          "countryArea": "NY",
          "country": {
            "country": "United States of America",
            "code": "US",
            "__typename": "CountryDisplay"
          },
          "firstName": "First Name",
          "lastName": "Last Name",
          "__typename": "Address"
        }
      }
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 2,
      "maximumAvailable": 50000
    }
  }
}
Update Delivery Method
Use checkoutDeliveryMethodUpdate to pass the delivery method returned by the checkout query.
Notice that the return type in checkout.deliveryMethod can be either Warehouse or ShippingMethod, so we need to use union type.
Learn more about delivery methods.
- Mutation
- Response
mutation {
  checkoutDeliveryMethodUpdate(
    id: "Q2hlY2tvdXQ6MDk1MmNiNWUtMzZkYi00YTQ5LThhN2MtZjAyNGE2M2Y1NzNj"
    deliveryMethodId: "U2hpcHBpbmdNZXRob2Q6MTU="
  ) {
    errors {
      message
      field
    }
    checkout {
      deliveryMethod{
        ...on Warehouse{
          id
          name
        }
        ... on ShippingMethod{
          id
          name
        }
      }
    }
    __typename
  }
}
{
  "data": {
    "checkoutDeliveryMethodUpdate": {
      "errors": [],
      "checkout": {
        "deliveryMethod": {
          "id": "U2hpcHBpbmdNZXRob2Q6MTU=",
          "name": "FedEx"
        }
      },
      "__typename": "CheckoutDeliveryMethodUpdate"
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 0,
      "maximumAvailable": 50000
    }
  }
}
Completing checkout
Checkout can be completed if all requirements are satisfied.
When the checkout is fully paid, the webhook CHECKOUT_FULLY_PAID will be triggered.
- GraphQL
- Result
mutation {
  checkoutComplete(
    id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
  ) {
    order {
      id
      status
    }
    errors {
      field
      message
    }
  }
}
{
  "data": {
    "checkoutComplete": {
      "order": {
        "id": "T3JkZXI6MjU=",
        "status": "UNFULFILLED"
      },
      "errors": []
    }
  }
}
Other Mutations and Queries
- checkoutAddPromoCode- Add a promo code to the checkout.
- customerAttach- Attach a user to the checkout.
- customerDetach- Detach a user from the checkout.