POS UI extensions / 2026-10破壊的変更

Cart API の書き込みは
「POS が確認しないと reject」に変わる

これまではカートが実際に変わっていなくても mutation は成功(resolve)扱いでした。2026-10 からは POS が書き込みを確認できない場合に promise が reject されるため、すべての呼び出し箇所でエラー処理が必要になります。

このページの構成
  1. そもそも何が変わるのか(30秒で理解)
  2. 仕組み図解 : 2026-07 以前と 2026-10 の違い
  3. 対象になる Cart API mutation
  4. reject 時の 2 つのメッセージ
  5. 影響を受けるアプリ/受けないアプリ
  6. 移行手順とコード例
  7. 技術者が押さえるべき5つのポイント
  8. 業務に活かせる3つのユースケース
  9. 提案で使える1行サマリ

1そもそも何が変わるのか

POS はすべてのカート書き込みについて結果を返しており、カートが変わったと確認できるのは success の結果だけです。
API バージョン 2026-10 からは、POS が書き込みを確認できない限り Cart API の mutation は reject されます。これまで見えなかった「書き込みの取りこぼし」が、呼び出し元のエラーとして表に出てきます。

2026-07 以前 : 結果に関係なく resolve

POS が書き込みを反映したかどうかに関係なく mutation は resolve します。そのため、反映された書き込みと取りこぼされた書き込みをアプリが区別できず、カートは変わっていないのに手数料や割引を「適用済み」と表示してしまうことがあります。

2026-10 : 確認できなければ reject

POS が書き込みを確認したときだけ resolve します。確認できなければ reject され、アプリはリトライする・スタッフにメッセージを出す・自分の state をロールバックする、といった対応をその場で取れます。

2仕組み図解 : 2026-07 以前と 2026-10 の違い

2026-07 以前 2026-10 以降 cart mutation 例 applyCartDiscount POS 適用 or 取りこぼし 常に resolve 結果に関係なし 取りこぼしに気づけない 「割引適用済み」表示でも カートは変わっていない cart mutation 例 applyCartDiscount POS 結果を返す success → resolve カートが変わったと確定 未確認 → reject 2 種類のメッセージ 呼び出し元で対処 リトライ スタッフに通知 state をロールバック
なぜ重要か : 現状、カート書き込みの取りこぼしは 何も言わずに起きるため気づけません。reject にすることで、この「気づかれないデータ欠損」が呼び出し元のエラーとして見えるようになります。

3対象になる Cart API mutation

2026-10 で「未確認なら reject」になるもの(15 個)

カート・明細
bulkCartUpdate removeLineItem
カート割引
applyCartDiscount addCartCodeDiscount removeAllDiscounts
顧客
setCustomer removeCustomer
明細プロパティ
addLineItemProperties bulkAddLineItemProperties removeLineItemProperties
明細割引
setLineItemDiscount bulkSetLineItemDiscounts removeLineItemDiscount
販売プラン
addLineItemSellingPlan removeLineItemSellingPlan

※ カテゴリ分けはこのページで読みやすくするためのもので、元記事にはありません。

2026-10 で新しく追加されたもの

NEW
updateLineItemQuantity

2026-10 で新しく追加された mutation で、最初のリリースから「未確認なら reject」の仕様です。古い挙動のバージョンはありません。

4reject 時の 2 つのメッセージ

拒否された(カートは変わっていない)
POS refused the cart update. The cart was not changed.

POS が書き込みを受け付けなかったケースで、カートは変わっていません。レジ担当が支払いに進んだ後など、POS がカートの変更をもう受け付けていないときに起きます。カートを編集できる状態に戻れば、リトライで成功する可能性があります。

確認できなかった(結果は不明)
POS could not confirm the cart update.

結果が分からず、一部だけ書き込まれている可能性もあります。リトライする前にカートを読み直す必要があります。

この 2 つのメッセージは「未確認の書き込み」専用です。cart mutation は、割引の値が不正、顧客が見つからないといった 別の理由でも reject されます。メッセージで判定するのは、この 2 ケースを区別したいときだけにしてください。
ケースカートの状態推奨される対処
refused変化なしカートを編集できる状態に戻ってからリトライ
could not confirm不明(一部書き込みの可能性)カートを読み直してからリトライ
その他の reject記載なし不正な割引値・顧客が見つからない等、原因ごとに対処

5影響を受けるアプリ/受けないアプリ

影響あり

2026-10 以降を宣言した extension

api_version = "2026-10" 以降の POS UI extension から、上記の mutation を 1 つでも呼んでいるアプリ。

影響なし

2026-07 以前のまま

今の挙動がそのまま続きます。2026-07 は API バージョニングのサポート期間が終わるまで使えます。

挙動が変わる

すでに try/catch を書いている

未確認の書き込みでも成功したものとして処理を続けるのではなく、既存の catch / .catch() ハンドラが実行されるようになります。

適用単位は ストアではなく extension ごとです。各 extension が宣言している API バージョンで決まります。

6移行手順とコード例

