Shopify Scriptsの期限は2026年6月30日:Functionsへの移行手順

執筆:Shubham Vats(Revize創業者)

公開日:読了まで24分

目次

今日は2026年4月16日です。昨日の4月15日、Shopify Script Editorが編集不可になりました。新しいScriptの作成や公開はもうできません。この期限は、購入後の処理に特に影響します。配送先住所の変更は購入後の注文編集で最も多く、編集された注文全体の30.2%を占めます(Revize, 2026)。その編集を処理しているScriptも、現状のまま変更できません。2026年6月30日の実行停止まで、残り75日です。

Shopify Plusの開発者、あるいはPlusストアを運営する代理店として、この12か月間、移行を「次のスプリント」に先送りしてきたなら、対応が必要です。単なる改善案件ではありません。7月1日の午前0時にチェックアウトの処理が動かなくなる問題です。多くのPlusストアには、長年の間に5~20個のScriptsが蓄積されています。それぞれが、誰が書いたかも覚えていない割引ルール、配送方法の非表示、決済方法の制御を支えています。

このガイドは、1月に欲しかった技術的な移行マニュアルです。 方針だけでなく、実際のコードを扱います。Shopify CLIでFunctionのひな形を作り、割引、配送方法のカスタマイズ、決済方法のカスタマイズをRustまたはJavaScriptで実装する方法を説明します。タグを付けた一部の顧客で安全にテストし、既存のチェックアウトに影響を与えずに本番環境へ公開するところまで進めます。

ストアのScriptsをFunctionsへ移行しましょう。

Shopify ScriptsをShopify Functionsのモジュールへ移行する開発者

要点:ScriptsからFunctionsへの移行を60秒で把握

移行の概要: Shopify Scripts(Script Editorで記述するRubyコード。Plus限定)は、Shopify Functions(RustまたはJavaScriptで記述するWebAssemblyモジュール。すべてのプランで利用可能)に置き換わります。shopify app generate extensionでFunctionのひな形を作り、必要なカートデータを取得するrun.graphqlクエリを書きます。次に、割引や配送方法の非表示などの操作を返すrun.rsまたはrun.jsを実装します。shopify app deployでデプロイし、Shopify AdminまたはGraphQLミューテーションで有効化します。Functionsはコンパイル済みのWASMとして5ms未満で実行され、すべてのプランで動作します。今後、Shopifyがサポートするカスタマイズ手段はFunctionsだけです。

6月30日に実際に変わること

コードに取りかかる前に、日付を整理します。重要な期限は2つあります。

日付 起こること 対応
2026年4月15日 (経過済み) Script Editorが読み取り専用になります。新しいScriptsの作成も、既存のScriptsの編集もできません。 既存のScriptsは引き続き実行されます。今すぐ移行しなければ、処理内容を変更できないままになります。
2026年6月30日 すべてのShopify Scriptsの実行が停止します。 この日までに代替のFunctionを稼働させる必要があります。

移行できたかどうかで結果が決まります。6月30日までにFunctionをデプロイすれば、チェックアウトの処理は継続します。間に合わなければ、影響を受けるすべてのカートは、標準の価格、標準の配送料、すべての決済方法が有効な状態に戻ります。部分的な猶予はありません。Scriptは実行されるか、されないかのどちらかであり、6月30日以降は実行されません。

ヒント: Shopify AdminでSettings → Checkout → Customizations Reportを開いてください。ストアで有効なすべてのScript、その処理内容、推奨される代替Functionの種類を確認できます。まずはここから始めましょう。

FunctionsとScripts:実際に変わった点

