【今日のひとこと】そろそろBFCMの足音が聞こえてきましたね… ご準備お疲れさまです!

【Shopify】ちょっとマニアックな Checkout (カゴ落ち) の話

EC サイトでは “商品をカートに入れたまま決済されずに放置される状態” を「カゴ落ち」と表現します。

そして Shopify には「カゴ落ちメール」という機能があります。

参考記事

 

今回 Shopify App 開発において、Shopify のカゴ落ちについて調べる機会があったのでまとめておきます。

Checkout が作成されるタイミング

Shopify では Checkout というリソースがカゴ落ちと対応しています。

ただし、 Checkout 自体は「購入手続き」そのものを指すため、決済されずに放置された状態もそうでないものも合わせて Checkout として扱われます。後述しますが、 Shopify Admin API では「カゴ落ち状態の購入手続き」のことを Abandoned checkouts という風に分けて表現されることもあります。

自分が確認した範囲では、 Checkout が作成されるタイミングは 2 種類存在します。

「ご購入手続きへ」をクリックした

ストアフロントにてショッピングカートから購入手続き画面へ遷移するタイミングで Checkout が作成されます。
カートに入れただけでは Checkout は作成されないようです。

ショッピングカートから購入手続き画面へ遷移するタイミングで Checkout は作成される

 

購入手続きの画面へ遷移すると URL に checkouts/75cfb11998bd728322b780c87f2183bc という表記が見えるかと思います。この 75cfb11998bd728322b780c87f2183bccheckout_token と呼ばれる値で、 Checkout を一意に表す値となっています。

 

購入手続き画面の URL に checkout token は表示されている

 

一方、 checkout_idCheckout を一意に表す値として存在するため、若干紛らわしい表現でもあります。

この checkout_token はカートの中身を変更してから再度購入手続き画面へ遷移しても変化することはありません。

「今すぐ購入」をクリックした

「今すぐ購入」は 動的チェックアウトボタン という機能で、商品詳細画面からカートをスキップして購入手続きに遷移する、という動きになります。ストアの設定によっては表示されていないケースもあります。

 

動的チェックアウトボタンからも Checkout は作成される

 

こちらは前述の「ご購入手続きへ」とは別の Checkout として扱われるようで、URL には先ほどとは異なる checkout_token が表示されます。

 

動的チェックアウトから作成された Checkout はカート画面から作成される Checkout とは別扱いとなる

Checkout が削除されるタイミング

これらの Checkout は購入手続きが完了すると削除されます。

ただし「カゴ落ちメール」に記載されたリンクから Customer が購入を完了した場合は completed_at という項目に購入完了日が記録され、 Checkout は削除されずに残ります。カゴ落ちメールの効果測定の際にはこの値を確認すると良さそうです。

completed_at
The date and time (ISO 8601 format) when the checkout was completed. For abandoned checkouts, this value is null until a customer completes the checkout using the recovery URL.

Abandoned checkouts

Shopify Admin API からカゴ落ちを確認する

Shopify Admin API には REST API と GraphQL の 2 種類が存在しますが、これを書いている 2021/10/20 時点で Checkout への参照は REST API でしか提供されていないようです。

前述の通り、 Checkout は「購入手続き」そのものを指すため、「カゴ落ち状態」を表す Abandoned checkouts と「購入手続き」を表す Checkouts でそれぞれ API が存在しています。

注意しなければいけないのは、それぞれの API で必要となる access scope が異なるという点です。

  • Abandoned checkouts
    • read_orders または write_orders が必要
  • Checkouts
    • read_checkouts または write_checkouts が必要

API のエンドポイントを見ると一見おなじ scope でアクセス出来そうな気がしてしまいます。

  • Abandoned checkouts
    • GET /admin/api/2021-07/checkouts.json
    • GET /admin/api/2021-07/checkouts/count.json
  • Checkouts
    • GET /admin/api/2021-07/checkouts/{token}.json
    • GET /admin/api/2021-07/checkouts/{token}/shipping_rates.json
    • POST /admin/api/2021-07/checkouts.json
    • POST /admin/api/2021-07/checkouts/{token}/complete.json
    • PUT /admin/api/2021-07/checkouts/{token}.json

Checkout ID を指定して「カゴ落ち」の Checkout を取得する

ここで勘の鋭い方はお気付きかもしれませんが、 Abandoned checkouts には ID や checkout_token を指定して個別に取得する API が存在しません。

  • GET /admin/api/2021-07/checkouts.json
    • 全てのカゴ落ちを取得する
  • GET /admin/api/2021-07/checkouts/count.json
    • カゴ落ちの件数を取得する

しかし工夫すれば任意の ID の Checkout を取得することが可能です。
GET /admin/api/2021-07/checkouts.json には以下のようなパラメータが指定できます。

limit ≤ 250 default 50
The maximum number of results to show.

since_id
Restrict results to after the specified ID.

Abandoned checkouts

limit は API から返す Checkout の件数、 since_id は指定した ID 以降の Checkout を取得するパラメータです。
前述の checkout_token は英数字 (16 進数) でしたが、 ID は数値なので、以下のようなプログラムを書けば任意の ID の Checkout を取得する事ができます。

2021/10/22 プログラムを一部修正しました

checkout_id = 1234567890

shop.with_shopify_session do
  ShopifyAPI::AbandonedCheckout
    .all(params: { since_id: checkout_id - 1, limit: 1 })
    .find { |checkout| checkout.id == checkout_id }
end

Shopify/shopify_api という gem を利用していますので、詳細はそちらをご参照下さい。

以上、Shopify のカゴ落ちについてのちょっとマニアックな話でした。何かのご参考になれば幸いです。