End-to-End Guide: Headless checkout flow with the GraphQL Storefront API

The BigCommerce GraphQL Storefront API lets server-side and browser-side clients manage product, cart, and checkout objects to build storefront features. The GraphQL Storefront API can solve the same use cases as our REST Management API’s cart and checkout features, but makes it easier to build headless storefront applications. Developers using the GraphQL Storefront API can spend less time focusing on API interactions and more time building the shopper experience.

This end-to-end guide describes how to work with shopper interactions on headless storefronts. These steps let you build shopping experiences where the purchase funnel is mainly powered by the GraphQL Storefront API, from catalog browsing through checkout. The examples walk you through critical capabilities that fit many headless use cases.

You can use the GraphQL Storefront API playground to run the example queries in this guide. To access your store’s GraphQL Storefront API playground, sign in to your store, and navigate to Settings > API > Storefront API Playground.

Prerequisites

To complete the guide, you need the following:

Accessing the GraphQL Storefront API

You can make requests to the GraphQL Storefront API in a server-to-server context. This guide describes creating and using a customer access token to authenticate and use the GraphQL Storefront API.

Create a customer access token

A customer access token is unique to an individual user’s account. To generate a customer access token, enter your GraphQL variables (user email and password) and run the login mutation.

GraphQL variables
1{
2 "email": "user@email.com",
3 "pass": "password"
4}
Create a customer access token
1# Create a customer access token
2POST https:{{storeDomain}}/graphql
3Authorization: Bearer {{STOREFRONT_TOKEN}}
4Accept: application/json
5Content-Type: application/json
6
7mutation Login($email: String!, $pass: String!) {
8 login(email: $email, password: $pass) {
9 result
10 customer {
11 entityId
12 email
13 }
14 customerAccessToken {
15 value
16 expiresAt
17 }
18}
19}

In a tool like Postman or Altair, add the customer access token to the Headers tab as follows. For more information, see Using a Customer Access Token.

Authorization header with customer access token
{
"X-Bc-Customer-Access-Token": "{{customer access token}}",
"Authorization": "Bearer {{STOREFRONT_TOKEN}}"
}

Querying product data

The GraphQL Storefront API lets you retrieve product data from a store. The following example demonstrates how to query a simple product using the GraphQL Storefront API. Pricing and visibility response values can vary based on the customer. For more information and examples, see the Guide to working with products.

When possible, use the following best practices for queries to the GraphQL Storefront API.

  • Query fewer than 50 resources at a time.
  • Limit query complexity.
  • Limit pagination.
  • Employ security practices and limit scope.
  • Cache data to avoid repeat fetching of data that hasn’t changed.
Get a product
1GET https://store.example.com/graphql
2Authorization: Bearer {{STOREFRONT_TOKEN}}
3Accept: application/json
4X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
5
6# This query retrieves one product.
7query SingleProduct ($entityId: Int) {
8 site {
9 product(entityId: $entityId) {
10 id
11 entityId
12 name
13 sku
14 description
15 prices {
16 price {
17 value
18 currencyCode
19 }
20 }
21 }
22 }
23}

Creating a cart

BigCommerce’s GraphQL Storefront API provides the same cart and checkout objects as the REST Storefront API. Pricing and visibility response values can vary based on the customer. The following example shows how to create a new cart by adding a simple product.

Make note of one of the cart’s entityId displayed in the response. You will need to use it in later steps.

Create a cart (simple)
1POST https://store.example.com/graphql
2Accept: application/json
3Authorization: Bearer {{STOREFRONT_TOKEN}}
4X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
5
6# Creates a new cart, adding a simple product.
7
8mutation createCartSimple($createCartInput: CreateCartInput!) {
9 cart {
10 createCart(input: $createCartInput) {
11 cart {
12 entityId
13 lineItems {
14 physicalItems {
15 name
16 quantity
17 }
18 digitalItems {
19 name
20 quantity
21 }
22 giftCertificates {
23 name
24 }
25 customItems {
26 name
27 quantity
28 }
29 }
30 }
31 }
32 }
33}

Add cart line items

To add a new line item to the existing cart, add the cart ID to the input variables or the mutation will fail.

Add cart line items
1 POST https://store.example.com/graphql
2 Authorization: Bearer {{STOREFRONT_TOKEN}}
3 X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5 mutation addCartLineItems($addCartLineItemsInput: AddCartLineItemsInput!) {
6 cart {
7 addCartLineItems(input: $addCartLineItemsInput) {
8 cart {
9 entityId
10 }
11 }
12 }
13 }

Get a checkout

The following query example shows how to display the contents of a checkout.

You can access cart and checkout details in the same request as other information. The cart ID is the same as a checkout ID.

