Skip to main content

Shipping and Billing

Shipping

This step is only used if purchased items require shipping (if they are physical products). The user must select a specific shipping method to create shipping for this checkout. To signify whether shipping is required, use the isShippingRequired field in the Checkout object.

Adding address data

Address can be assigned using the checkoutShippingAddressUpdate mutation:

mutation {
checkoutShippingAddressUpdate(
shippingAddress: {
country: PL
firstName: "John"
lastName: "Smith"
streetAddress1: "ul. Tęczowa 7"
postalCode: "53-030"
city: "Wroclaw"
}
id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
) {
checkout {
shippingAddress {
firstName
lastName
streetAddress1
city
postalCode
}
}
errors {
field
message
code
}
}
}
Expand ▼

Successful response:

{
"data": {
"checkoutShippingAddressUpdate": {
"checkout": {
"shippingAddress": {
"firstName": "John",
"lastName": "Smith",
"streetAddress1": "ul. Tęczowa 7",
"city": "WROCLAW",
"postalCode": "53-030"
}
},
"errors": []
}
}
}

More information about address validation can be found on the address validation page.

Default address

Customers with accounts can set up default addresses, which will be attached automatically during the checkout creation. More information on API reference page for accountSetDefaultAddress.

Listing available shipping methods

After choosing the shipping address, API can be queried for available delivery methods in the user area:

query {
checkout(id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw") {
shippingMethods {
id
name
active
price {
currency
amount
}
}
availableCollectionPoints {
id
name
clickAndCollectOption
}
}
}

Response:

{
"data": {
"checkout": {
"shippingMethods": [
{
"id": "U2hpcHBpbmdNZXRob2Q6MTY1Nw==",
"name": "DHL",
"price": {
"currency": "USD",
"amount": 10.0
},
"active": true,
"message": ""
},
{
"id": "U2hpcHBpbmdNZXRob2Q6MTM=",
"name": "UPS",
"price": {
"currency": "USD",
"amount": 8.0
},
"active": false,
"message": "Not available."
}
],
"availableCollectionPoints": [
{
"id": "V2FyZWhvdXNlOjU0NjliNWQ3LThmOGUtNGVmOS1iMGQxLWNhYWZmYTg4MjI1OQ==",
"name": "Local Store",
"clickAndCollectOption": "LOCAL"
},
{
"id": "V2FyZWhvdXNlOjU0NjliNWQ3LThmOGUtNGVmOS1iMGQxLWNhYWZmYTg4MjI1OA==",
"name": "Company HQ",
"clickAndCollectOption": "ALL"
}
]
}
}
}
Expand ▼

Shipping methods can be internal (defined in the Saleor Dashboard) or external (coming from the 3-rd party). Collection points are warehouses that allow picking-up orders e.g. for click & collect flow.

Selecting the delivery method

Use the checkoutDeliveryMethodUpdate mutation to effectively pair the specific Checkout object with the specified delivery method selected by the user.

This operation requires the following input:

  • id: the checkout ID (the id field of the Checkout object).
  • deliveryMethodId: the shipping method ID or Warehouse ID (from the shippingMethods or availableCollectionPoints field of the Checkout object).

In the following mutation, we assign a delivery method to the checkout using IDs from the previous example. Note that for the checkout object, we want to get back the update totalPrice including shipping costs:

Please note, that selecting collectionPoint or shippingMethod is mandatory for the checkout flow. In other words, setting deliveryMethod is mandatory.

mutation {
checkoutDeliveryMethodUpdate(
id: "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw"
deliveryMethodId: "U2hpcHBpbmdNZXRob2Q6MTM="
) {
checkout {
id
deliveryMethod {
__typename
... on Warehouse {
name
}
... on ShippingMethod {
name
}
}
totalPrice {
gross {
amount
currency
}
}
}
errors {
field
message
}
}
}
Expand ▼

As a result, we get an updated checkout object with a delivery method set:

{
"data": {
"checkoutDeliveryMethodUpdate": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZTEzZDFjOTItOWJkNi00ODViLTgyMDctZTNhM2I5NjVkZTQw",
"deliveryMethod": {
__typename: "ShippingMethod"
"name": "UPS"
},
"totalPrice": {
"gross": {
"amount": 25.99,
"currency": "USD"
}
}
},
"errors": []
}
}
}
Expand ▼