項目 Shopify Scripts(廃止予定) Shopify Functions(代替)
言語 Ruby DSL(Shopify固有) Rust、JavaScript、TypeScript
実行環境 Shopifyのインフラ上で動くサンドボックス化されたRuby WebAssembly(WASM)。実行時間は5ms未満
利用できるプラン Plusのみ すべてのプラン(カスタムアプリにはPlusが必要。公開アプリは利用可能)
エディター Shopify Admin内のScript Editor ローカルIDEとShopify CLI
バージョン管理 なし。編集内容がそのまま本番に反映 Gitで完全にバージョン管理可能
テスト チェックアウトで手動テスト shopify app devによるローカル開発、プレビューリンク
デプロイ 管理画面で「保存」をクリック ターミナルからshopify app deployを実行
対象 明細項目、配送、決済 割引、Cart Transform、Validation、Delivery Customization、Payment Customization、Order Routing、Fulfillment Constraintsなど

構造上の変化は大きなものです。Scriptsでは、テキスト欄のRubyコードを修正していました。Functionsでは、アプリを作成し、バージョン管理し、ローカルでテストし、CIパイプラインを通してデプロイします。習得には少し時間がかかります。一方、FunctionsはShopifyが長期的に採用する仕組みであり、Scriptsのような暫定的な仕組みではありません。近い将来、チェックアウトの処理を再び移行する必要はないでしょう。

Scriptsに対応するFunctionの種類を選ぶ

現在使っている各Scriptは、それぞれ1つのFunction APIに対応します。以下の対応表を手元に置いてください。

旧Scriptの種類 処理内容 新しいFunction API Functionのターゲット
Line Item Script 特定の商品、顧客、カートの条件に応じて割引を適用 Cart & Checkout Discounts API cart.lines.discounts.generate.run
Shipping Script(割引) カートのルールに応じて送料無料や送料割引を適用 Cart & Checkout Discounts API cart.delivery-options.discounts.generate.run
Shipping Script(非表示・名称変更・並べ替え) $Xを超える場合に配送料を非表示にする、「Standard」を「$50以上で無料」に変更する Delivery Customization API cart.delivery-options.transform.run
Payment Script B2B向けにPayPalを非表示にする、$500を超える場合に代金引換を非表示にする、決済方法を並べ替える Payment Customization API cart.payment-methods.transform.run
カートを変更するScript(まれ) 商品をバンドルする、明細項目を入れ替える Cart Transform API cart.transform.run
チェックアウトをブロックするScript SKUの組み合わせが無効なカートを拒否する Cart & Checkout Validation API cart.validations.generate.run

10個のScriptsがある場合、作成するFunctionsはおそらく3~5個です。複数のScriptsを、分岐を整理した1つのFunctionにまとめられることがよくあります。

割引、配送、決済のカスタマイズを統合するShopify Functions

前提条件:ローカル開発環境を準備する

Functionのひな形を作る前に、次の3つをローカルにインストールします。ターミナルで確認してください。

1. Node.js 18以降

Shell
node --version
# Must be >= 18.0.0

古いバージョンの場合は、nvmを使うか、nodejs.orgからダウンロードしてインストールします。

2. Shopify CLI 3以降

Shell
npm install -g @shopify/cli@latest
shopify version
# Should output 3.x or higher

3. Rustツールチェーン(FunctionsをRustで記述する場合のみ)

Shell
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
rustup target add wasm32-wasip1
cargo --version

JavaScriptのFunctionsにはRustは必要ありません。チームで使う言語を1つ選び、統一しましょう。両方を混在させると保守の負担が増えます。

4. 開発ストア

Partnerダッシュボードにログインして新しい開発ストアを作成するか、既存の開発ストアを使用します。本番環境へ公開する前に、このストアへFunctionsをデプロイします。

最初のFunctionのひな形を作る

定型的な部分の大半はCLIが生成します。任意のディレクトリで次を実行してください。

Shell
# Create a new Shopify app (skip if you already have one)
shopify app init my-checkout-functions
cd my-checkout-functions

# Generate a Function extension
shopify app generate extension

