Sell through the Checkout API

The Checkout API makes it possible to purchase products from a Shopify store programmatically. A checkout in Shopify is the object used to manage a customer’s cart as it transitions to a paid checkout. This includes calculating taxes, shipping rates, attaching the customer’s information, and finally completing a purchase by submitting a payment. Use this API if you want a fully customized checkout user experience, while taking full advantage of the commerce engine used to power every Shopify store.

Caution

The Checkout API is only for use with the Sales Channel SDK. It is not possible to use it to create a new checkout for an individual store — for that you can use our JavaScript, iOS, and Android Buy SDKs.

How it works

Using a series of API calls, your platform can create a checkout, and update it a few times to programatically execute Shopify's checkout process, pictured below:

Checkout api flow

Authentication

Authentication for the Checkout API is performed via OAuth. All requests to this API must include the permanent access token in an X-Shopify-Access-Token request header. For more information, please read the OAuth Documentation

POST /api/checkouts.json HTTP/1.1
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Host: channelsrule.myshopify.com
Content-Type: application/json

Protocol and hostname

The Checkout API is accessible via the store’s {subdomain}.myshopify.com or the store’s primary domain using https only.

Reservation

Reservations are done on a per-checkout basis. For the duration of the reservation, the line items in the checkout will be reserved for the given checkout. Upon creating a checkout, the default and maximum reservation time is 300 seconds (five minutes.) The reservation can be manually set during creation and extended when editing a checkout using the attribute reservation_time which represents the amount of seconds to reserve the items for. A checkout can still be completed when the reservation has expired, but in the event that a line item is no longer available the call to /payments.json will fail.

Creating a checkout

In order for a customer to be able to purchase a desired product variant, a checkout must be created. The checkout can be updated partially at anytime with the information provided by the customer.

The checkout provides information like tax lines, shipping costs, shipping requirements and more. You can display this to the customer and use it to complete other checkout requirements like updating the shipping rate that the customer chooses.

Example request to create a checkout

POST /api/checkouts.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "checkout":{
    "email": "john.smith@example.com",
    "line_items": [{
      "variant_id": 11184583431,
      "quantity": 1
    }],
    "shipping_address": {
      "first_name": "John",
      "last_name": "Smith",
      "address1": "126 York St.",
      "city": "Ottawa",
      "province_code": "ON",
      "country_code": "CA",
      "phone": "(123)456-7890",
      "zip": "K1N 5T5"
    }
  }
}

View Response

HTTP/1.1 201 Created
Content-Type: application/json; charset=utf-8

