🌟

Shopifyで期間限定セールを行う方法を考察

2024/08/08に公開

はじめに

今回は、Shopify で期間限定セールを行う方法について考察してみました。

メタフィールドを利用する方法や、Shopify の Function を利用する方法等について調べました。

それでは、頑張っていきましょう。

期間限定販売の定義

まずは、期間限定販売の定義からです。

期間限定販売とは、特定の商品やコレクションを特定の期間内に限って販売することを意味します。例えば、季節限定の商品や、イベントに合わせた特別販売、キャンペーン商品などが該当します。この手法は、販売期間を制限することで、商品に希少価値を持たせ、顧客の購入意欲を引き出すことを目的としています。

期間限定販売のメリット

次に、期間限定販売を行うメリットについてです。

ある程度メリットが無いと、Shopify で期間限定販売を行う意味が無いですからね。

1. 購買意欲の喚起

期間限定販売は、顧客に対して「今買わなければ手に入らない」という緊急感を与えるため、購買意欲を高める効果があります。これにより、売上の短期的な向上が期待できます。

2. 在庫管理の効率化

特定の期間内での販売を計画することで、在庫管理がしやすくなります。期間限定商品の在庫を予め設定し、販売期間が終了したら販売を停止することで、在庫リスクを低減できます。

3. ブランドイメージの向上

限定商品や特別コレクションを提供することで、ブランドの独自性や魅力をアピールできます。これにより、顧客のブランドへのロイヤルティが向上し、長期的な顧客関係の構築に繋がります。

4. マーケティング効果の最大化

期間限定販売は、効果的なマーケティングキャンペーンと組み合わせることで、大きな宣伝効果を得ることができます。SNSやメールマーケティングを活用して、キャンペーンの告知や進捗を顧客に知らせることで、注目を集めることができます。

期間限定販売の実装方法

それではここから、期間限定販売の実装方法について考察していきます。

まずは、Shopify のドキュメントから確認しましょう。

Shopify には、Discount のFunction API があるので、まずはそのドキュメントから確認していきます。

About the Order Discount Function API

こちらの公式ドキュメントを参照しましょう。

https://shopify.dev/docs/api/functions/reference/order-discounts

About the Order Discount Function API
The Order Discount API enables you to create a new type of discount that is applied to all merchandise in the cart.
Example use casesAnchor link to section titled "Example use cases"
Money off the order subtotal. For example, $5 off the order subtotal.
Money off products on an order. For example, 20% off all products on the order.
Tiered discount by spend. For example, spend $100 get 10% off all products.

こちらのドキュメントにある通り、Order Discount Function APIは注文全体に対して割引を行う API です。こちらの API を期間限定で走るようにすれば、Shopify で期間限定セールが実装できそうですね。

以下のドキュメントにサンプルコードがあったので共有しておきます。
https://shopify.dev/docs/api/functions/reference/order-discounts/graphql

query Input {
  cart {
    lines {
      id
      merchandise {
        id
      }
    }
  }
}
{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/0",
        "merchandise": {
          "id": "gid://shopify/ProductVariant/0"
          }
      },
      {
        "id": "gid://shopify/CartLine/1",
        "merchandise": {
          "id": "gid://shopify/ProductVariant/1"
        }
      }
    ]
  }
}

こちらの Function の中で、割引金額は、商品や Discount のメタフィールドに持たせれば実装できそうです。

なので、後は dateTime をメタフィールドに持たせれば、実装できそうですよね。

Order Discount Function API の中で dateTime を使用する方法

それでは次に、Order Discount Function API の中で dateTime を使用する方法について考察していきましょう。

色々調べてみると、以下の Shopify 公式の GitHub リポジトリの Discussion に遭遇しました。

https://github.com/Shopify/function-examples/discussions/416