Switching from C&C to standard delivery method

After choosing the click & collect option on a checkout, going back to a standard delivery method will require the shipping address to be changed.

  1. First use checkoutDeliveryMethodUpdate (just with id or token provided). This will remove the collection point from checkout and also remove the shipping address.
mutation {
checkoutDeliveryMethodUpdate(id: "your_checkout_id") {
checkout {
id
}
}
}
  1. Now checkoutShippingAddressUpdate can be used to set the new shipping address for checkout.
  2. Finally, use checkoutDeliveryMethodUpdate with deliveryMethodId to set the standard delivery method.

Address Validation

The checkout's mutations that accept an address as an input have a field that can turn off the address validation. It allows assigning a partial or not fully valid address to the checkout. Providing country code is mandatory for all addresses regardless of the rules provided in this input.

The address validation input has two boolean fields:

  • checkRequiredFields - signals Saleor to raise an error when the provided address doesn't have all the required fields. Set to true by default.
  • checkFieldsFormat - signals Saleor to raise an error when the provided address doesn't match the expected format. Set to true by default.
  • enableFieldsNormalization - determines if Saleor should apply normalization on address fields. Example: converting city field to uppercase letters. Set to true by default.

checkoutCreate

The checkoutCreate mutation has an optional input for providing shipping and billing addresses. If you want to provide only a part of the address, you can disable the address validation.

The mutation accepts validationRules as an input field.

mutation {
checkoutCreate(
input: {
channel: "default-channel"
email: "customer@example.com"
lines: [{ quantity: 1, variantId: "UHJvZHVjdFZhcmlhbnQ6Mjk3" }]
shippingAddress: { country: US }
billingAddress: { postalCode: "XX-YYY", country: US }
validationRules: {
shippingAddress: { checkRequiredFields: false }
billingAddress: { checkRequiredFields: false, checkFieldsFormat: false }
}
}
) {
checkout {
id
}
errors {
field
code
}
}
}
Expand ▼

The response contains the created checkout object:

{
"data": {
"checkoutCreate": {
"checkout": {
"id": "Q2hlY2tvdXQ6NGY1NjI1MDQtOWE2ZS00YjRjLWJiZWYtYmNjNDhkNWMwNDVj"
},
"errors": []
}
}
}

CheckoutShippingAddressUpdate

The checkoutShippingAddressUpdate mutation has an optional field for controlling the shipping address validation: validationRules.

mutation {
checkoutShippingAddressUpdate(
id: "Q2hlY2tvdXQ6MjU1MmYxYTctN2Q3MC00ODg5LTg1OWYtNGNiNWNlMGI4Zjhk"
shippingAddress: { postalCode: "12-333", country: PL }
validationRules: { checkRequiredFields: false }
) {
errors {
field
message
code
}
checkout {
id
shippingAddress {
id
postalCode
firstName
lastName
country {
code
}
}
}
}
}
Expand ▼

The response contains the updated checkout object:

{
"data": {
"checkoutShippingAddressUpdate": {
"errors": [],
"checkout": {
"id": "Q2hlY2tvdXQ6MjU1MmYxYTctN2Q3MC00ODg5LTg1OWYtNGNiNWNlMGI4Zjhk",
"shippingAddress": {
"id": "QWRkcmVzczo4Mg==",
"postalCode": "12-333",
"firstName": "",
"lastName": "",
"country": {
"code": "PL"
}
}
}
}
}
}
Expand ▼

CheckoutBillingAddressUpdate

The checkoutBillingAddressUpdate mutation has an optional field for controlling the billing address validation: validationRules.

mutation {
checkoutBillingAddressUpdate(
id: "Q2hlY2tvdXQ6ZTM4NjMyYzItZTg5NS00ZjE4LTg3YTMtNjIwNGU0NzlmYjUw"
validationRules: { checkFieldsFormat: false, checkRequiredFields: false }
billingAddress: { country: GB, postalCode: "XX YYY" }
) {
checkout {
id
billingAddress {
streetAddress1
city
cityArea
postalCode
country {
code
}
countryArea
}
}
}
}
Expand ▼

The response contains the updated checkout object:

{
"data": {
"checkoutBillingAddressUpdate": {
"checkout": {
"id": "Q2hlY2tvdXQ6ZTM4NjMyYzItZTg5NS00ZjE4LTg3YTMtNjIwNGU0NzlmYjUw",
"billingAddress": {
"streetAddress1": "",
"city": "",
"cityArea": "",
"postalCode": "XX YYY",
"country": {
"code": "GB"
},
"countryArea": ""
}
}
}
}
}
Expand ▼
note

The information about address validation can be found on the address validation page.

note

The shipping and billing addresses need to be valid when finalizing checkout by calling checkoutComplete mutation.

note

The fields for shipping and billing addresses will be normalized (if needed) on completing the checkout by calling checkoutComplete mutation.

Customer Address Saving Strategies

Address updates allow configuring the address-saving strategy for both shipping and billing addresses. This setting determines whether the shipping or billing address should be saved in the customer's address book. It applies only when the checkout is completed by a logged-in user.

By default, both billing and shipping addresses are saved in the customer's address book.

Use cases:

  • External Click & Collect (C&C) addresses: Prevents collection point addresses from being saved to a customer’s address book.
  • Customer choice during checkout: Allows customers to explicitly decide whether to save newly entered addresses to their account.

Applicable Checkout Mutations

The default behavior can be adjusted in the following checkout mutations:

mutation createCheckout($input: CheckoutCreateInput!) {
checkoutCreate(input: $input){
checkout {
id
}
errors {
field
code
}
}
}

input data:

{
"input": {
"channel": "default-channel",
"email": "customer@example.com",
"lines": [{ "quantity": 1, "variantId": "UHJvZHVjdFZhcmlhbnQ6Mjk3" }],
"saveShippingAddress": false,
"shippingAddress": {
"firstName": "John",
"lastName": "Doe",
"streetAddress1": "1470 Pinewood Avenue",
"city": "Michigan",
"postalCode": "49855",
"country": "US",
"countryArea": "MI"
},
"saveBillingAddress": true,
"billingAddress": {
"firstName": "John",
"lastName": "Doe",
"streetAddress1": "1470 Pinewood Avenue",
"city": "Michigan",
"postalCode": "49855",
"country": "US",
"countryArea": "MI"
}
}
}
Expand ▼
mutation checkoutShippingAddressUpdate(
$id: ID,
$shippingAddress: AddressInput!
$saveAddress: Boolean
){
checkoutShippingAddressUpdate(
id: $id
shippingAddress: $shippingAddress
saveAddress: $saveAddress
) {
errors {
field
message
code
}
checkout {
id
shippingAddress {
id
postalCode
firstName
lastName
country {
code
}
}
}
}
}
Expand ▼

input data:

{
"id": "Q2hlY2tvdXQ6MjU1MmYxYTctN2Q3MC00ODg5LTg1OWYtNGNiNWNlMGI4Zjhk",
"shippingAddress": { "postalCode": "12-333"},
"saveAddress": false
}
mutation checkoutBillingAddressUpdate(
$id: ID,
$billingAddress: AddressInput!
$saveAddress: Boolean
){
checkoutBillingAddressUpdate(
id: $id
billingAddress: $billingAddress
saveAddress: $saveAddress
) {
errors {
field
message
code
}
checkout {
id
billingAddress {
id
postalCode
firstName
lastName
country {
code
}
}
}
}
}
Expand ▼

input data:

{
"id": "Q2hlY2tvdXQ6MjU1MmYxYTctN2Q3MC00ODg5LTg1OWYtNGNiNWNlMGI4Zjhk"
"billingAddress": { "postalCode": "12-333"}
"saveAddress": false
}

Important Notes

The setting is treated as part of the address and cannot be provided independently in the mutation input. Attempting to set saveShippingAddress or saveBillingAddress without including the corresponding shippingAddress or billingAddress will result in an error.

For example, providing saveShippingAddress in the checkoutCreate mutation without including shippingAddress will raise an error:

mutation createCheckout($input: CheckoutCreateInput!) {
checkoutCreate(input: $input){
checkout {
id
}
errors {
field
code
}
}
}

invalid input data:

{
"input": {
"channel": "default-channel"
"email": "customer@example.com"
"lines": [{ "quantity": 1, "variantId": "UHJvZHVjdFZhcmlhbnQ6Mjk3" }]
"saveShippingAddress": true
}
}
warning

Any update to the address, even a partial change, resets the saveAddress flag to its default behavior. To ensure the correct setting is applied, explicitly provide the saveAddress value with each update.