{
  "checkout":{
    "created_at":"2016-03-18T13:21:39-04:00",
    "currency":"CAD",
    "customer_id":2475498631,
    "email":"john.smith@example.com",
    "location_id":null,
    "order_id":null,
    "requires_shipping":true,
    "reservation_time":300,
    "source_name":"1257344",
    "source_identifier":null,
    "source_url":null,
    "taxes_included":false,
    "token":"f9604c3f13b35c7ba36932436310ef09",
    "updated_at":"2016-03-18T13:21:39-04:00",
    "payment_due":"28.25",
    "payment_url":"https:\/\/elb.deposit.shopifycs.com\/sessions",
    "reservation_time_left":300,
    "subtotal_price":"25.00",
    "total_price":"28.25",
    "total_tax":"3.25",
    "attributes":[],
    "note":"",
    "order":null,
    "order_status_url":null,
    "privacy_policy_url":"https:\/\/checkout.shopify.com\/10890068\/policies\/16561415.html",
    "available_shipping_rates":[
      {
        "id":"shopify-Standard%20Shipping-8.00",
        "price":"8.00",
        "title":"Standard Shipping",
        "checkout":{
          "total_tax":"3.25",
          "total_price":"36.25",
          "subtotal_price":"25.00"
        },
        "phone_required":false,
        "delivery_range":null
      }
    ],
    "refund_policy_url":"https:\/\/checkout.shopify.com\/10890068\/policies\/16561351.html",
    "terms_of_service_url":"https:\/\/checkout.shopify.com\/10890068\/policies\/16561479.html",
    "user_id":null,
    "web_url":"https:\/\/checkout.shopify.com\/10890068\/checkouts\/f9604c3f13b35c7ba36932436310ef09",
    "tax_lines":[
      {
        "price":"3.25",
        "rate":0.13,
        "title":"HST"
      }
    ],
    "payments": []
    "line_items":[
      {
        "id":"5a022a40c46d1e19",
        "key":"5a022a40c46d1e19",
        "product_id":3669728775,
        "variant_id":11184596679,
        "sku":"RUBY-001",
        "vendor":"channelsrule",
        "title":"Ruby Girls Tee",
        "variant_title":"small",
        "taxable":true,
        "requires_shipping":true,
        "price":"25.00",
        "compare_at_price":"30.00",
        "line_price":"25.00",
        "properties":{

        },
        "quantity":1,
        "grams":200,
        "fulfillment_service":"manual",
        "applied_discounts":[

        ]
      }
    ],
    "gift_cards":[

    ],
    "shipping_rate":null,
    "shipping_address":{
      "id":3763006023,
      "first_name":"John",
      "last_name":"Smith",
      "phone":"(123)456-7890",
      "company":null,
      "address1":"126 York St.",
      "address2":null,
      "city":"Ottawa",
      "province":"Ontario",
      "province_code":"ON",
      "country":"Canada",
      "country_code":"CA",
      "zip":"K1N 5T5"
    },
    "credit_card":null,
    "billing_address":null,
    "discount":null
  }
}

Updating a checkout

During the whole checkout process, it’s possible to update the checkout with the data received from the customer. A validation, specific only to the fields that have changed, will be provided so you can give feedback to the customer that is updating their information. This is especially useful to assign the shipping rates, add line items, add gift cards, and so on.

Example request to update the line items

PATCH /api/checkouts/0aff29a2c5ab826fe623ebf8588617b3.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "checkout":{
    "line_items": [
      {
        "variant_id": 11184583431,
        "quantity": 1
      },
      {
        "variant_id": 11184596679,
        "quantity": 1
      }
    ],
    "shipping_rate": {
      "id": "shopify-Standard%20Shipping-8.00"
    }
  }
}

View Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "checkout":{
    ...
    "line_items":[
      {
        "id":"d4afb7b2a7668ec7",
        "key":"d4afb7b2a7668ec7",
        "product_id":3669721031,
        "variant_id":11184583431,
        "sku":"HOOT-001",
        "vendor":"channelsrule",
        "title":"Graphic Owl Guys Tee",
        "variant_title":"small",
        "taxable":true,
        "requires_shipping":true,
        "price":"25.00",
        "compare_at_price":"30.00",
        "line_price":"25.00",
        "properties":{},
        "quantity":1,
        "grams":200,
        "fulfillment_service":"manual",
        "applied_discounts":[

        ]
      },
      {
        "id":"e01a627d3f611bdc",
        "key":"e01a627d3f611bdc",
        "product_id":3669728775,
        "variant_id":11184596679,
        "sku":"RUBY-001",
        "vendor":"channelsrule",
        "title":"Ruby Girls Tee",
        "variant_title":"small",
        "taxable":true,
        "requires_shipping":true,
        "price":"25.00",
        "compare_at_price":"30.00",
        "line_price":"25.00",
        "properties":{},
        "quantity":1,
        "grams":200,
        "fulfillment_service":"manual",
        "applied_discounts":[]
      }
    ],
    ...
  }
}

Example request to update the shipping rate

PATCH /api/checkouts/0aff29a2c5ab826fe623ebf8588617b3.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "checkout":{
    "shipping_rate": {
      "id": "shopify-Standard%20Shipping-8.00"
    }
  }
}

View Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "checkout": {
    ...
    "available_shipping_rates":[
      {
        "id":"shopify-Standard%20Shipping-8.00",
        "price":"8.00",
        "title":"Standard Shipping",
        "checkout":{
          "total_tax":"6.50",
          "total_price":"64.50",
          "subtotal_price":"50.00"
        },
        "phone_required":false,
        "delivery_range":null
      }
    ],
    "shipping_rate":{
      "id":"shopify-Standard%20Shipping-8.00",
      "price":"8.00",
      "title":"Standard Shipping"
    }
    ...
  }
}

Card vaulting

To ensure customer confidentiality, we process transactions on credit cards by relying on a separate card vaulting endpoint. It's a two step process where the credit card is submitted to the vault, the vault returns a payment session_id that can be used to create a payment from that credit card.

For more information, please read the Card Vault Documentation

Example request to vault a credit card

POST /sessions HTTP/1.1
Host: https://elb.deposit.shopifycs.com
Content-Type: application/json
Accept: application/json

{
  "credit_card":{
    "number": "1",
    "month": "12",
    "year": "2019",
    "verification_value": "123",
    "first_name":"John",
    "last_name":"Smith"
  }
}

View Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "id":"east-44a400ef20b36e38f10b882cb7260796"
}

Completing the purchase

In order to complete the purchase, a payment must be created using the session_id created in the previous step. The payment will always cover the total price of the checkout and will broker the transaction synchronously.

POST /api/checkouts/0aff29a2c5ab826fe623ebf8588617b3/payments.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "payment": {
    "source": {
      "session_id": "east-44a400ef20b36e38f10b882cb7260796"
    }
  }
}

View Response

HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8

{
  "checkout":{
    "order":{
      "id":2717309319,
      "name":"#1025",
      "status_url":"https:\/\/checkout.shopify.com\/10890068\/checkouts\/f9604c3f13b35c7ba36932436310ef09\/thank_you"
    },
    "payments":[
      {
        "amount":"64.50",
        "amount_in":null,
        "amount_out":null,
        "amount_rounding":null,
        "authorization":"53433",
        "created_at":"2016-03-18T13:50:08-04:00",
        "currency":"CAD",
        "error_code":null,
        "gateway":"bogus",
        "id":2907189703,
        "kind":"authorization",
        "message":"Bogus Gateway: Forced success",
        "status":"success",
        "test":true
      }
    ],
    "credit_card":{
      "first_name":"John",
      "last_name":"Smith",
      "first_digits":"1",
      "last_digits":"1",
      "expiry_month":12,
      "expiry_year":2019
    }
    ...
  }
}

Handling errors

Validation errors

PATCH /api/checkouts/0aff29a2c5ab826fe623ebf8588617b3.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "checkout": {
    "email": "not a valid email"
  }
}

View Response

HTTP/1.1 422 OK
Content-Type: application/json; charset=utf-8

{
  "errors":  {
    "checkout":  {
      "email": [{"code": "invalid", "message": "is invalid", "options": {}}],
    }
  }
}

For a list of elements, the errors will be index based. For example, when there is an error only on the second line item, the errors will be on the second element in the list.

PATCH /api/checkouts/0aff29a2c5ab826fe623ebf8588617b3.json HTTP/1.1
Host: channelsrule.myshopify.com
X-Shopify-Access-Token: d833234ea788000e7aba6af8b1b9a282
Content-Type: application/json

{
  "checkout":{
    "line_items": [
      {
        "variant_id": 11184583431,
        "quantity": 1
      },
      {
        "variant_id": 11184596679,
        "quantity": 255
      }
    ]
  }
}

View Response

HTTP/1.1 422 OK
Content-Type: application/json; charset=utf-8

{
  "errors": {
    "checkout": {
      "line_items": [
        null,
        {
          "quantity": [{
            "code": "not_enough_in_stock",
            "message": "Not enough items available. Only 30 left.",
            "options": {
            "remaining": 30
          }
        }]
      }]
    }
  }
}

Handling connection errors and retries

Network connection and mobile devices are not always stable. Hence, to ensure the payment is received correctly, a request can be made at any time to retrieve the checkout object. That request will be deferred until the transaction succeeds or fails.