CLIの案内に従って選択します。割引用のFunctionなら、次のように選びます。

  • 種類: Function
  • テンプレート: discount(またはcart_checkout_validation、delivery_customization、payment_customizationなど)
  • 言語: RustまたはJavaScript
  • 名前: volume-discount-fnなど

extensions/volume-discount-fn/が作成され、次のファイルが入ります。

コード
extensions/volume-discount-fn/
├── shopify.extension.toml      # Function config — targets, build, version
├── src/
│   ├── cart_lines_discounts_generate_run.graphql   # Input query
│   └── cart_lines_discounts_generate_run.rs        # Function logic
├── Cargo.toml                  # Rust dependencies (Rust only)
└── README.md

主に編集するのは、設定用の**.toml、入力用の.graphql、処理内容を記述する.rs / .js**の3種類です。

チュートリアル1:Line Item Scriptを置き換える(数量割引)

以前のScriptが、特定のコレクションの商品をカートに5点以上入れた場合に、注文の小計を10%割り引いていたとします。対応するFunctionは次のとおりです。

手順1.1:設定(shopify.extension.toml)

TOML
api_version = "2026-01"

[[extensions]]
name = "volume-discount-fn"
handle = "volume-discount-fn"
type = "function"

[[extensions.targeting]]
target = "cart.lines.discounts.generate.run"
input_query = "src/cart_lines_discounts_generate_run.graphql"
export = "cart_lines_discounts_generate_run"

[extensions.build]
command = "cargo build --target=wasm32-wasip1 --release"
path = "target/wasm32-wasip1/release/volume-discount-fn.wasm"
watch = ["src/**/*.rs"]

手順1.2:入力クエリ(src/cart_lines_discounts_generate_run.graphql)

GraphQL
query Input {
  cart {
    lines {
      id
      quantity
      cost {
        subtotalAmount {
          amount
        }
      }
      merchandise {
        ... on ProductVariant {
          product {
            inAnyCollection(ids: ["gid://shopify/Collection/123456789"])
          }
        }
      }
    }
  }
  discount {
    discountClasses
  }
}

ヒント: Functionsが参照できるのは、クエリで取得したデータだけです。GraphQLの取得項目は必要最小限にしましょう。不要なフィールドを省くほど、実行が速くなり、コストも抑えられます。

手順1.3:処理内容(src/cart_lines_discounts_generate_run.rs)

Rust
use super::schema;
use shopify_function::prelude::*;
use shopify_function::Result;

#[shopify_function]
fn cart_lines_discounts_generate_run(
    input: schema::cart_lines_discounts_generate_run::Input,
) -> Result<schema::CartLinesDiscountsGenerateRunResult> {
    // Bail if discount class doesn't match
    let has_order_discount = input
        .discount()
        .discount_classes()
        .contains(&schema::DiscountClass::Order);

    if !has_order_discount {
        return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] });
    }

    // Sum quantities of items in the target collection
    let qualifying_qty: i64 = input
        .cart()
        .lines()
        .iter()
        .filter(|line| {
            if let schema::Merchandise::ProductVariant(v) = line.merchandise() {
                *v.product().in_any_collection()
            } else {
                false
            }
        })
        .map(|line| *line.quantity())
        .sum();

    if qualifying_qty < 5 {
        return Ok(schema::CartLinesDiscountsGenerateRunResult { operations: vec![] });
    }

    // Apply 10% off the order subtotal
    Ok(schema::CartLinesDiscountsGenerateRunResult {
        operations: vec![schema::CartOperation::OrderDiscountsAdd(
            schema::OrderDiscountsAddOperation {
                selection_strategy: schema::OrderDiscountSelectionStrategy::First,
                candidates: vec![schema::OrderDiscountCandidate {
                    targets: vec![schema::OrderDiscountCandidateTarget::OrderSubtotal(
                        schema::OrderSubtotalTarget {
                            excluded_cart_line_ids: vec![],
                        },
                    )],
                    message: Some("Volume discount: 10% off".to_string()),
                    value: schema::OrderDiscountCandidateValue::Percentage(
                        schema::Percentage { value: Decimal(10.0) }
                    ),
                    conditions: None,
                    associated_discount_code: None,
                }],
            },
        )],
    })
}