注意 : これまで resolve していた呼び出しが reject するようになります。 reject を catch しないと、ハンドラの残りの処理は実行されません。書き込み後に描画する UI や、ローディング状態を解除するといった後片付けも含めて止まります。
Before
await shopify.cart.applyCartDiscount('FixedAmount', 'Winter discount', '5.00');
setDiscountApplied(true);
After
try {
  await shopify.cart.applyCartDiscount('FixedAmount', 'Winter discount', '5.00');
  setDiscountApplied(true);
} catch (error) {
  setDiscountApplied(false);
  showToast('Could not update the cart. Try again before payment.');
}
1

呼び出し箇所を洗い出す

extension の中で、対象の cart mutation を呼んでいるすべての場所を確認します。

2
catch

それぞれに reject 処理を入れる

try/catch か .catch() を入れ、state を戻す・メッセージを出す処理を書きます。

3

api_version = "2026-10" に上げる

エラー処理が入ってからバージョンを上げます。

すぐに移行できない場合は、2026-07 以前のままにしておきます。 影響は受けないので、エラー処理を入れ終わってからバージョンを上げれば大丈夫です。エラー処理を入れずに上げると、最初の未確認書き込みでハンドラが止まり、スピナーが出たままになったり確認ステップが飛ばされたりします。

7技術者が押さえるべき5つのポイント

await

1. catch しない await は後続処理ごと止まる

reject が catch されないと、書き込み後の UI 描画もローディング解除も実行されません。「スピナーが消えない」「確認ステップが飛ばされる」が典型的な症状です。後片付けはエラー時にも通る場所に置く必要があります。

拒否 不明

2. 「拒否」と「不明」でリトライ方針が違う

refused はカートが変わっていないので、編集できる状態に戻ればそのままリトライできます。could not confirm は一部だけ書き込まれた可能性があるので、まずカートを読み直してからリトライします。何も考えずにリトライすると二重適用の恐れがあります。

3. メッセージで分岐するのは必要なときだけ

不正な割引値や顧客が見つからないなど、2 つのメッセージ以外の理由でも reject されます。基本はすべての reject を catch で受け、2 ケースを区別したいときだけメッセージで判定します。

07 10

4. 切り替えは extension ごと

影響範囲はストアではなく、各 extension の api_version で決まります。複数の extension を持つアプリでは、一つずつエラー処理を入れてから上げる段階的な移行ができます。

update Qty

5. 新しい updateLineItemQuantity は最初から reject 前提

2026-10 で追加された updateLineItemQuantity は、最初のリリースから reject する仕様です。この mutation に乗り換える場合、「resolve したらカートが変わった」と前提にして、最初から catch を書く設計にします。

8業務に活かせる3つのユースケース

-5.00
USE CASE 1

割引・手数料の「適用済み表示なのに未反映」をなくす

課題
POS extension で割引や手数料を入れたとき、カートは変わっていないのに「適用済み」と表示されることがある(2026-07 以前の挙動)。
打ち手
呼び出し箇所すべてに try/catch を入れ、catch でフラグを戻してトーストを出す(記事の After 例)。そのうえで api_version = "2026-10" に上げる。
効果
気づかれずに起きていた書き込みの取りこぼしが、スタッフに見えるエラーになる。支払い前にやり直せる。
技術メモ
catch の中で UI の state(例: setDiscountApplied(false))を戻す。ローディング解除も忘れずに。
拒否 → 再試行 不明 → 再読込
USE CASE 2

reject の種類に応じたリトライ処理をアプリ共通で用意する

課題
reject の中身が「拒否(カートは変わっていない)」か「不明(一部書き込みの可能性)」かで、正しいリトライ方法が違う。
打ち手
2 つのメッセージで判定し、拒否はカートを編集できる状態に戻ってからリトライ、不明はカートを読み直してからリトライする。それ以外の reject は理由ごとに処理する。
効果
何も考えずにリトライして起きる二重適用を避けつつ、リトライで成功するケースは自動で拾える。
技術メモ
メッセージで分岐するのは 2 ケースを区別したいときだけにする。既定の動作は「すべての reject を catch」。
10 10 07
USE CASE 3

複数の POS extension を一つずつ安全に 2026-10 へ移行する

課題
カートを操作する extension がいくつもあり、一度に全部直すのは難しい。
打ち手
エラー処理を入れ終わった extension から api_version を 2026-10 に上げる。まだのものは 2026-07 のままにしておく。
効果
適用単位が extension ごとなので、本番の挙動を壊さずに段階的に移行できる。
技術メモ
2026-07 は API バージョニングのサポート期間が終わるまで動く。期限は記事に記載なし。API versioning のドキュメントで確認すること。

9提案で使える1行サマリ

「POS UI extensions 2026-10 では、POS が確認できないカート書き込みが reject されるようになります。
気づかれずに起きていた書き込みの取りこぼしがエラーとして見えるので、呼び出し箇所すべてに catch を入れてからバージョンを上げましょう。
間に合わない extension は 2026-07 のままで大丈夫です。」