SHARE
  1. Top
  2. ブログ一覧
  3. 特定のニーズに合わせたディスカウントをShopify Discount Functionで実現する
Eコマース

特定のニーズに合わせたディスカウントをShopify Discount Functionで実現する

公開日

2024.12.30

更新日

2024.12.30

SHARE
特定のニーズに合わせたディスカウントをShopify Discount Functionで実現するのサムネイル

Shopifyには標準でディスカウントコードを設定する機能があります。例えば、商品割引や注文割引、送料割引が設定できます。最近では「Xを買うとYをプレゼント」といったニーズにも対応できるようになりました。しかし、Shopifyのディスカウント機能は、特定のニッチなニーズまで柔軟に対応することが難しい場合があります。
そこで、Shopify Discount Functionを使って、特定のニーズに合わせたディスカウントを実現する方法を解説します。

Shopify Discount Functionとは

Shopify discount extensionとは、Shopify Functionsを使ってカスタムの割引ロジックを実装できる拡張機能です。通常のディスカウントコード設定ではできない、細かい購入条件や顧客属性などに基づく割引の適用を実現できる点が大きな特徴です。

具体的には、Shopifyのチェックアウト時にバックエンドロジックを挟み込み、カート内容(商品や数量、価格など)を動的に検証して割引を計算・適用します。たとえば「特定の商品タイプを◯点以上購入した場合のみ割引」「会員ランクがゴールド以上の顧客だけ追加の割引を適用」など、標準機能だけでは実現しづらい高度な割引設定を構築可能です。

Shopify Discount Functionの設定方法

今回は、特定の異なる商品タイプを購入した場合に割引を適用する例を紹介します。4月の引越しシーズンであれば、「家具」と「家電」の商品タイプを同時に購入すると、10%の割引を適用するというシチュエーションで実装してみましょう。

extensionの作成

Shopify Discount Functionうちの Order Discount Functionを作成します。以下のコードを実行して、新しいFunctionを作成します。

shopify app generate extension --template order_discounts --name order-discount --flavor typescript  

これで、extensions/order-discount ディレクトリが作成され、Functionの雛形が生成されます。

入力データの定義

Functionが実行される際の注文データの入力データを定義します。作成したextensionのsrc/run.graphqlを編集して、入力データの定義を追加します。

query RunInput {
  cart {
    lines {
      merchandise {
        ... on ProductVariant {
          product {
            productType
          }
        }
      }
    }
  }
}

このようにカートの中に入っている商品アイテムの商品タイプを取得するようにgraphQLのフィールドを定義します。

編集後、extensinsionディレクトリで以下のコマンドを実行して、入力データの定義を反映します。

cd extensions/order-discount

shopify app function typegen

これで、入力データをtypescriptの型定義として生成することができます。

ロジックの実装

Functionのロジックを実装します。src/run.tsを編集して、カート内の商品タイプをチェックして割引を適用するロジックを実装します。

import type {
  RunInput,
  FunctionRunResult,
  ProductVariant,
} from "../generated/api";
import { DiscountApplicationStrategy } from "../generated/api";

// 定数定義
const EMPTY_DISCOUNT: FunctionRunResult = {
  discountApplicationStrategy: DiscountApplicationStrategy.First,
  discounts: [],
};

const DISCOUNT_PERCENTAGE = 10;
const DISCOUNT_TARGET_PRODUCT_TYPES = ["家具", "家電"];
const DISCOUNT_MESSAGE = "春の一人暮らしキャンペーンです。新しい生活を応援します!";

// 割引ロジックを関数化
function createDiscount(): FunctionRunResult {
  return {
    discountApplicationStrategy: DiscountApplicationStrategy.First,
    discounts: [
      {
        message: DISCOUNT_MESSAGE,
        targets: [
          {
            orderSubtotal: { // カートの合計金額に対する割引
              excludedVariantIds: [], // 除外する商品はなし
            },
          },
        ],
        value: {
          percentage: {
            value: DISCOUNT_PERCENTAGE,
          },
        },
      },
    ],
  };
}

// メインの関数
export function run(input: RunInput): FunctionRunResult {
  // カート内の商品タイプを抽出
  const productTypes = input.cart.lines.map(
    (line) => (line.merchandise as ProductVariant).product.productType,
  );

  // 割引対象のすべてのタイプがカート内に含まれているか確認
  const isDiscountTarget = DISCOUNT_TARGET_PRODUCT_TYPES.every((target) =>
    productTypes.includes(target),
  );

  // 割引対象の場合は割引を適用、それ以外は空の割引を返す
  return isDiscountTarget ? createDiscount() : EMPTY_DISCOUNT;
}