手順1.4:テスト、デプロイ、有効化

Shell
# Local development with hot reload
shopify app dev

# When ready, deploy
shopify app deploy

# In the GraphiQL panel that opens (press `g` in the dev terminal),
# create the automatic discount that uses your Function:
GraphQL
mutation {
  discountAutomaticAppCreate(
    automaticAppDiscount: {
      title: "Volume Discount (5+ collection items)"
      functionHandle: "volume-discount-fn"
      discountClasses: [ORDER]
      startsAt: "2026-04-16T00:00:00Z"
    }
  ) {
    automaticAppDiscount { discountId }
    userErrors { field message }
  }
}

これでFunctionが稼働します。バージョン管理もでき、以前のScriptを完全に置き換えられます。

チュートリアル2:Shipping Scriptを置き換える(カート金額に応じて配送方法を非表示にする)

よくあるScriptの例は、「カートの小計が$500を超える場合、高額な注文に翌日配送を適用しないようExpress Shippingを非表示にする」というものです。Delivery Customization Functionでは、次のように実装します。

手順2.1:ひな形を作る

Shell
shopify app generate extension --template delivery_customization --name hide-express-fn

手順2.2:入力クエリ(src/run.graphql)

GraphQL
query Input {
  cart {
    cost {
      subtotalAmount {
        amount
      }
    }
    deliveryGroups {
      deliveryOptions {
        handle
        title
      }
    }
  }
}

手順2.3:処理内容(src/run.js。JavaScript版)

JavaScript
// @ts-check
/**
 * @typedef {import("../generated/api").RunInput} RunInput
 * @typedef {import("../generated/api").FunctionRunResult} FunctionRunResult
 */

const NO_CHANGES = { operations: [] };
const THRESHOLD = 500.0;
const HIDE_TITLES = ["Express", "Overnight"];

/**
 * @param {RunInput} input
 * @returns {FunctionRunResult}
 */
export function run(input) {
  const subtotal = parseFloat(input.cart.cost.subtotalAmount.amount);
  if (subtotal < THRESHOLD) return NO_CHANGES;

  const operations = input.cart.deliveryGroups.flatMap((group) =>
    group.deliveryOptions
      .filter((opt) => HIDE_TITLES.some((t) => opt.title.includes(t)))
      .map((opt) => ({
        hide: { deliveryOptionHandle: opt.handle },
      }))
  );

  return { operations };
}

手順2.4:Shopify Adminで有効化する(GraphQLは不要)

Delivery Customizationsには、Shopify Admin内に操作画面があります。shopify app deployの後、次の手順を実行します。

  1. Settings → Shipping and deliveryを開きます
  2. ページ下部のCustomizationsセクションまでスクロールします
  3. Add customizationをクリックし、作成したFunctionを選択します
  4. 保存します

これで、配送方法を非表示にするルールが本番環境で稼働します。ミューテーションは不要です。

チェックアウトで配送方法を非表示にするShopifyのDelivery Customization Function

チュートリアル3:Payment Scriptを置き換える(B2B顧客には代金引換を非表示にする)

以前のScriptが「『B2B』タグの付いた顧客には代金引換を表示しない」という処理をしていたとします。Payment Customizationでは、次のように実装します。

手順3.1:ひな形を作る

Shell
shopify app generate extension --template payment_customization --name hide-cod-b2b-fn

手順3.2:入力クエリ

GraphQL
query Input {
  cart {
    buyerIdentity {
      customer {
        hasTags(tags: [{ tag: "B2B" }]) {
          tag
          hasTag
        }
      }
    }
  }
  paymentMethods {
    id
    name
  }
}

