コンテンツにスキップ
Scripts移行支援2026年6月30日に廃止

Shopify Scriptsは2026年6月30日に動作を停止しました。今すぐすべきことをご案内します。

ストアにカスタム割引、BOGO、バンドルのScriptがあった場合、それらは2026年6月30日に静かに実行を停止しました。エラーもアラートもなく、ログにも何も記録されません。ここでは実際に何が起きたのか、Shopify Functionsへの移行に何が必要なのか、そしてStackableで何を再構築できるのかを正直にお伝えします。

実際に何が起きたのか
  • Shopify Scriptsは2026年6月30日、まだ利用していたすべてのストアで実行を停止しました。
  • Script内にあったカスタム割引、BOGO、バンドルのロジックは、その日を境に適用されなくなりました。
  • この不具合は仕様上、静かに発生します。条件がカートに一致しないShopify Functionは単に発火しないだけです。エラーは発生せず、Shopifyから通知が届くこともありません。
ストアオーナーが不意打ちを受ける理由

この移行に取り組むストアオーナーたちは、Shopifyコミュニティフォーラムで同じ危険性を語っています。

以前のScriptは割引の適用を静かに停止していて、顧客から満額請求されたとクレームが来て初めて気づきました。エラーもアラートもなく、注文ログにも何も残っていませんでした。気づくまでの数週間、壊れた状態のまま運用していたのです。

これがScriptsからFunctionsへ移行する際の核心的なリスクです。Functionは正しく構成されて動作しているか、設定ミスで沈黙しているかのどちらかであり、その中間状態は目に見えません。条件の不一致、しきい値の入力ミス、コレクションの指定間違いなど、どんな設定ミスも、正しく動作している場合とまったく同じ「沈黙」を生み出します。これを見抜く唯一の方法は、本番で信頼する前に、発火すべきケースと発火すべきでないケースの両方を意図的にテストすることです。

移行に実際必要なこと

始める前に知っておくべき4つのこと

01

1つのScriptが、しばしば3つの移行になる

1つのScriptファイルが、割引ロジック、配送料金、支払いカスタマイズを同時に扱っているケースがありました。Functionsではこれが割引、配送、支払いという別々のFunctionタイプに分割され、それぞれ個別に設定・デプロイする必要があります。「自分のScriptを移行する」ということは、多くの場合、最大3つの異なるものを移行することを意味し、これが移行に関してストア運営者から最も多く聞かれる不満です。

02

ノーコードビルダーが対応するのは通常、割引とBOGOのみ

お使いのScriptが配送料金や支払い方法にも関わっていた場合、Stackableを含むノーコードの割引Functionビルダーはそこまでカバーしていません。配送や支払いのカスタマイズには、開発者がFunctionを直接記述する必要があります。

03

今のうちに古いScriptのソースを保存しておく

Script Editorが完全に廃止されると、保存されていたコードは復元できなくなります。まだ移行の準備ができていなくても、今日のうちに古いScriptのソースをエクスポートまたはコピーしておき、後継となるものの参考資料として残しておきましょう。

04

発火すべきカートと発火すべきでないカートの両方をテストする

新しいFunctionを信頼する前に、2つのテストカートを用意しましょう。1つは発火するべきカート、もう1つは意図的に発火しないべきカートです。発火すべきでない場面で発火してしまうFunctionは、静かに発火しないFunctionと同じくらい大きな損失を招きます。

ScriptsとFunctionsの実際の仕組み

あらゆる移行判断を説明する3つのポイント

何が再構築でき、何ができないかという議論のほとんどは、3つの事実に行き着きます。Scriptsには3つの種類があり、それぞれ枠は1つしかなかったこと、Functionsはその3種類を4つの異なるAPIに分割したこと、そしてFunctionは実行前に読み取るすべてのデータをあらかじめ宣言しなければならないことです。この3点さえ押さえれば、このページの残りはただの算数です。

Shopify Scriptsには3つの種類がありました

Script Editorでは、Rubyを1行でも書く前に種類を選ぶ必要があり、その種類によってコードが操作できる対象が決まっていました。

明細行Script

商品の価格を変更する種類です。カートを行ごとに処理して価格を付け替えるもので、段階的な割引、BOGO、バンドル価格、値下げはすべてここに実装されていました。

