First interaction to order
This article covers a simple "happy path" from creating a session all the way to completing an order.
First interaction
When a shopper first interacts with the Direct to Consumer store, it is essential to identify the shopper's country based on their location, which will determine their default market, pricelist and language. Additionally, session and selection queries can be combined e.g. to support a mini cart. It is recommended to execute these two queries on each page to consistently keep the session and selection states up to date .
{
query {
session {
country {
code
name
isEU
}
countryState {
code
name
}
language {
code
name
default
}
market {
id
name
}
pricelist {
id
name
currency {
code
}
}
}
selection {
id
grandTotal {
formattedValue
}
#...
}
}
}
The response includes information about the current session state and a generated token extensions.token for subsequent queries to operate on the created session.
{
"data": {
"session": {
"country": {
"code": "SE",
"name": "Sweden",
"isEU": true
},
"countryState": null,
"language": {
"code": "en",
"name": "English",
"default": false
},
"market": {
"id": 1,
"name": "EU"
},
"pricelist": {
"id": 1,
"name": "SEK",
"currency": {
"code": "SEK"
}
}
}
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "3584630cde2b0b595a1622cf5d979016"
}
}
It’s possible to change the session country and language to apply to a different market and pricelist, or get shipping and payment widgets in the desired language. The following queries can be used to build switchers for that purpose:
Available countries
query {
countries(onlyShipTo: true) {
code
name
isEU
states {
code
name
}
}
}
Returns a list of countries that the store can ship to.
{
"data": {
"countries": [
{
"code": "SE",
"name": "Sweden",
"isEU": true,
"states": []
}
// ...
]
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "d47fabf8c91fc2eff073f78439bb25ac"
}
}
If countries are not filtered by onlyShipTo: true, the API returns all countries, even those that are not available for shipping. In case such a country is selected and set on selection, browsing products and adding them to the selection remains possible. However, at the checkout stage that selection cannot be completed.
Set country and state
mutation {
setCountryState(countryCode: "US", stateCode: "AL") {
userErrors {
message
path
}
}
}
This mutation updates the country and state on both the session and the selection.
Available languages
query {
languages {
name
code
default
}
}
Returns a list of available languages.
{
"data": {
"languages": [
{
"name": "English",
"code": "en",
"default": true
},
{
"name": "Swedish",
"code": "sv",
"default": false
},
...
]
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "d7cb10381d339dba10e2c02d1e5a6b9e"
}
}
Set language
mutation {
setLanguage(code: "sv") {
session {
language {
code
name
default
}
}
}
}
The setLanguage mutation updates the language on the session and returns the current session state.
{
"data": {
"setLanguage": {
"session": {
"language": {
"code": "sv",
"name": "Swedish",
"default": false
}
}
}
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "be2f73a4f5bf2cb40e9e00f7d1d7a7ef"
}
}
Browse products
The displayItems query is the main way to get a list of all available products (remember, products in the webshop API are variants activated on store displays). This versatile query accommodates both products and bundles, offering functionalities to search, filter, sort, and paginate DisplayItems.
query {
displayItems(
limit: 20
page: 1
where: { filters: [{ key: "collections", values: ["1"] }] }
sort: [{ key: PRICE, order: ASC }]
)
}
Use the displayItem query to fetch detailed information about a product.
query {
displayItem(id: 1) {
id
#...
}
}
Along with all other fields, it includes IDs needed to add the product to the selection.
{
"data": {
"displayItem": {
"id": 1,
"items": [
{
"id": "1-1"
}
],
"bundle": {
"id": 2,
"sections": [
{
"items": [
{
"items": [
{
"id": "2-1"
}
]
},
{
"items": [
{
"id": "2-2"
}
]
}
]
},
{
"items": [
{
"items": [
{
"id": "3-1"
}
]
}
]
}
]
}
}
},
"extensions": {
"traceId": "a374844cf5a0afcbc348039292d65abc"
}
}
Add products to selection
After the shopper has chosen a product and size, a DisplayItem can be added to the selection. The mutation varies based on the product type, offering two options:
Product or fixed bundle
mutation {
addItem(item: "1-1", quantity: 2) {
selection {
lines {
id
quantity
item {
id
}
}
}
}
}
Flexible bundle
mutation {
addFlexibleBundle(
item: "1-1"
quantity: 2
sections: [{ sectionId: 1, item: "2-2" }, { sectionId: 2, item: "3-1" }]
) {
selection {
lines {
id
quantity
item {
id
}
}
}
}
}
For an item, use the string taken from DisplayItem.items.id.
For a section item in flexible bundles, use the string from DisplayItem.bundle.sections.items.items.id.
Each DisplayItem added to a selection becomes a selection line under selection.lines with a unique ID. The uniqueness of the ID allows for tracking and managing individual selection lines. The same product can appear as multiple lines if it has different comments or voucher-modified prices.
{
"data": {
"addItem": {
"selection": {
"lines": [
{
"id": "38dd369a199561f6a62f60b0badf092a",
"quantity": 6,
"item": {
"id": "1-1"
}
}
]
}
}
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "d47fabf8c91fc2eff073f78439bb25ac"
}
}
If a product already exists, calling addItem increases its quantity in the selection. This is particularly useful when shoppers decide to add more units of a product already in their selection.
Update line
Modify any line within a selection by updating its quantity, adding comments, or specifying a subscription plan.
mutation {
updateLine(
lineId: "38dd369a199561f6a62f60b0badf092a"
quantity: 1
subscriptionPlanId: 1
comment: ""
)
}
Delete line
Deletion of any line within a selection can be accomplished through two distinct methods:
Dedicated mutation:
mutation {
deleteLine(lineId: "38dd369a199561f6a62f60b0badf092a") {
selection {
lines {
id
}
}
}
}
Updating a line with quantity 0
mutation {
updateLine(lineId: "38dd369a199561f6a62f60b0badf092a", quantity: 0) {
selection {
lines {
id
}
}
}
}
The response for the following query represents the current selection state.
{
"data": {
"deleteLine": {
"selection": {
"lines": []
}
}
},
"extensions": {
"token": "0031ca7f-b068-4558-97e2-227a76ff80e7",
"traceId": "ed10aa16c82549c37e65507c181b72e1"
}
}
Both mutations behave identically, so choose whichever you prefer.
Get selection
Any selection mutation responds with selection data to keep you updated on the current selection state. However, it's still possible to retrieve the selection anytime it's needed, for example, to display a mini cart.
query {
selection {
id
lines {
id
item {
id
name
}
quantity
price {
value {
formattedValue
}
}
}
grandTotal {
formattedValue
}
#...
}
}
Checkout
When a shopper proceeds to checkout, it's time to set an address and display the full selection state including totals and taxes. Shipping and payment methods are pre-selected by default, however it’s possible to change them using separate mutations. Include the selection.checkout field in your query to obtain the data necessary for the checkout process.
query {
selection {
checkout {
totals {
type
price {
formattedValue
}
... on SelectionTotalTaxRow {
taxPercent
}
}
shippingMethods {
id
name
}
paymentMethods {
id
name
}
shippingAddress {
firstName
lastName
address1
address2
city
zipCode
stateOrProvince
cellPhoneNumber
faxNumber
email
companyName
attention
vatNumber
country {
name
code
}
state {
name
code
}
}
addressFields {
shippingAddress {
key
visible
required
}
separateBillingAddress {
key
visible
required
}
newsletter {
key
visible
required
}
termsAndConditions {
key
visible
required
}
}
#...
}
}
}
Once the shopper enters an address, use the setAddress mutation to update the address on a selection:
mutation {
setAddress (shippingAddress: AddressInput!, separateBillingAddress: AddressInput)
}
After setting the address, shipping and payment methods can be updated. All available ones can be found under selection.checkout.shippingMethods and selection.checkout.paymentMethods. To update them on a selection, use the following two mutations:
mutation {
setShippingMethod(id: 1)
setPaymentMethod(id: 1)
}
Payment
After the shopper has reviewed order totals, supplied an address, and chosen shipping and payment methods, initiate the payment process with the paymentInstructions mutation call. (see API docs for PaymentInstructionsInput)
mutation {
paymentInstructions (input: PaymentInstructionsInput!) {
action {
action
... on FormPaymentAction {
html
formFields
formType
}
... on JavascriptPaymentAction {
formFields
formType
script
}
... on RedirectPaymentAction {
url
}
... on SuccessPaymentAction {
order {
number
#...
}
}
}
userErrors {
path
message
}
}
}
There are several possible options for handling PaymentActionType:
| PaymentActionType | Description |
|---|---|
| FORM | Render FormPaymentAction.html |
| JAVASCRIPT | Execute JavascriptPaymentAction.script |
| REDIRECT | Redirect shopper to RedirectPaymentAction.url |
| SUCCESS | Order has already been finalized |
Upon completion of the payment process and the shopper’s redirection to the paymentReturnPage, execute the paymentResult mutation to finalize the transaction.
mutation {
paymentResult(
paymentMethodFields: "json-encoded map of fields from GET and POST data"
) {
userErrors {
path
message
}
type
... on PaymentResultSuccessPayload {
order {
id
#...
}
}
... on PaymentResultFailedPayload {
selection {
id
#...
}
}
}
}
Include all POST and GET variables as paymentMethodFields for verification and order finalization. Upon a successful payment result call, access order details in the response under PaymentResultSuccessPayload.order. If the chosen payment method supports a payment receipt, it can be retrieved from PaymentResultSuccessPayload.order.paymentHtml.
Ensure to consistently incorporate and address userErrors in mutations wherever they are provided, to facilitate effective error handling and enhance the overall robustness of your API integration.