手順3.3:処理内容(src/run.js)

JavaScript
const NO_CHANGES = { operations: [] };

export function run(input) {
  const tagCheck = input.cart?.buyerIdentity?.customer?.hasTags?.[0];
  const isB2B = tagCheck?.hasTag === true;
  if (!isB2B) return NO_CHANGES;

  const codMethod = input.paymentMethods.find((pm) =>
    pm.name.toLowerCase().includes("cash on delivery")
  );
  if (!codMethod) return NO_CHANGES;

  return {
    operations: [{ hide: { paymentMethodId: codMethod.id } }],
  };
}

手順3.4:有効化する

Payment Customizationsも、Settings → Payments → CustomizationsにShopify Adminの操作画面があります。配送方法と同様に、Functionを選択して保存します。

ここで購入後の注文編集について

このRevizeブログの記事なので、Revizeについても簡単に説明します。Revizeが扱うのは、Functionsでは変更できない購入後の注文です。注文後、顧客は商品の追加、サイズの交換、配送先住所の修正、適用し忘れた割引の追加を希望することがあります。Functionsはチェックアウトで動きます。Revizeはその後に動きます。 Functionsはカートで許可する処理を決め、Revizeは顧客とサポートチームが、返金して注文を作り直すことなく、その後の注文を編集できるようにします。これは2種類のストアに重要です。注文数が多く、手作業での編集が追いつかないストア(Plusの運営者はもちろん、処理件数の多いAdvancedストアも含みます)と、顧客体験をブランドの中心に据えるストアです。後者では、「申し訳ありませんが変更できません」というメールが、次の購入を失う原因になります。

ScriptsからFunctionsへの移行計画は立てたものの、購入後の注文編集を整理していない場合、約3週間後には次の「なぜこんなに難しいのか」という問題に直面するでしょう。公開したばかりの注文管理ガイドで、チェックアウト後の対応を一通り説明しています。

Functionsへの移行に戻りましょう。

テスト戦略:顧客タグを使う方法

Functionsには、Shopify Adminで切り替えられる「下書きモード」はありません。実務では、新しいFunctionの実行対象を顧客タグで限定し、古いScriptと新しいFunctionを並行して動かします。タグ付き顧客に対して同じ結果になることを確認してから、全顧客に切り替えます。

手順1:テスト用ユーザーにタグを付ける

Customersで、社内のアカウント2~3件にFN-TESTERタグを付けます。

手順2:タグの有無でFunctionの処理を分岐する

JavaScript
// At the top of your run function
let is_tester = input
    .cart()
    .buyer_identity()
    .and_then(|bi| bi.customer())
    .map(|c| c.has_any_tag())
    .unwrap_or(&false);

if !*is_tester {
    return Ok(default_result);  // Fall through to existing Script
}

// New Function logic only runs for tagged users

手順3:入力クエリにhasAnyTagを追加する

GraphQL
cart {
  buyerIdentity {
    customer {
      hasAnyTag(tags: ["FN-TESTER"])
    }
  }
}

手順4:チェックアウトで確認する

タグ付きユーザーとしてログインし、チェックアウトを進めて、Functionが実行されることを確認します。タグのないユーザーでもログインし、古いScriptが引き続き動くことを確認します。数日間、結果が一致していればタグの判定を外し、すべての顧客にFunctionを実行します。

手順5:古いScriptを非公開にする

Apps → Script Editor → [Your Script] → Unpublishを開きます。非公開にした後は、Functionだけが処理を担います。

運用規模が大きくなっても使えるデプロイ手順

開発者のノートパソコンからデプロイし続ける運用は避けましょう。1~2個のScriptsを移行したら、CIパイプラインを整えます。

最小限のワークフロー