run関数には先ほど定義したinputデータが渡され、カート内の商品タイプを取得して割引を適用するかどうかを判定するロジックを実装します。今回は、カート内の商品タイプに「家具」と「家電」が含まれている場合に10%の割引を適用するように設定しています。

商品の設定

商品タイプが「家具」と「家電」の商品を作成します。管理画面から商品を作成し、商品タイプを「家具」または「家電」に設定します。

alt text

alt text

デプロイ

Functionのロジックを実装したら、Functionをデプロイします。以下のコマンドを実行して、Functionをデプロイします。

shopify app deploy

Functionの有効化

Functionはデプロイしただけでは実行されません。Functionを有効化するためには、Admin APIを使ってFunctionを有効化する必要があります。今回は自動でディスカウントが適用されるようにdiscountAutomaticAppCreatemutationを使ってFunctionを有効化します。

先にfunctionのIDを取得します。functions queryを使ってFunctionのIDを取得します。GraphQLの実行はShopify GraphiQL Appを使えば管理画面からアプリを開いて簡単に実行できます。

query shopifyFunctions{
  shopifyFunctions(first: 30){
    edges {
      node {
        id
        title
        apiType
        description
      }
    }
  }
}

クエリを実行したら先ほど作成したFunctionがあることを確認して、IDをコピーします。

{
  "node": {
    "id": "5e61dede-e4d5-40d7-9a4d-7f7705d0b5e6",
    "title": "注文の割引金額",
    "apiType": "order_discounts",
    "description": "カスタムのカートルールとお客様ルールに基づいた注文レベルのディスカウント。"
  }
}

alt text

次に、Functionを有効化します。以下のmutationを実行してFunctionを有効化します。シーズンに合わせてキャンペーンの期間を設定すると良いでしょう。 また、今回は他のとのクーポンの併用を許可しないように設定しています。

mutation discountAutomaticAppCreate($automaticAppDiscount: DiscountAutomaticAppInput!) {
  discountAutomaticAppCreate(automaticAppDiscount: $automaticAppDiscount) {
    automaticAppDiscount {
      discountId
      title
      startsAt
      endsAt
      status
    }
     userErrors {
      field
      message
    }
  }
}

# Variables
{
  "automaticAppDiscount": {
    "title": "春の一人暮らしキャンペーン",
    "functionId": "9d9183a7-f307-49dd-8a4d-1b579ba06d62",
    "combinesWith": {
      "orderDiscounts": false,
      "productDiscounts": false,
      "shippingDiscounts": false
    },
    "startsAt": "2025-03-01T00:00:00Z",
    "endsAt": "2025-04-30T23:59:59Z"
  }
}

実行後の結果は以下のようになります。無事にFunctionが有効化されたことが確認できます。

{
  "data": {
    "discountAutomaticAppCreate": {
      "automaticAppDiscount": {
        "discountId": "gid://shopify/DiscountAutomaticNode/1096034746468",
        "title": "春の一人暮らしキャンペーン",
        "startsAt": "2025-03-01T00:00:00Z",
        "endsAt": "2025-04-30T23:59:59Z",
        "status": "SCHEDULED"
      },
      "userErrors": []
    }
  },
  "extensions": {
    "cost": {
      "requestedQueryCost": 10,
      "actualQueryCost": 10,
      "throttleStatus": {
        "maximumAvailable": 2000,
        "currentlyAvailable": 1990,
        "restoreRate": 100
      }
    }
  }
}

管理画面のディスカウント一覧からもアプリディスカウントとして作成されていることが確認できます。こちらのディスカウントは来年の3月から適用されるのでステータスは「スケジュール済み」になっています。

alt text

埋め込みアプリやAdmin Blockを組み合わせて、管理画面からFunctionの設定を行うことも可能で、後日blogにてご紹介する予定です。

動作確認

ディスカウントの開始日を迎えたら、カートに「家具」と「家電」の商品を追加してチェックアウトすると、10%の割引が適用されることを確認します。

alt text

きちんと注文合計の10%である100円が割引されていることが確認できました。

運用のポイント

  • テストを書いて要件通りの条件で割引が適用されることを確認しましょう。
  • 動作確認で失敗していたらパートナーダッシュボードからログを確認してエラーの原因を特定しましょう。
  • 実際は他のクーポンとの併用を許可するかどうか、割引の適用条件や割引率などを検討して設定しましょう。

まとめ

Shopify Discount Functionを使えば、特定のニーズに合わせたディスカウントを柔軟に設定できます。今回は、異なる商品タイプを購入した場合に割引を適用する例を紹介しましたが、他にも様々な割引設定が可能です。ぜひ、自社のビジネスニーズに合わせてカスタムディスカウントを設定してみてください。

参考