配送Script

配送料金を操作する種類です。料金を割引したり、非表示にしたり、名称を変更したり、購入者に表示されるリストの並び順を変えたりできました。この4つのうち割引にあたるのは最初の1つだけです。

支払いScript

支払い方法を操作する種類で、動作は同じ4パターンでした。方法を非表示にする、名称を変更する、リストの並び順を変える、そして実際にはほとんどの場合、特定のカートに対して非表示にするというものです。

そして、実際に目にするあらゆるScriptの形を決定づけていた制約があります。それは、各種類につき公開できるScriptは常に1つだけだったということです。ストア全体で明細行の枠は1つしかありませんでした。そのため、VIP割引、クリアランス価格、購入金額のしきい値、季節限定プロモーションを同時に運用したいストア運営者は、4つのScriptを書くのではなく、その4つすべてを1つのファイルにまとめ、末尾に「より条件の良い価格を採用する」という自作ルールを添えるのが常でした。実際のScriptsが入り組んで見えるのはこのためです。1つのルールが下手に書かれているのではなく、本来別々であるべき複数のルールが、分けることを許されなかったのです。

4つのキャンペーンが1つのファイルに統合された実際のScriptを見る

4つのFunction APIがそれらに取って代わりました

ShopifyはScriptsを1つのもので置き換えたわけではありません。コードがカートのどこで動くかではなく、何を変更できるかによって分割された4つのもので置き換えたのです。

Discount Function API

値引きを担当します。商品割引、注文割引、配送割引はすべて、今ではこの1つに統合されたAPIにまとまっています。以前のScriptが価格を変更していたなら、移行先はここです。

Shopify のドキュメント

Delivery Customization API

配送オプションの非表示、名称変更、並び替えを担当します。Shopifyは、チェックアウト時に配送オプションをカスタマイズできるAPIはこれだけだと明言しており、割引アプリがどのように作られていてもここには手が届きません。

Shopify のドキュメント

Payment Customization API

支払い方法の非表示、名称変更、並び替え、さらに支払い条件や注文にレビューが必要かどうかを担当します。かつてのScript Editorの支払い部分がここに集約されています。

Shopify のドキュメント

Cart and Checkout Validation API

メッセージを表示してチェックアウトをブロックします。購入数の上限、年齢確認、最低注文金額のルールはここに含まれます。エラーを返す仕組みなので、注文を止めることはできても、静かに内容を変更することはできません。

Shopify のドキュメント

StackableはDiscount Functionアプリであり、それ以外の何物でもありません。割引Functionを構築しているため、配送割引を含め、以前のScriptが価格に対して行っていたことはすべて再構築できます。一方で、配送カスタマイズ、支払いカスタマイズ、バリデーションFunctionは提供していません。配送料金の非表示、支払い方法の名称変更、購入数量の上限設定などをお断りしているのは、それを作っていないからではなく、そもそも種類の異なるアプリだからです。

この2つを組み合わせると、ストア運営者が苦労して気づくことになる、あの一文にたどり着きます。1つのScriptが、しばしば3つの移行になるということです。配送料金を非表示にし、支払い方法をブロックしていた明細行Scriptは、今では割引Function、配送カスタマイズ、支払いカスタマイズという、それぞれ別に記述してデプロイする必要があるものになります。再構築を終えてから気づくより、ここで先に知っていただきたいと考えています。

実は割引ではなかった配送Scriptの例を見る

Functionsは純粋関数であり、すべての項目が事前に宣言されます

Scriptは、カートの中身が何であれ、普通のRubyコードとして実行されていました。Functionはサンドボックス内で実行され、Shopifyは次のいずれも持たないことを保証しています。

  • ネットワークがありません。購入者がチェックアウトしている間、FunctionはERPやロイヤルティプロバイダー、その他どのサービスも呼び出せません。
  • 時計がありません。Functionは現在時刻を取得できないため、「火曜日は半額」はコード内の条件ではなく、スケジュール設定された割引として実現する必要があります。
  • 乱数がありません。10人に1人にサイコロを振るような処理は行えません。
  • ファイルシステムもなく、要求していない項目を取得することもできません。Functionが読み取るすべてのデータは、入力クエリの中であらかじめ名前を指定しておく必要があり、そのクエリにはShopifyが設定した厳格なコスト上限があります。