YAML
# .github/workflows/deploy-functions.yml
name: Deploy Shopify Functions
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: '20' }
      - uses: dtolnay/rust-toolchain@stable
        with: { targets: wasm32-wasip1 }
      - run: npm install -g @shopify/cli@latest
      - run: shopify app deploy --force
        env:
          SHOPIFY_CLI_PARTNERS_TOKEN: ${{ secrets.SHOPIFY_CLI_PARTNERS_TOKEN }}

PartnerダッシュボードのSettings → Tokensでパートナートークンを生成します。これでmainへのマージごとにFunctionsがデプロイされます。「あの変更はデプロイ済み?」とSlackで確認する必要もなくなります。

バージョン管理とロールバック

shopify app deployはバージョン付きのスナップショットを作成します。以前のバージョンに戻すには、次を実行します。

Shell
shopify app versions list
shopify app release --version <previous-version-id>

以前のコードを思い出して貼り直す必要があったScriptsと比べると、大きな改善です。

ローカル、ステージング、本番環境にまたがるShopify Functionsのデプロイパイプライン

多くのチームが間違えること

この1年間、Plusマーチャントの移行を支援する中で、同じ5つのミスが繰り返し見られました。

1. Scriptsを1対1でFunctionsへ移そうとする。 1つのFunctionで、3つのScriptsをより整理された分岐処理に置き換えられる場合があります。書き直す前に、Scripts全体の役割を確認しましょう。

2. 読み取りスコープを忘れる。 多くのFunctionsではread_customers、read_orders、またはwrite_discountsが必要です。shopify.app.tomlのscopesに追加してアプリを再認証してください。そうしないと、入力クエリがnullを返します。

3. 結果の一致を検証せず、タグのない顧客にもFunctionsを実行する。 コードが正しく見えても、空のカート、ギフトカード、ストアクレジット、B2Bの下書き注文など、境界条件で問題が見つかります。タグで対象を限定した段階的な公開には2日かかりますが、重大な障害を防げます。

4. Customizations Reportを確認しない。 実際に稼働している処理を把握するうえで、最も役立つ一覧です。記憶を頼りに移行せず、レポートを基に進めましょう。

5. コレクションIDや顧客タグをコードに直接書き込む。 マーチャントが値を調整できるようにするなら、メタフィールドを使ってFunctionを設定します。CLIはメタフィールドを使う設定のひな形も作成できます。詳しくは、ShopifyのFunction設定に関するドキュメントを参照してください。

今後75日間の移行チェックリスト

6月30日までに無理なく完了するための、現実的な週ごとの計画です。

週 対応
第1週(今週) Customizations Reportを取得します。すべてのScriptを洗い出し、Functionへ移行するか、公開アプリを使うか、削除するかを決めます。
第2~3週 ローカル開発環境を準備します。最初のFunctionのひな形を作り、最も単純なScript(通常は決済方法の非表示ルール)を移行します。
第4~6週 割引用のScriptsを移行します。Discounts APIは機能が多いため、ここに最も時間がかかります。タグを使って十分にテストします。
第7~8週 配送用のScriptsを移行します。Shopify AdminからDelivery Customizationsを有効化します。
第9~10週 CIパイプラインを構築します。開発者のノートパソコンからのデプロイをすべて移行します。
第11週 (6月中旬) 最終的に結果の一致を確認します。すべてのScriptsを非公開にし、2週間、Functionsだけでストアを運用します。
6月30日 Scriptsの終了日を迎えます。移行を早めに終えているため、処理は止まりません。

今週始めれば余裕があります。6月に始めると、その余裕はありません。

Shopify ScriptsからFunctionsへの週ごとの移行計画

よくある質問

Functionsを使うにはShopify Plusが必要ですか?

カスタムFunctionsにはShopify Plusが必要ですが、公開アプリのFunctionsはすべてのプランで動作します。 Plusを利用していない場合は、Functionを提供する公開アプリをShopify App Storeからインストールするか、Plusへアップグレードして独自のカスタムFunctionsを作るかの2つの方法があります。Scriptsを使っていた大規模なマーチャントの多くは、すでにPlusを利用しているため、実務上はあまり変わりません。