#215 shipped date and comparisons, but no dateTime. @nickwesselman mentioned this is due to function run caching.
We need (and others report needing) the current dateTime. Here's our use-case:
Merchant delivers local groceries and lets customers specify a delivery date before they get to checkout. This is set as a cart attribute as specifiedDeliveryDate.
Merchant needs to close off ordering the day before delivery at 8:00 pm local time to prep for deliveries the following day.
Merchant wants a checkout validation function that prevents checkout if the current time is after 8:00 pm the day before the specifiedDeliveryDate.
Actual behavior
There is no dateTime, only date, nor do any comparison functions work to compare the current dateTime to a variable. It currently only allows comparison to a metafield value, but we can't update a metafield value to be the 8:00 pm the day before the Cart attribute's specifiedDeliveryDate.
To solve my use-case, I did a workaround using a combination of date and timeAfter but had to hardcode the cutoff time. Eventually, we'll want to have different cutoff times per delivery day and doing a dynamic cutoff of hour granularity would get a bit hairy as you'd have to add 24 afterX... fields.
shop {
localTime {
date
after8pm: timeAfter(time: "20:00:00")
}
}
Expected behavior
Shopify adds a dateTime field to LocalTime that can be used in validations in a function run (e.g. compare it against a Cart attribute or Shop metafield that holds a hash like { "2024-01-04": "2024-01-03T20:00:00", ...}).

上記の通り、Shopify Function 内では現在の時刻(dateTime)を取得することができないようです。

Shopify Function 内で現在の時刻を取得できるように多くの要望が寄せられていますが、今のところ開発はされていないようです。

そのため、別の方法で実装する必要がありそうです。

次に、Order Discount API の GraphQL の reference を確認しましょう。

https://shopify.dev/docs/api/functions/reference/order-discounts/graphql

Order Discount API reference
The Order Discount API enables you to create a new type of discount that is applied to all merchandise in the cart.
Extension targetsAnchor link to section titled "Extension targets"
The Order Discount API exposes the following targets:
Target Output type Description
purchase.order-discount.run FunctionRunResult Outputs the order-level discount that should be applied to the cart
InputAnchor link to section titled "Input"
The RunInput object is the complete schema that your function can receive as input.
For a list of fields that the Order Discount API's Input object accepts, refer to Input.

こちらのリファレンスから、現在のdateTime を比較する方法について調べていきます。

以下のドキュメントを発見できました。

https://shopify.dev/docs/api/functions/reference/order-discounts/graphql/common-objects/localtime

上記のドキュメントの timeAfter や timeBefore を用いれば、現在の時刻と比較した boolean の値を取得できそうです。

ここまでで、Order Discount Function API を用いた方法についてはある程度目途が立ちましたね。

Order Discount Function APIを有効化した後に、商品のメタフィールドやディスカウントのメタフィールドを作成し、その値を timeAfter や timeBefore に渡すことで、Shopify で期間限定セールを実装することができそうです。

ディスカウントのメタフィールドに渡す値は、以下のようになるかと思います。

{
  "sale_start_datetime": date,
  "sale_end_datetime": date,
  "message": string,
  "discount_value": number
}

上記のメタフィールドをディスカウントの API に設定して、Order Discount Function APIを有効化して実行するだけで、割と簡単に Shopify で期間限定セールを実施できるかと思います。

ここまでで、注文に対する期間限定セールの実装方法が分かったので、次は商品毎の期間限定セールの実装方法について考察していきましょう。

商品毎の期間限定セールの実装方法について考察

それでは次に、商品毎に期間限定セールを行う方法について考察していきましょう。

今回は、以下の About the Product Discount Function APIを使用することになりそうです。

https://shopify.dev/docs/api/functions/reference/product-discounts

About the Product Discount Function API
The Product Discount API enables you to create a new type of discount that is applied to particular product variants or cart lines.
Example use casesAnchor link to section titled "Example use cases"
Money off a product. For example, 20% off shirts.
Money off a product variant. For example, $5 off blue shirts.
Money off a cart line. For example, 10% off products with a name engraving option.
Buy a specific quantity of a product for a specific amount. For example, $5 off up to 2 blue shirts.
Buy a specific amount of a product, get a second amount at a discount. For example, buy 4 shirts and get 2 blue shirts free.
Developer tools a

上記の文章にあるように、こちらの Function API は商品毎のディスカウントを行えそうです。

以下のドキュメントにサンプルコードがあったので、共有致します。
https://shopify.dev/docs/api/functions/reference/product-discounts/graphql