Shopify のドキュメント

この最後のルールが、ストア運営者にとって最もコストの大きいものであり、それが誰にとってのコストなのかを正確に述べておく価値があります。Shopifyがデータを隠しているわけではありません。当社自身のチェックアウトクエリは、Shopifyが許可する上限コストにすでに達しており、項目を1つ追加するには別の項目を諦める必要があります。現在お断りしているScript形状のうち9つは、まさにこの理由だけでお断りしています。すでに値下げ済みの商品を除外する、都道府県や郵便番号を読み取る、顧客のこれまでの注文件数を確認する、といったものです。これらはすべてShopifyが提供している機能です。当社がまだそのための余地を作れていないだけです。これは当社側のギャップであり、プラットフォームの制約だと言うのは嘘になります。

ライブラリ全体で拒否している中で、正真正銘のShopify側の制約は2件だけであり、どちらも同じ事実に起因しています。ストア上のすべてのDiscount Functionは同じ瞬間に実行され、互いが何をしたかを知ることができません。そのため、「この商品はすでに割引済みか」を確認するScriptや、すでに値引き後の小計に対してしきい値を判定するScriptは、今日の時点では当社にも他の誰にも、どんな方法であっても再構築できません。当社の拒否リストにあるそれ以外のものはすべて当社側で解決できる問題であり、アプリ内およびライブラリの全ページでそのように明記しています。

本当にShopifyの制約によるお断り2件を読む
最も高くつく違い

価格を設定することと、金額を差し引くことは同じではありません

Scriptを手作業で再構築する前に、これだけは読んでください。2つのファイルが同じメソッドを、同じ定数、同じメッセージで呼び出していても、意味がまったく逆になることがあります。以下の2つはどちらも実在し、どちらもよくあるものですが、違いはマイナス記号1つだけです。

これは価格を$9.99に設定します

FIXED_PRICE = Money.new(cents: 999)

Input.cart.line_items.each do |line_item|
  next unless line_item.variant.product.product_type == "Clearance"
  line_item.change_line_price(FIXED_PRICE * line_item.quantity, message: "Clearance $9.99 each")
end

Output.cart = Input.cart

$79.00の商品の場合、割引額は$69.01となり、購入者の支払額は$9.99です。特典が設定価格であり、バリエーションごとにカウントされ繰り返し適用されるVolumeオファーとして再構築されるため、すべてのユニットの価格が付け替えられます。

カートと設定つきの実例を見る

これは$9.99を割り引きます

DISCOUNT = Money.new(cents: 999)

Input.cart.line_items.each do |line_item|
  next unless line_item.variant.product.product_type == "Clearance"
  new_price = line_item.line_price - (DISCOUNT * line_item.quantity)
  line_item.change_line_price(new_price, message: "$9.99 off each")
end

Output.cart = Input.cart

同じ$79.00の商品で、割引額は$9.99となり、購入者の支払額は$69.01です。特典がユニットごとの金額オフであり、商品ごとにカウントされ1回だけ適用されるVolumeオファーとして再構築されます。

カートと設定つきの実例を見る

メソッドは同じ、$9.99も同じ、メッセージの文言も同じです。唯一の見分け方は、2つ目のファイルが代入する前に`line_item.line_price`から値を差し引いている点です。$79.00の商品でこれを逆に読み違えると、どちらの方向であれ痛手となる形で、1ユニットあたり$59.02のずれが生じます。しかも2つの再構築は金額が違うだけではありません。一方はバリエーションごとにカウントして繰り返し適用され、もう一方は商品ごとにカウントして1回だけ適用されるため、購入者が2つ買った瞬間からさらに結果が乖離していきます。

これは、よくあるアドバイスでは見抜けない種類の失敗です。ファイルを逆に読み違えて再構築されたオファーも、発火すべきカートでは発火し、発火すべきでないカートでは静かなままなので、双方向のテストをすり抜けてしまいます。Scripts Rescueはこれを別の問いを立てることで防ぎます。公開を許可する前に、まだ再現できるカートに対して以前のScriptが請求していた金額を尋ね、それを再構築したオファーが計算する金額と比較するのです。1セントでもずれていれば公開はロックされたままです。現在Scripts移行を提供している5つのアプリを調査しましたが、金額の証明をストア運営者に求めるものは1つもありませんでした。