FunctionsをTypeScriptで記述できますか?

はい。TypeScriptは完全にサポートされており、CLIでひな形を作成できます。 shopify app generate extensionを実行して「JavaScript」を選ぶと、生成されるプロジェクトにはimport("../generated/api")からの型宣言が含まれます。必要ならファイルを.tsに変更し、tsconfig.jsonを追加できます。コンパイル後の出力(WASM)は、元の言語にかかわらず同じです。

FunctionsはScriptsと比べてどのくらい速いですか?

Functionsは通常5ms未満で実行され、RubyのScriptsより大幅に高速です。 WebAssemblyにコンパイルされ、軽量な実行環境で動くため、Shopifyは実行時間を5ms以内に制限しています。Functionがこの制限を超えると操作は破棄され、Functionは何も操作を返しません。実際には、適切に実装したFunctionは1~2msで実行されます。性能の上限はScriptsよりはるかに高くなります。

Functionから外部APIを呼び出せますか?

いいえ。Functionsはネットワークリクエストを送信できません。 入力されたカートデータを計算し、操作を出力する仕組みです。CRMでの照会やリアルタイムの在庫確認など、外部データが必要な場合は、あらかじめメタフィールドに保存するか、別の仕組み(App Proxy、Webhook、バックエンドでの照会を伴うCart Transform)を使う必要があります。単純な移植ではなく設計の見直しが必要になる、最も一般的な理由です。

Cart TransformとDiscountsはどう違いますか?

Discountsは価格を変更し、Cart Transformはカートの内容を変更します。 10%割引、送料無料、1点購入でもう1点無料の施策にはDiscounts APIを使います。2つの商品を1つの明細項目にまとめたり、1つのバリエーションを複数に分けたりする場合はCart Transformを使います。古いScriptsでは両方の処理が混在していた場合があります。移行時には2つのFunctionsに分けてください。

開発ストアなしでFunctionをローカルテストできますか?

cargo test(Rust)またはnpm test(JS)で単体テストはできますが、統合テストには開発ストアが必要です。 CLIのshopify app function runを使えば、サンプルの入力ファイルに対してFunctionを実行でき、素早く修正を重ねるのに役立ちます。ただし、チェックアウトの動作を最初から最後まで確認するには、実際のカートがあるストアが必要です。

同じ種類のFunctionを複数使えますか?

はい。Shopifyは同じターゲットに複数のFunctionsを設定でき、実行順序も決まっています。 割引の順序は、Shopifyの割引の併用ルールに従います。Delivery CustomizationsとPayment Customizationsでは、Functionsを連続して実行でき、各Functionの出力が次に渡されます。多くのチームは、管理を簡単にするため、種類ごとに1つのFunctionを使います。

Functionをデプロイした後、Scriptはどうなりますか?

Apps → Script EditorでScriptを非公開にするまで、両方が並行して実行されます。 これは、並行稼働でテストできるようにするためです。Functionが動作することを確認したら、Scriptを手動で非公開にしてください。2026年6月30日以降は、非公開にしたかどうかに関係なく、すべてのScriptsの実行が停止します。

移行はSEOやテーマに影響しますか?

いいえ。Functionsはチェックアウト時にサーバー側で実行され、テーマや商品ページには触れません。 変更するのは、チェックアウト時の割引、配送方法、決済方法だけです。ストアフロント、商品テンプレート、SEOへの影響はありません。

カスタムプロパティ付きのInput.line_itemsを使うScriptは、どう移行しますか?

カスタムプロパティには、GraphQL入力のカート明細にあるattributeフィールドからアクセスできます。 linesの選択項目にattribute(key: "your-key") { value }を追加します。Functionは、Scriptsが明細項目のプロパティを読んでいたのと同じように値を取得します。Rubyのメソッド呼び出しではなく、GraphQLを使う点が異なります。