Get checkout
1GET https://store.example.com/graphql
2Authorization: Bearer {{STOREFRONT_TOKEN}}
3X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5query getCheckout($entityId: Int) {
6 site {
7 checkout(entityId: $entityId) {
8 entityId
9 billingAddress {
10 ...CheckoutBillingAddressFields
11 }
12 shippingConsignments {
13 ...CheckoutShippingConsignmentFields
14 }
15 order {
16 entityId
17 }
18 shippingCostTotal {
19 ...MoneyFields
20 }
21 giftWrappingCostTotal {
22 ...MoneyFields
23 }
24 handlingCostTotal {
25 ...MoneyFields
26 }
27 taxTotal {
28 ...MoneyFields
29 }
30 taxes {
31 ...CheckoutTaxFields
32 }
33 subtotal {
34 ...MoneyFields
35 }
36 grandTotal {
37 ...MoneyFields
38 }
39 createdAt {
40 utc
41 }
42 updatedAt {
43 utc
44 }
45 customerMessage
46 outstandingBalance {
47 ...MoneyFields
48 }
49 coupons {
50 ...CheckoutCouponFields
51 }
52 promotions {
53 ...CheckoutPromotionFields
54 }
55 }
56 }
57}
58
59fragment CheckoutConsignmentAddressFields on CheckoutConsignmentAddress {
60 ...CheckoutAddressFields
61}
62
63fragment CheckoutBillingAddressFields on CheckoutBillingAddress {
64 entityId
65 ...CheckoutAddressFields
66}
67
68fragment CheckoutAddressFields on CheckoutAddress {
69 firstName
70 lastName
71 email
72 company
73 address1
74 address2
75 city
76 stateOrProvince
77 stateOrProvinceCode
78 countryCode
79 postalCode
80 phone
81 customFields {
82 entityId
83 ... on CheckoutAddressCheckboxesCustomField {
84 valueEntityIds
85 }
86 ... on CheckoutAddressDateCustomField {
87 date {
88 utc
89 }
90 }
91 ... on CheckoutAddressMultipleChoiceCustomField {
92 valueEntityId
93 }
94 ... on CheckoutAddressNumberCustomField {
95 number
96 }
97 ... on CheckoutAddressPasswordCustomField {
98 password
99 }
100 ... on CheckoutAddressTextFieldCustomField {
101 text
102 }
103 }
104}
105
106fragment CheckoutShippingConsignmentFields on CheckoutShippingConsignment {
107 entityId
108 address {
109 ...CheckoutConsignmentAddressFields
110 }
111 availableShippingOptions {
112 ...CheckoutAvailableShippingOptionFields
113 }
114 selectedShippingOption {
115 ...CheckoutSelectedShippingOptionFields
116 }
117 coupons {
118 ...CheckoutCouponFields
119 }
120 shippingCost {
121 ...MoneyFields
122 }
123 handlingCost {
124 ...MoneyFields
125 }
126 lineItemIds
127}
128
129fragment CheckoutAvailableShippingOptionFields on CheckoutAvailableShippingOption {
130 entityId
131 description
132 type
133 imageUrl
134 cost {
135 ...MoneyFields
136 }
137 transitTime
138 isRecommended
139}
140
141fragment CheckoutSelectedShippingOptionFields on CheckoutSelectedShippingOption {
142 entityId
143 description
144 type
145 imageUrl
146 cost {
147 ...MoneyFields
148 }
149 transitTime
150}
151
152fragment MoneyFields on Money {
153 value
154 currencyCode
155}
156
157fragment CheckoutCouponFields on CheckoutCoupon {
158 entityId
159 code
160 couponType
161 discountedAmount {
162 ...MoneyFields
163 }
164}
165
166fragment CheckoutTaxFields on CheckoutTax {
167 name
168 amount {
169 ...MoneyFields
170 }
171}
172
173fragment CheckoutPromotionFields on CheckoutPromotion {
174 banners {
175 entityId
176 type
177 locations
178 text
179 }
180}

Add a checkout billing address

This mutation adds a billing address to an existing checkout.

Add a checkout billing address
1 POST https://store.example.com/graphql
2 Authorization: Bearer {{STOREFRONT_TOKEN}}
3 X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5 mutation addCheckoutBillingAddress($addCheckoutBillingAddressInput: AddCheckoutBillingAddressInput!) {
6 checkout {
7 addCheckoutBillingAddress(input: $addCheckoutBillingAddressInput) {
8 checkout {
9 entityId
10 }
11 }
12 }
13 }

Add a checkout shipping consignment

This mutation adds a shipping consignment to an existing checkout.

Make a note of a shipping consignment’s entityId and the desired shipping option’s entityId returned from your request. You will need to use these in later steps.

Add a checkout shipping consignment
1POST https://store.example.com/graphql
2Authorization: Bearer {{STOREFRONT_TOKEN}}
3X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5mutation addCheckoutShippingConsignments($addCheckoutShippingConsignmentsInput: AddCheckoutShippingConsignmentsInput!) {
6 checkout {
7 addCheckoutShippingConsignments(input: $addCheckoutShippingConsignmentsInput) {
8 checkout {
9 entityId
10 shippingConsignments {
11 entityId
12 availableShippingOptions {
13 entityId
14 }
15 selectedShippingOption {
16 entityId
17 }
18 }
19 }
20 }
21 }
22}

Select checkout shipping option

This mutation adds a selected shipping to an existing checkout.

Select checkout shipping option
1POST https://store.example.com/graphql
2Authorization: Bearer {{STOREFRONT_TOKEN}}
3X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5mutation selectCheckoutShippingOption($selectCheckoutShippingOptionInput: SelectCheckoutShippingOptionInput!) {
6 checkout {
7 selectCheckoutShippingOption(input: $selectCheckoutShippingOptionInput) {
8 checkout {
9 entityId
10 }
11 }
12 }
13 }

Complete checkout

Completing a checkout creates an incomplete order until you process the payment. For PCI compliance-related reasons, the GraphQL Storefront API does not handle payments. You must use the Payments API to process payments. The payments workflow includes the following three steps:

  1. Fetch available payment methods
  2. Create a payment access token by either requesting one with the following mutation or using the REST Payments API
  3. Capture payment
Complete checkout
1 POST https://store.example.com/graphql
2 Authorization: Bearer {{STOREFRONT_TOKEN}}
3 X-Bc-Customer-Access-Token: {{CUSTOMER_ACCESS_TOKEN}}
4
5 mutation completeCheckout($completeCheckoutInput: CompleteCheckoutInput!) {
6 checkout {
7 completeCheckout(input:$completeCheckoutInput) {
8 orderEntityId
9 paymentAccessToken
10 }
11 }
12 }

Resources

GraphQL Storefront API

REST Management API