用語を翻訳する

Rubyの各要素がキャンペーンでは何になるか

再構築が失敗するポイントは毎回ほとんど同じで、しかもそのほとんどは一見しただけではわかりません。特典部分はたいてい簡単です。金額が静かに動くのはカウント方法と繰り返しの扱いで、Scriptではそれが計算式で表現され、キャンペーンでは設定項目で表現されるからです。

Scriptではキャンペーンでは間違えやすい点
change_line_price(PRICE * qty)設定価格を特典とするVolumeオファー。減算ではなく代入です。これが上で説明した罠です。ユニット価格が定数そのものになるため、$79の商品が$9.99で販売されます。
line_price - (AMOUNT * qty)ユニットごとの金額オフを特典とするVolumeオファー。減算であることがすべての手がかりです。定数は上の行と同じでも、請求額はまったく異なります。
line_price * 0.9割引率10%を特典とするオファー。この乗数は、購入者が節約する金額ではなく、支払う側に残る割合を表します。そのまま90と入力すると、カタログの10分の9をタダで手放すことになります。
next unless line_item.quantity >= 3最低数量3の階層。階層は境界値を含み、条件を満たす最も高い階層のみが発火します。ルールを次々と積み重ねていたScriptには、1つのオファーで置き換えられる等価物がなく、それぞれ個別のオファーが必要になります。
line_items.size > 1最低数量2。同じルールではありません。Scriptではここをカート明細行の数でカウントしていましたが、キャンペーンではユニット数でカウントするため、同じ商品を2つ含む1つの明細行が、Scriptでは対象外だったところでも条件を満たすようになります。
sets = quantity / (BUY + GET)無料ユニットを追加分としてカウントするBuy X Get Y。代わりにBUYの数だけで割ると、無料ユニットが対象数量に含まれる扱いになります。3つ購入で1つ無料のオファーで9ユニットの場合、無料になるのは2個か3個かの違いが生まれます。文字1つ分の違いで、無料で渡す量が1.5倍になります。
customer.tags.include?("vip")タグで絞り込んだ顧客の対象条件。Shopifyは大文字小文字を含め、タグを完全一致で照合しますが、多くのScript方言では両辺をまず小文字に変換していました。公開の後ではなく前に、綴りを確認してください。
product.tags / product_type / vendorタグ・商品タイプ・ベンダーを対象範囲としたターゲティング。対象範囲の指定漏れは、この表の中で最もコストの大きいミスです。「セールタグに20%オフ」のはずが、販売するすべての商品が20%オフになってしまうからです。

この表に載っていないものが1つあります。Collectionsです。Scriptは商品のタグ、タイプ、ベンダーを読み取ることはできても、Collectionを読み取ることはできませんでした。そのため、Collectionを確認しているように見えるRubyがあっても、実際にはそのとおりには動作していませんでした。キャンペーンはCollectionを対象にできますが、以前のScriptにはそれができなかったのです。

すべての形状を書き出しました

自分で推測せず、Scriptを検索して確認する

当社がカタログ化したすべてのScript形状には、専用ページが用意されています。元のRuby、それがどのパターンとして認識されるか、実際に生成される設定内容、実際のエンジンが計算した割引額を示す公開デモストアのカート、そして静かなままであるべきカートです。お断りしている項目も同じ形式で書き出されており、それぞれShopifyの制約なのか、当社側のギャップなのか、それとも別の種類のアプリの領分なのかがラベル付けされています。これは私たちが最初に欲しかったリファレンスなので、公開しています。

Script の型
42
現在再構築可
38
理由つきで不可
21
Stackableでできること、できないこと

対応範囲についての正直な回答

StackableはルールベースのDiscountロジックをネイティブのShopify Functions上で再構築します。任意のカスタムコードを実行するものではありません。

Stackableで再現できること

  • 階層/ボリューム割引(例:「3点以上購入で15%オフ」)
  • Buy X Get YおよびBOGOロジック(繰り返し階層を含む)
  • オファー間の明示的な割引の重ねがけルール
  • 任意のキャンペーンにおけるスケジュール開始・終了、および即時一時停止