分析や注文タグはどうなりますか?Functionsはデータを書き込めますか?

Functions自体は注文タグを書き込んだり、Webhookを起動したりできません。現在のカートに対する操作を返すだけです。 タグ付けや後続のワークフローには、注文作成イベントで起動するShopify Flowを使います。多くのマーチャントは、割引用のFunctionと、注文に「VOLUME-DISCOUNT-APPLIED」タグを付けるFlowを組み合わせています。

カスタムFunctionを作らずにインストールできる公開アプリはありますか?

はい。Shopify App Storeには、よくある用途向けにFunctionsを提供するアプリが多数あります。 「discount function」「delivery customization」「payment customization」で検索してください。数量割引、タグに応じた決済方法の非表示、一定金額以上の送料無料といった単純な用途なら、既存のアプリを使うことで開発にかかる日数を減らせる場合があります。カスタムFunctionsは、自社固有の処理に使いましょう。

6月30日の期限に間に合わなかった場合はどうなりますか?

Scriptの実行が停止します。代替処理も猶予期間も延長もありません。 Scriptが行っていた割引、配送料の非表示、決済方法の制限などは、7月1日の午前0時(UTC)に標準の動作へ戻ります。事業に必要な処理なら、その日より十分前に稼働させる計画を立ててください。特に結果の一致を検証する場合、移行には多くのチームが見積もるより時間がかかります。

Script Editorアプリを完全に削除できますか?

2026年6月30日以降にアンインストールできますが、Shopifyが自動的に削除する可能性もあります。 Scriptsの実行が止まれば、エディターを使う目的はなくなります。移行を完了しているなら、今すべてのScriptsを非公開にして、すぐにアプリをアンインストールすることもできます。Functionsは独立して動作します。

今週やるべきこと

この記事を読んでタブを閉じる前に、今後7日間で次の4つを済ませてください。

1. Customizations Reportを取得する。 Settings → Checkout → Customizations Reportを開いてエクスポートします。これが移行対象の一覧になります。

2. 開発環境を準備する。 Node 18以降、Shopify CLI、必要な場合はRustをインストールします。shopify versionが動くことを確認してください。所要時間は合計30分です。

3. 小さなFunctionを1つ作り、開発ストアへ公開する。 手元にある最も単純なScriptを選びます。通常は決済方法の非表示ルールです。最初から最後まで移行してみてください。本番環境へ公開しなくても、開発ツール一式が動くことを検証できます。

4. 今後8週間の作業時間を予定表に確保する。 スプリントの合間の空き時間だけでは移行は進みません。たとえば毎週火曜と木曜の午後に定期的な枠を取り、リリース作業として扱いましょう。

私たちが見てきた移行チームには共通の傾向があります。着手を先延ばしにする2週間、実作業の3週間、仕上げの1週間です。合計6週間かかります。残りは10週間あります。その余裕は、着手の先送りではなく、コードレビューと品質確認に使ってください。

チェックアウトの処理を整理した後、多くのチームが次に取り組むのは購入後の対応です。注文後の配送先住所の変更、商品の交換、割引の追加などが該当します。こうした対応が計画に入っているなら(注文数の多いPlusストアでも、顧客体験を重視するAdvancedストアでも、取り組む価値があります)、RevizeはShopify App Storeで利用できます。ここで作成するどのFunctionとも併用できます。

参考資料

2026年8月更新。 Revizeは、顧客が購入後に自分で注文を編集できるShopifyアプリです。フルフィルメント前であれば、サポートへの問い合わせなしで、配送先住所の変更、バリエーションや商品の交換、キャンセル、返金またはストアクレジットの受け取りができます。詳しくは、顧客自身がShopifyの注文を編集できるようにする方法をご覧いただくか、Shopify App StoreでRevizeをご確認ください。