query Input {
  cart {
    lines {
      id
      attribute (key: "Engraving Name") {
        key
        value
      }
      merchandise {
        __typename
        ... on ProductVariant {
          id
        }
      }
    }
  }
}
{
  "cart": {
    "lines": [
      {
        "id": "gid://shopify/CartLine/0",
        "attribute": null,
        "merchandise": {
          "id": "gid://shopify/ProductVariant/1"
        }
      },
      {
        "id": "gid://shopify/CartLine/1",
        "attribute": {
          "key": "Engraving Name",
          "value": "Isabella Garcia"
        },
        "merchandise": {
          "id": "gid://shopify/ProductVariant/1"
        }
      },
      {
        "id": "gid://shopify/CartLine/2",
        "attribute": null,
        "merchandise": {
          "id": "gid://shopify/ProductVariant/2"
        }
      },
    ]
  }
}

この場合は、商品のメタフィールドに割引率を設定して、Discount Function を走らせることになりそうです。

timeAfter や timeBefore の使い方に関しては、Order Discount APIと同様の使い方になるので割愛します。

メタフィールドの設定方法についてですが、自分の確認したところ Shopify の管理画面からディスカウントのメタフィールドを編集することはできないので、以下のメタフィールドを更新する API を使用することになりそうです。

https://shopify.dev/docs/api/admin-graphql/2024-07/mutations/metafieldsSet

mutation MetafieldsSet($metafields: [MetafieldsSetInput!]!) {
  metafieldsSet(metafields: $metafields) {
    metafields {
      key
      namespace
      value
      createdAt
      updatedAt
    }
    userErrors {
      field
      message
      code
    }
  }
}

ここまでで、商品毎に期間限定セールを行う方法についての考察は終了です。

Shopify のカスタムアプリを使って Function API を実装すれば実現できそうですが、非エンジニアの方には難しいかと思うので、念のため Shopify アプリも紹介します。

アプリを使って期間限定セールを実現する方法

それでは次に、Shopify アプリを使って期間限定セールを実現する方法について考察します。

以下の記事が参考になりました。

https://unblog.unreact.jp/blog/xo1nfc-bm
https://qiita.com/eijiSaito/items/56176d376642596f3c88
https://unblog.unreact.jp/blog/shopify-timesale
https://unreact.jp/blog/shopify-timesale
https://unreact.jp/shopify-apps/sa-044-ur-limitedtimesale/guide

今回紹介する Shopify アプリは、シンプル期間限定セール|お手軽バーゲンセールです。

シンプル期間限定セール|お手軽バーゲンセールの機能

ここからは、シンプル期間限定セール|お手軽バーゲンセールの機能の紹介と、実装方法の考察になります。

https://apps.shopify.com/shopify-application-436?locale=ja

アプリの機能自体は非常にシンプルなので、サクッと紹介します。

こちらは、以下のような注文の自動ディスカウントを行うことで、Shopify で期間限定セールを実現しています。

恐らく、Order Discount Function APIを使って実装されているアプリだと思われます。

https://shopify.dev/docs/api/functions/reference/order-discounts

期間限定セールの開始日と終了日を設定することで、期間限定セールを実現しています。

恐らく、内部的にはディスカウントのメタフィールドに販売開始日時・販売終了日時を設定しているものと思われます。

また、割引条件は定額とパーセント割引の二種類から選べます。

https://shopify.dev/docs/api/functions/reference/order-discounts/graphql

恐らく、output.json の以下のtargetのオブジェクトで制御を行っているのでしょうね。

{
  "discountApplicationStrategy": "FIRST",
  "discounts": [
    {
      "value": {
        "percentage": {
          "value": "10.0"
        }
      },
      "targets": [
        {
          "orderSubtotal": {
            "excludedVariantIds": [
            ]
          }
        }
      ],
      "message": "10% off"
    }
  ]
}

非常にシンプルに使うことができるので、カスタムアプリを作成するのが難しい場合は選択肢の一つに入ってくるかと思います。

https://apps.shopify.com/shopify-application-436?locale=ja

最後に

ここまでで、カスタムアプリを作成して期間限定セールを作成する方法と、Shopify の期間限定セールアプリを用いて実装する方法の二つを解説しました。

お疲れさまでした。

Discussion