開発者が必要になること

  • 古いScriptが実行していた任意のカスタムコード(独自の価格計算式や、ビルダーが対応しない一回限りの条件など)
  • 配送のカスタマイズ(別のFunctionタイプ)
  • 支払いのカスタマイズ(別のFunctionタイプ)
  • ルールベースの割引設定に還元できないもの全般

以前のScriptがこのリストの内容を行っていた場合、Stackableを含むノーコードビルダーでは対応できません。それは設定画面ではなく、開発者が書くFunctionが必要な領域です。

よくある質問

よくある質問

古いScriptsは失われてしまったのですか?

Scriptsは2026年6月30日に実行を停止しましたが、それは必ずしもScript Editorに保存されたソースコードが削除される瞬間と同じではありません。いずれにせよ、古いScriptのコードは今すぐエクスポートまたはコピーしておいてください。Shopifyがエディタを完全に廃止すると、復元できなくなります。

Functionの設定ミスがあった場合、エラーは表示されますか?

いいえ。条件がカートに一致しないFunctionは、エラーもアラートもなく、静かに発火しないだけです。本番環境で信頼する前に、必ず発火するべきカートと発火するべきでないカートの両方でテストしてください。

Stackableは古いScriptが行っていたことをすべて代替できますか?

ルールベースの部分のみです。階層/ボリューム割引、BOGO、割引の重ねがけ、スケジュール設定は、すべてネイティブなShopify Functions上で再構築されています。Stackableは任意のカスタムコードを実行しません。お使いのScriptが独自の価格計算式やビルダーが対応しない条件など、本当に特殊な処理を行っていた場合は、開発者がFunctionを直接記述する必要があります。

Scriptが扱っていた配送や支払いのロジックはどうなりますか?

それらは配送と支払いという別のFunctionタイプであり、Stackableは関与しません。割引ロジックとは別に、開発者がそれぞれを移行する必要があります。

Scripts Rescueはどのプランで使えますか?

以前のRubyを読み取って再構築するツールであるScripts Rescueは、Proプランの機能です。Stackable自体はインストール無料で、Volume階層、Buy X Get Y、Spend goal、送料無料、スケジュール設定、シミュレーターを含むコア割引エンジンはすべてのプランで無料です。ただしRubyの救済機能だけは別で、複数ストア対応やShopify Flowと同じくProプランに含まれています。

再構築した割引が、以前と同じ金額を請求することはどうすればわかりますか?

公開する前に、それを証明することが求められる仕組みになっているためです。発火すべきカートと発火すべきでないカートをテストするのが一般的なアドバイスですが、これでは最悪の失敗、つまり正しいタイミングで発火しても金額が間違っているオファーは見抜けません。Scripts Rescueは、まだ再現できるカートに対して以前のScriptが請求していた金額を尋ね、それを再構築したオファーが計算する金額と比較して、両者が1セント単位で一致するまで公開をロックしたままにします。Scripts移行を提供している5つのアプリを調査しましたが、それを求めるものは1つもありませんでした。

なぜ自分のScriptはあれほど複雑に見えたのですか?

各種類につき公開できるScriptが常に1つだけだったからです。4つのプロモーションを運用していたストアは、4つのScriptを書くことができず、その4つすべてを1つのファイルにまとめ、末尾にどれを採用するかを決めるルールを添えていました。読みにくく見えるRubyのほとんどは、実際には1つの枠を共有する複数のシンプルなルールであり、それぞれを個別に見れば大抵はきれいに再構築できます。

移行についての詳しい解説はどこで読めますか?

当社の最初のブログ記事では、Scriptsの廃止と移行パスについてさらに詳しく解説しています。また、Script例のライブラリには、Script形状ごとに元のRubyと実際の再構築内容をまとめたページが用意されています。

Stackableをインストールしてルールベースの割引を再構築

ボリューム階層、BOGO、重ねがけ、スケジュール設定を、導入初日からネイティブのShopify Functions上で実行します。

Scripts RescueはProプランの機能です。Stackable自体はインストールが無料で、クレジットカード登録も不要です。

本サイトの運営には必須Cookieを使用しており、お客様の同意をいただいた場合のみ、アクセス状況を把握するための分析Cookieを使用します。詳細は Cookieポリシー.