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 the call is made by an authenticated user, the created checkout will be assigned to that user.
-
If the call is not made by an authenticated user, the created checkout will not have a user assigned. A user email is not required at this stage, but it must be provided before adding a promo code, creating a payment, or completing the checkout.
Checkout.channel.countries
provides a list of countries to which shipping is available, derived from all shipping methods assigned to the checkout's channel. This can be useful for rendering a country picker in the checkout view.
- Mutation
- Variables
- Result
mutation CheckoutCreate($input: CheckoutCreateInput!) {
checkoutCreate(input: $input) {
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
}
}
}
{
"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"
}
}
}
{
"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.
- Mutation
- Variables
- Result
mutation CheckoutEmailUpdate($id: ID, $email: String!) {
checkoutEmailUpdate(id: $id, email: $email) {
checkout {
id
email
}
errors {
field
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZmE5ZjBkMjYtMWM3NC00MDgyLTk3MzktYTIxOGE2NzVjMDZk",
"email": "test_customer@example.com"
}
{
"data": {
"checkoutEmailUpdate": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZmE5ZjBkMjYtMWM3NC00MDgyLTk3MzktYTIxOGE2NzVjMDZk",
"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 will be removed from the checkout.
- Mutation
- Variables
- Response
mutation CheckoutLinesAdd($id: ID, $lines: [CheckoutLineInput!]!) {
checkoutLinesAdd(id: $id, lines: $lines) {
checkout {
lines {
id
variant {
name
}
quantity
}
totalPrice {
gross {
currency
amount
}
}
}
}
}
{
"id": "Q2hlY2tvdXQ6ZmE5ZjBkMjYtMWM3NC00MDgyLTk3MzktYTIxOGE2NzVjMDZk",
"lines": [
{
"quantity": 1,
"variantId": "UHJvZHVjdFZhcmlhbnQ6Mjc0"
}
]
}
{
"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 the provided quantity.
- Mutation
- Variables
- Response
mutation CheckoutLinesAdd($id: ID, $lines: [CheckoutLineInput!]!) {
checkoutLinesAdd(id: $id, lines: $lines) {
checkout {
lines {
id
variant {
name
}
quantity
}
totalPrice {
gross {
currency
amount
}
}
}
}
}
{
"id": "Q2hlY2tvdXQ6ZmE5ZjBkMjYtMWM3NC00MDgyLTk3MzktYTIxOGE2NzVjMDZk",
"lines": [
{
"quantity": 1,
"variantId": "UHJvZHVjdFZhcmlhbnQ6Mjc0",
"forceNewLine": true
},
{
"quantity": 2,
"variantId": "UHJvZHVjdFZhcmlhbnQ6Mjc0"
}
]
}
{
"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 the checkout can be overridden. The provided price will be treated as the base price of the variant. Applying a voucher or sale in the checkout will be applied 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
- Variables
- Response
mutation CheckoutLinesAdd($id: ID, $lines: [CheckoutLineInput!]!) {
checkoutLinesAdd(id: $id, lines: $lines) {
checkout {
id
lines {
variant {
id
}
quantity
totalPrice {
gross {
amount
currency
}
net {
amount
currency
}
}
}
}
errors {
field
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw",
"lines": [
{
"quantity": 1,
"variantId": "UHJvZHVjdFZhcmlhbnQ6MzA2",
"price": 16.22
}
]
}
{
"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 and Billing Address​
Use checkoutShippingAddressUpdate
and checkoutBillingAddressUpdate
mutations to set the destination address.
Keep in mind that address affects the availability of the products.
Read more about shipping and billing in checkout.
- 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.
The return type in checkout.deliveryMethod
can be either Warehouse
or ShippingMethod
, so a union type must be used.
Learn more about delivery methods and how Saleor return shipping methods.
See the GraphQL documentation to learn more about unions.
- Mutation
- Variables
- Response
mutation CheckoutDeliveryMethodUpdate($id: ID, $deliveryMethodId: ID) {
checkoutDeliveryMethodUpdate(
id: $id, deliveryMethodId: $deliveryMethodId)
{
errors {
message
field
}
checkout {
deliveryMethod {
... on Warehouse {
id
name
}
... on ShippingMethod {
id
name
}
}
}
__typename
}
}
{
"id": "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw",
"deliveryMethodId": "U2hpcHBpbmdNZXRob2Q6MTU="
}
{
"data": {
"checkoutDeliveryMethodUpdate": {
"errors": [],
"checkout": {
"deliveryMethod": {
"id": "U2hpcHBpbmdNZXRob2Q6MTU=",
"name": "FedEx"
}
},
"__typename": "CheckoutDeliveryMethodUpdate"
}
},
"extensions": {
"cost": {
"requestedQueryCost": 0,
"maximumAvailable": 50000
}
}
}
Apply a Promo Code​
Use checkoutAddPromoCode
to add a voucher code or gift card to a checkout.
For more details, see the vouchers and gift cards guides.
- Mutation
- Variables
- Response
mutation CheckoutAddPromoCode($id: ID, $promoCode: String!) {
checkoutAddPromoCode(id: $id, promoCode: $promoCode) {
checkout {
id
discount {
amount
currency
}
totalPrice {
gross {
amount
currency
}
}
voucherCode
giftCards{
last4CodeChars
}
}
errors {
field
code
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm",
"promoCode": "WELCOME10"
}
{
"data": {
"checkoutAddPromoCode": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm",
"discount": {
"amount": 40,
"currency": "USD"
},
"totalPrice": {
"gross": {
"amount": 40,
"currency": "USD"
}
},
"voucherCode": "WELCOME10",
"giftCards": []
},
"errors": []
}
}
}
Attach Customer to Checkout​
Use checkoutCustomerAttach
to assign a user to an anonymous checkout.
- When called by a logged-in customer, provide the
checkoutId
. - When called by an App, provide
checkoutId
andcustomerId
, require theIMPERSONATE_USER
permission.
- Mutation
- Variables
- Response
mutation CheckoutCustomerAttach($id: ID, $customerId: ID) {
checkoutCustomerAttach(id: $id, customerId: $customerId) {
checkout {
id
email
user {
id
email
}
}
errors {
field
code
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm",
"customerId": "VXNlcjoxNA=="
}
{
"data": {
"checkoutCustomerAttach": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm",
"email": "gary.fisher@example.com",
"user": {
"id": "VXNlcjoxNA==",
"email": "gary.fisher@example.com"
}
},
"errors": []
}
},
"extensions": {
"cost": {
"requestedQueryCost": 1,
"maximumAvailable": 50000
}
}
}
Detach Customer from Checkout​
Use checkoutCustomerDetach
to remove the assigned user from a checkout.
- Mutation
- Variables
- Response
mutation CheckoutCustomerDetach($id: ID) {
checkoutCustomerDetach(id: $id) {
checkout {
id
email
user {
id
}
}
errors {
field
code
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm"
}
{
"data": {
"checkoutCustomerDetach": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm",
"email": "gary.fisher@example.com",
"user": null
},
"errors": []
}
}
}
Completing checkout​
Checkout can be completed if all requirements are satisfied.
When the checkout is fully paid, the CHECKOUT_FULLY_PAID
webhook will be triggered.
- Mutation
- Variables
- Result
mutation CheckoutComplete($id: ID) {
checkoutComplete(id: $id) {
order {
id
status
}
errors {
field
message
}
}
}
{
"id": "Q2hlY2tvdXQ6ZDYyNzk4OTgtNmE2My00NTk3LWFhYTktMTVhOWEwN2I1MzFm"
}
{
"data": {
"checkoutComplete": {
"order": {
"id": "T3JkZXI6MjU=",
"status": "UNFULFILLED"
},
"errors": []
}
}
}