支払いハンドラ API

W3C作業草案

この文書の詳細について
このバージョン:
https://www.w3.org/TR/2025/WD-payment-handler-20250927/
最新の公開バージョン:
https://www.w3.org/TR/payment-handler/
最新の編集者ドラフト:
https://w3c.github.io/payment-handler/
履歴:
https://www.w3.org/standards/history/payment-handler/
コミット履歴
テストスイート:
https://wpt.live/payment-handler/
編集者:
Ian Jacobs (W3C)
Jinho Bang (招待専門家)
Stephen McGruer (Google)
以前の編集者:
Andre Lyver (Shopify)
Tommy Thorsen (Opera)
Adam Roach (Mozilla)
Rouslan Solomakhin (Google)
Adrian Hope-Bailie (Coil)
フィードバック:
GitHub w3c/payment-handler (プルリクエスト, 新しい issue, オープンな issue)

要旨

この仕様は、Webアプリケーションが支払い要求を処理できる機能を定義します。

この文書の状況

このセクションは、本書の公開時点での状態を説明します。現在の W3C の刊行物の一覧および本技術報告書の最新改訂版は、W3C の標準と草案の索引で確認できます。

Web Payments Working Group は、グループがまだ対応していないすべてのバグ報告の一覧を 管理しています。この草案では、作業部会でまだ議論される保留中のいくつかの問題点を示しています。これらの問題(有効かどうかを含む)の結論についてはまだ決定されていません。未解決の問題に対する仕様案を含むプルリクエストは歓迎されます。

この文書は、Web Payments Working Group によって、勧告トラックを使用した作業草案として公開されました。

作業草案としての公開は、W3C およびそのメンバーによる支持を意味するものではありません。

本書は草案であり、いつでも更新、置換、または他の文書により廃止される可能性があります。本書を作業中の文書以外として引用することは適切ではありません。

本書は、W3C 特許方針の下で運営されるグループによって作成されました。 W3C は、グループの成果物に関連して行われたあらゆる特許開示の 公開リスト を維持しています;そのページには特許を開示するための手順も含まれます。個人が、当該個人が本質的な請求(Essential Claim(s))を含むと信じる特許を実際に知っている場合は、W3C 特許方針の第6節に従ってその情報を開示する必要があります。

この文書は、2025年8月18日 の W3C プロセス文書に従って管理されています。

1. 導入

このセクションは規範ではありません。

この仕様は、Webアプリケーションがユーザーに代わって支払い要求を処理できるようにするためのいくつかの新機能を定義します:

この仕様は、オペレーティングシステム固有の仕組み(いわゆる「ネイティブアプリ」)で作られたソフトウェアがどのように支払い要求を処理するかについては扱いません。

2. 概要

本文書では次のフローを想定します:

  1. あるオリジンが、サポートされる支払い方法の集合について支払い要求を処理するためのユーザー許可を要求します。例えば、ユーザーが小売店や銀行のサイトを訪れたときに、そのオリジンから支払いハンドラを登録するよう促される場合があります。オリジンは権限の範囲を確立しますが、オリジンの機能は追加のユーザー同意を必要とせずに進化する可能性があります。
  2. 支払いハンドラservice workerコード内で定義されます。
  3. 商人(または他の payee)が[payment-request] の canMakePayment() または show() メソッドを呼び出すと(例:ユーザー—payer—がチェックアウトページのボタンを押したとき)、ユーザーエージェントは候補となる支払いハンドラのリストを計算します。これは商人が受け入れる支払い方法と、ユーザーエージェントがさまざまな手段で知っている支払い方法を比較することで行われ、以下を含むがこれらに限定されません:
    • このAPIを通じて以前に登録されたもの。
    • トランザクションの過程でこのAPIを通じて登録される可能性があるもの(例えば、payment method manifestで特定されるもの)。
    • オペレーティングシステムなど、他の仕組みを通じて登録されたもの。
  4. ユーザーエージェントはユーザーに対して候補支払いハンドラの選択肢を表示します。ユーザーエージェントはこれらの選択肢を、登録時に提供された、またはWebアプリから入手可能な情報(ラベルやアイコン)を用いて表示します。
  5. ユーザー(payer)が支払いハンドラを選択すると、ユーザーエージェントは選択された支払いハンドラの PaymentRequestEvent を(user interaction task sourceを参照)選択された支払いハンドラの service worker 内で発火します。PaymentRequestEvent には PaymentRequest([payment-request]で定義) からの情報や、支払い先のオリジンなどの追加情報が含まれます。
  6. 支払いハンドラが起動されると、必要な手順を実行して支払い要求を処理し、適切な支払い応答をpayeeに返します。ユーザーとの対話が必要な場合、支払いハンドラはその目的のためにウィンドウを開くことができます。
  7. 支払いハンドラが要求の処理を終えると、ユーザーエージェントは非同期に応答を受け取ります。その応答は[payment-request]の PaymentResponse になります。

あるオリジンは複数の service worker を用いて支払いアプリを実装することができ、そのためオリジンごとに複数の支払いハンドラが登録される場合があります。どのハンドラが呼び出されるかはユーザーの選択によって決まります。

2.1 支払い要求の処理

このセクションは規範ではありません。

支払いハンドラは、ユーザーに代わって支払い要求を処理できるWebアプリケーションです。

支払いハンドラのロジックは、サポートする支払い方法によって駆動されます。いくつかの支払い方法は支払いハンドラによるほとんど処理を必要とせず、単に支払いカードの詳細を応答として返すだけです。その場合は、返されたデータを入力として支払いを処理するのはpayeeのウェブサイトの役割です。

対照的に、暗号通貨の支払いや銀行発のクレジット振替のように、支払いハンドラが支払いの処理を開始することを要求する支払い方法もあります。そのような場合、支払いハンドラは支払い参照、エンドポイントURL、あるいはpayeeのウェブサイトが支払いの結果を判定するのに使用できるその他のデータを返します(支払い自体を処理するのではなく)。

支払い要求の処理には、多数の相互作用が含まれることがあります:新しいウィンドウや他のAPI(例えばWeb Cryptography API)を通じたユーザーとのやり取り、またはウェブリクエストなどを通じた他のサービスやオリジンとのやり取りなどです。

この仕様は、PaymentRequestEvent を支払いハンドラが受け入れてから支払いハンドラが応答を返すまでに発生するこれらの活動については扱いません。支払いハンドラを構成し支払い要求を処理するために必要となる可能性のあるこれらすべての活動は、支払いハンドラの実装に委ねられます。例えば:

したがって、オリジンはライフサイクル管理、セキュリティ、ユーザー認証、ユーザーとの対話などのために他の多くのWeb技術に依存します。

2.2 他の種類の支払いアプリとの関係

このセクションは規範ではありません。

この仕様は、サードパーティのモバイル支払いアプリがユーザーエージェントとどのように(独自の仕組みを通じて)相互作用するか、あるいはユーザーエージェント自体がどのように簡易的な支払いアプリ機能を提供するかを扱うものではありません。

Different types of payment apps. Payment Handler API is for Web apps.
Figure 1 Payment Handler API は Web アプリが支払いを処理できるようにします。他の種類の支払いアプリは別の(独自の)仕組みを使用する場合があります。

3. 登録

支払いハンドラは、ユーザーエージェントに対してジャストインタイム(JIT)登録メカニズムを通じて登録されます。

3.1 ジャストインタイム登録

支払いハンドラが商人がshow() メソッドを呼び出したときに登録されていない場合、ユーザーエージェントはトランザクション中にユーザーがこの支払いハンドラを登録することを許可する可能性があります(「ジャストインタイム」)。

このセクションの残りの内容は規範ではありません。

ユーザーエージェントは、商人が要求したURLベースの支払い方法識別子を通じて見つかったpayment method manifestから支払いハンドラ情報を導出することにより、ジャストインタイムインストールを実行する場合があります。

4. 管理

本セクションでは、支払いハンドラが自身のプロパティを管理するために利用できる機能を説明します。

4.1 ServiceWorkerRegistration インターフェイスへの拡張

WebIDLpartial interface ServiceWorkerRegistration {
  [SameObject] readonly attribute PaymentManager paymentManager;
};

paymentManager 属性は支払いハンドラ管理機能を公開します。

4.2 PaymentManager インターフェイス

WebIDL[SecureContext, Exposed=(Window)]
interface PaymentManager {
  attribute DOMString userHint;
  Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
};

PaymentManager支払いハンドラが自身のサポートする委任(delegations)を管理するために使用されます。

4.2.1 userHint 属性

支払いハンドラ名とアイコンを表示する際、ユーザーエージェントはこの文字列を用いてユーザー体験を向上させる場合があります。例えば "**** 1234" のような user hint は特定のカードがこの支払いハンドラ経由で利用可能であることをユーザーに思い出させることができます。

4.2.2 enableDelegations() メソッド

このメソッドは支払いハンドラが非同期にサポートするPaymentDelegationのリストを宣言することを可能にします。

4.3 PaymentDelegation 列挙型

WebIDLenum PaymentDelegation {
  "shippingAddress",
  "payerName",
  "payerPhone",
  "payerEmail"
};
"shippingAddress"
支払いハンドラは必要に応じて配送先住所を提供します。
"payerName"
支払いハンドラは必要に応じて支払人の名前を提供します。
"payerPhone"
支払いハンドラは必要に応じて支払人の電話番号を提供します。
"payerEmail"
支払いハンドラは必要に応じて支払人のメールアドレスを提供します。

5. 支払いが可能か

支払いハンドラCanMakePaymentEvent をサポートしている場合、ユーザーエージェントは利用可能な支払いハンドラのフィルタリングに役立てるためにそれを使用してもよい。

実装は、開発者が CanMakePaymentEvent に応答するためのタイムアウトを課す場合がある。タイムアウトが期限切れになった場合、実装は respondWith()false を引数に呼び出されたかのように動作する。

5.1 ServiceWorkerGlobalScope への拡張

WebIDLpartial interface ServiceWorkerGlobalScope {
  attribute EventHandler oncanmakepayment;
};

5.1.1 oncanmakepayment 属性

oncanmakepayment 属性は、対応するイベントハンドライベントハンドラのイベント型が "canmakepayment" であるイベントハンドラである。

5.2 CanMakePaymentEvent

CanMakePaymentEvent は、支払いハンドラが支払い要求に応答できるかどうかのシグナルとして用いられる。

WebIDL[Exposed=ServiceWorker]
interface CanMakePaymentEvent : ExtendableEvent {
  constructor(DOMString type);
  undefined respondWith(Promise<boolean> canMakePaymentResponse);
};

5.2.1 respondWith() メソッド

このメソッドは、支払いハンドラが支払い要求に応答できるかどうかのシグナルとして用いられる。

5.3 CanMakePaymentEvent の処理

PaymentRequest を受信したら、ユーザーエージェントは次の手順をMUST実行する:

  1. ユーザーエージェントの設定が CanMakePaymentEvent の使用を禁止している(例:プライベートブラウジングモードの場合)なら、これらの手順を終了する。
  2. registration を、ServiceWorkerRegistration とする。
  3. registration が見つからない場合、これらの手順を終了する。
  4. 機能イベントを発火 "canmakepayment" を、registration 上で CanMakePaymentEvent を用いて行う。

5.4 CanMakePaymentEvent の処理の例

このセクションは規範ではありません。

この例では、CanMakePaymentEvent を監視する service worker の書き方を示す。CanMakePaymentEvent を受信すると、service worker は常に true を返す。

Example 1: CanMakePaymentEvent の処理
self.addEventListener("canmakepayment", function(e) {
  e.respondWith(new Promise(function(resolve, reject) {
    resolve(true);
  }));
});

5.5 支払いハンドラのフィルタリング

PaymentMethodData と、支払い方法識別子で一致する支払いハンドラが与えられたとき、このアルゴリズムはその支払いハンドラが支払いに使用できる場合に true を返す:

  1. methodName を、PaymentMethodData に指定された支払い方法識別子の文字列とする。
  2. methodData を、PaymentMethodData の支払い方法固有データとする。
  3. paymentHandlerOrigin を、支払いハンドラの ServiceWorkerRegistration のスコープ URL のorigin とする。
  4. paymentMethodManifest を、methodName取り込みおよび解析済みの支払い方法マニフェストとする。
  5. もし methodName が、paymentMethodManifest"*" 文字列のサポートされるオリジンを持つURL ベースの支払い方法識別子であるなら、true を返す。
  6. それ以外で、URL ベースの支払い方法識別子である methodNameoriginpaymentHandlerOrigin と同じである場合、支払いハンドラで CanMakePaymentEvent を発火し、その結果を返す。
  7. それ以外で、paymentMethodManifestサポートされるオリジンpaymentHandlerOrigin を含むorigin の順序付き集合である場合、支払いハンドラで CanMakePaymentEvent を発火し、その結果を返す。
  8. それ以外の場合、false を返す。

6. 呼び出し

ユーザーが支払いハンドラを選択すると、ユーザーエージェントは PaymentRequestEvent を発火し、その後の PaymentHandlerResponse を用いて [payment-request] の PaymentResponse を作成する。

Issue 117: Abort() の委任を Payment Handler でサポートするか

Payment Request API は、中止(abort)の管理責任を支払いアプリに委任することをサポートしている。Payment Handler インターフェイスに paymentRequestAborted イベントを追加する提案がある。このイベントは、paymentRequest が正常に中止されたかどうかを示す boolean パラメータを取る respondWith メソッドを持つ。

6.1 ServiceWorkerGlobalScope への拡張

本仕様は ServiceWorkerGlobalScope インターフェイスを拡張する。

WebIDLpartial interface ServiceWorkerGlobalScope {
  attribute EventHandler onpaymentrequest;
};

6.1.1 onpaymentrequest 属性

onpaymentrequest 属性はイベントハンドラであり、対応するイベントハンドラのイベント型PaymentRequestEvent である。

6.2 PaymentRequestDetailsUpdate 辞書

PaymentRequestDetailsUpdate は、更新された合計(必要に応じて修飾子や配送オプションを含む)および、支払い方法・配送先住所・配送オプションのユーザー選択に起因する可能性のあるエラーを含む。

WebIDLdictionary PaymentRequestDetailsUpdate {
  DOMString error;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  sequence<PaymentShippingOption> shippingOptions;
  object paymentMethodErrors;
  AddressErrors shippingAddressErrors;
};

6.2.1 error メンバー

ユーザーが選択した支払い方法・配送先住所・配送オプションが使用できない理由を説明する、人間が読める文字列。

6.2.2 total メンバー

変更された支払い方法・配送先住所・配送オプションに基づく更新後の合計。例えば、ユーザーが選択した支払い方法の請求先住所により付加価値税(VAT)が変わる場合や、ユーザーが選択・提供した配送オプション/住所により配送料が変わる場合に、合計は変更されうる。

6.2.3 modifiers メンバー

変更された支払い方法・配送先住所・配送オプションに基づく更新後の修飾子。例えば、請求先または配送先住所に基づいて全体の合計が €1.00 増えた場合、各修飾子で指定された合計も €1.00 増えるべきである。

6.2.4 shippingOptions メンバー

変更された配送先住所に基づく更新後の shippingOptions。例えば、ユーザーが提供した国では速達配送がより高価であったり、利用不可であったりする可能性がある。

6.2.5 paymentMethodErrors メンバー

支払い方法に対する検証エラー(存在する場合)。

6.2.6 shippingAddressErrors メンバー

配送先住所に対する検証エラー(存在する場合)。

6.3 PaymentRequestEvent

PaymentRequestEvent は、ユーザーによる選択後に Payment Handler で利用可能なデータとメソッドを表す。ユーザーエージェントは、PaymentRequest で利用可能なデータのサブセットを Payment Handler に伝える。

WebIDL[Exposed=ServiceWorker]
interface PaymentRequestEvent : ExtendableEvent {
  constructor(DOMString type, optional PaymentRequestEventInit eventInitDict = {});
  readonly attribute USVString topOrigin;
  readonly attribute USVString paymentRequestOrigin;
  readonly attribute DOMString paymentRequestId;
  readonly attribute FrozenArray<PaymentMethodData> methodData;
  readonly attribute object total;
  readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
  readonly attribute object? paymentOptions;
  readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions;
  Promise<WindowClient?> openWindow(USVString url);
  Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
  Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(optional AddressInit shippingAddress = {});
  Promise<PaymentRequestDetailsUpdate?> changeShippingOption(DOMString shippingOption);
  undefined respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise);
};

6.3.1 topOrigin 属性

最上位のoriginpayee のウェブページ)の文字列を返す。この属性は、PaymentRequestEvent の処理により初期化される。

6.3.2 paymentRequestOrigin 属性

PaymentRequest が初期化されたorigin を示す文字列を返す。PaymentRequesttopOrigin 内で初期化された場合、両属性は同じ値を持ち、そうでない場合は異なる値を持つ。例えば、PaymentRequesttopOrigin とは異なるオリジンの iframe 内で初期化された場合、この属性の値はその iframe のオリジンとなる。この属性は PaymentRequestEvent の処理 により初期化される。

6.3.3 paymentRequestId 属性

取得時、paymentRequestId 属性は、この PaymentRequestEvent に対応する PaymentRequest[[details]].id を返す。

6.3.4 methodData 属性

この属性には、ウェブサイトが受け入れる支払い方法識別子および関連する各支払い方法固有データを含む PaymentMethodData 辞書が含まれる。これは、下記で定義する MethodData の生成アルゴリズム を用いて PaymentRequest から設定される。

6.3.5 total 属性

この属性は、支払いに要求されている合計額を示す。これは [payment-request] で定義される PaymentCurrencyAmount 辞書型であり、対応する PaymentRequest オブジェクトが生成された際に提供された total フィールドのコピーで初期化される。

6.3.6 modifiers 属性

この PaymentDetailsModifier 辞書の列は、特定の支払い方法識別子に対する修飾子を含む(例:支払い金額や通貨種別が支払い方法ごとに異なる場合)。これは、下記で定義する Modifiers の生成アルゴリズム を用いて PaymentRequest から設定される。

6.3.7 paymentOptions 属性

対応する PaymentRequest における PaymentOptions の値。配送先住所および/または支払人の連絡先情報のいずれかが要求されている場合にのみ利用可能。

6.3.8 shippingOptions 属性

対応する PaymentDetailsInit 辞書における ShippingOptions の値(PaymentDetailsInitPaymentDetailsBase から ShippingOptions を継承する)。配送先住所が要求されている場合にのみ利用可能。

6.3.9 openWindow() メソッド

このメソッドは、支払いハンドラがユーザーにウィンドウを表示するために使用する。呼び出されると、ウィンドウを開くアルゴリズム を実行する。

6.3.10 changePaymentMethod() メソッド

このメソッドは、請求先住所などの支払い方法の詳細が与えられたときに更新後の合計を取得するために、支払いハンドラによって使用される。呼び出されると、支払い方法変更アルゴリズム を実行する。

6.3.11 changeShippingAddress() メソッド

このメソッドは、shippingAddress が与えられたときに更新後の支払い詳細を取得するために、支払いハンドラによって使用される。呼び出されると、支払い詳細変更アルゴリズム を実行する。

6.3.12 changeShippingOption() メソッド

このメソッドは、shippingOption 識別子が与えられたときに更新後の支払い詳細を取得するために、支払いハンドラによって使用される。呼び出されると、支払い詳細変更アルゴリズム を実行する。

6.3.13 respondWith() メソッド

このメソッドは、支払いが正常に完了した際に PaymentHandlerResponse を提供するために、支払いハンドラによって使用される。呼び出されると、eventhandlerResponsePromise を引数として PaymentRequest に応答するアルゴリズム を実行する。

Issue 123: ユーザーデータを支払いアプリと共有すべきか?

支払いアプリは、ユーザーの明示的な同意のもとでユーザーエージェントに保存されたユーザーデータを受け取るべきだろうか? 支払いアプリは、インストール時または初回起動時に権限を要求できる。

6.3.14 PaymentRequestEventInit 辞書

WebIDLdictionary PaymentRequestEventInit : ExtendableEventInit {
  USVString topOrigin;
  USVString paymentRequestOrigin;
  DOMString paymentRequestId;
  sequence<PaymentMethodData> methodData;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  PaymentOptions paymentOptions;
  sequence<PaymentShippingOption> shippingOptions;
};

topOriginpaymentRequestOriginpaymentRequestIdmethodDatatotalmodifierspaymentOptions、 および shippingOptions の各メンバーは、PaymentRequestEvent に定義されたものと同じ定義を共有する。

6.3.15 MethodData の生成アルゴリズム

methodData の値を初期化するために、ユーザーエージェントは次の手順(または同等の手順)を MUST 実行する:

  1. registeredMethods を、起動された支払いハンドラの登録済み支払い方法識別子の集合とする。
  2. 新しい空の Sequence を作成する。
  3. dataList を、新しく作成した Sequence に設定する。
  4. 対応する支払いリクエストにおける PaymentRequest@[[methodData]] の各項目について、次の手順を実行する:
    1. 検討中の項目を inData に設定する。
    2. commonMethods を、inData.supportedMethodsregisteredMethods の積集合に設定する。
    3. commonMethods が空である場合、残りのサブステップをスキップし、次の項目(存在する場合)に進む。
    4. 新しい PaymentMethodData オブジェクトを作成する。
    5. 新しく作成した PaymentMethodDataoutData に設定する。
    6. outData.supportedMethods を、commonMethods のメンバーを含むリストに設定する。
    7. outData.data を、inData.data のコピーに設定する。
    8. outDatadataList に追加する。
  5. methodDatadataList に設定する。

6.3.16 Modifiers の生成アルゴリズム

modifiers の値を初期化するために、ユーザーエージェントは次の手順(または同等の手順)を MUST 実行する:

  1. registeredMethods を、起動された支払いハンドラの登録済み支払い方法識別子の集合とする。
  2. 新しい空の Sequence を作成する。
  3. modifierList を、新しく作成した Sequence に設定する。
  4. 対応する支払いリクエストにおける PaymentRequest@[[paymentDetails]].modifiers の各項目について、次の手順を実行する:
    1. 検討中の項目を inModifier に設定する。
    2. inModifier.supportedMethodsregisteredMethods の積集合を commonMethods に設定する。
    3. commonMethods が空である場合、残りのサブステップをスキップし、次の項目(存在する場合)に進む。
    4. 新しい PaymentDetailsModifier オブジェクトを作成する。
    5. 新しく作成した PaymentDetailsModifieroutModifier に設定する。
    6. outModifier.supportedMethods を、commonMethods のメンバーを含むリストに設定する。
    7. outModifier.total を、 inModifier.total のコピーに設定する。
    8. outModifiermodifierList に追加する。
  5. modifiersmodifierList に設定する。

6.4 内部スロット

PaymentRequestEvent のインスタンスは、次の表の内部スロットを持って作成される:

内部スロット 既定値 説明(規範ではない
[[windowClient]] null 現在アクティブな WindowClient。支払いハンドラが現在ユーザーにウィンドウを表示している場合に設定される。そうでない場合は null。
[[respondWithCalled]] false YAHO

6.5 PaymentRequestEvent の処理

PaymentRequestPaymentRequest.show() によって受け取り、その後ユーザーが支払いハンドラを選択した場合、ユーザーエージェントは次の手順を MUST 実行する:

  1. registration を、ユーザーが選択した支払いハンドラに対応する ServiceWorkerRegistration とする。
  2. registration が見つからない場合、Promise を、PaymentRequest.show() によって作成されたものに対して "InvalidStateError" の DOMException で拒否し、これらの手順を終了する。
  3. 機能イベントを発火 "paymentrequest" を、registration 上で PaymentRequestEvent を用いて、次のプロパティとともに行う:

    topOrigin
    最上位の支払い先ウェブページのオリジンの直列化
    paymentRequestOrigin
    PaymentRequest が初期化されたコンテキストのオリジンの直列化
    methodData
    MethodData の生成アルゴリズム を実行した結果。
    modifiers
    Modifiers の生成アルゴリズム を実行した結果。
    total
    対応する PaymentRequestPaymentDetailsInit 上の total フィールドのコピー。
    paymentRequestId
    PaymentRequest の \[\[details\]\].id
    paymentOptions
    対応する PaymentRequest のコンストラクターに渡された paymentOptions 辞書のコピー。
    shippingOptions
    対応する PaymentRequestPaymentDetailsInit 上の shippingOptions フィールドのコピー。

    その後、dispatchedEvent について並行して次の手順を実行する:

    1. dispatchedEvent寿命延長プロミスに含まれるすべてのプロミスが解決するのを待つ。
    2. もし 支払いハンドラPaymentHandlerResponse を提供していない場合、PromisePaymentRequest.show() によって作成されたもの)を "OperationError" の DOMException で拒否する。

7. Windows

呼び出された支払いハンドラは、自身に関する情報を表示したり、ユーザー入力を求めたりする必要がある場合とない場合がある。支払いハンドラの表示の例としては次のようなものがある:

表示やユーザーとの対話を必要とする 支払いハンドラは、openWindow() を呼び出してユーザーにページを表示できる。

ユーザーエージェントは、このメソッドが PaymentRequestEvent と関連していることを知っているため、ユーザーのフローと整合し、混乱を招かない方法でウィンドウを描画するべきである(SHOULD)。生成されるウィンドウクライアントは、 PaymentRequest を開始したタブ/ウィンドウに結び付けられる。単一の 支払いハンドラが、このメソッドを用いて複数のクライアントウィンドウを開くことは許されるべきではない(SHOULD NOT)。

7.1 ウィンドウを開くアルゴリズム

Issue 115: ウィンドウを開くアルゴリズム

このアルゴリズムは、Service Workers 仕様の ウィンドウを開くアルゴリズム に類似している。

Issue 115: ウィンドウを開くアルゴリズム

手順を転載する代わりに、Service Workers 仕様を参照すべきだろうか?

  1. event を、この PaymentRequestEvent とする。
  2. eventisTrusted 属性が false の場合、"InvalidStateError" の DOMException で拒否された Promise を返す。
  3. request を、この PaymentRequestEvent をトリガーした PaymentRequest とする。
  4. url を、url 引数を parsing した結果とする。
  5. URL のパースで例外がスローされた場合、その例外で拒否された Promise を返す。
  6. urlabout:blank の場合、TypeError で拒否された Promise を返す。
  7. url の origin が、支払いハンドラに関連付けられた service worker の origin と同一でない場合、null で解決された Promise を返す。
  8. promise を新しい Promise とする。
  9. promise を返し、残りの手順を並行して実行する:
  10. event.[[windowClient]] が null でない場合:
    1. event.[[windowClient]].visibilityState が "unloaded" でないなら、promise を "InvalidStateError" の DOMException で拒否し、これらの手順を中止する。
  11. newContext を新しい top-level browsing context とする。
  12. Navigate を用いて、例外有効・置換有効で newContexturl に移動する。
  13. ナビゲーションで例外がスローされた場合、その例外で promise を拒否し、これらの手順を中止する。
  14. newContext の origin が、支払いハンドラに関連付けられた service worker client の origin と同一でない場合:
    1. promise を null で解決する。
    2. これらの手順を中止する。
  15. client を、create window client アルゴリズムを newContext を引数として実行した結果とする。
  16. event.[[windowClient]]client を設定する。
  17. promiseclient で解決する。

7.2 PaymentRequestEvent の処理の例

このセクションは規範ではありません。

この例では、PaymentRequestEvent を監視する service worker の書き方を示す。PaymentRequestEvent を受信すると、service worker はユーザーとの対話のためにウィンドウを開く。

Example 2: PaymentRequestEvent の処理
async function getPaymentResponseFromWindow() {
  return new Promise((resolve, reject) => {
    self.addEventListener("message", listener = e => {
      self.removeEventListener("message", listener);
      if (!e.data || !e.data.methodName) {
        reject();
        return;
      }
      resolve(e.data);
    });
  });
}

self.addEventListener("paymentrequest", e => {
  e.respondWith((async() => {
    // Open a new window for providing payment UI to user.
    const windowClient = await e.openWindow("payment_ui.html");

    // Send data to the opened window.
    windowClient.postMessage({
      total: e.total,
      modifiers: e.modifiers
    });

    // Wait for a payment response from the opened window.
    return await getPaymentResponseFromWindow();
  })());
});

上記のシンプルな仕組みを用いると、支払いハンドラのウィンドウに読み込まれる簡単な HTML ページは次のようになる:

Example 3: シンプルな Payment Handler ウィンドウ
<form id="form">
<table>
  <tr><th>Cardholder Name:</th><td><input name="cardholderName"></td></tr>
  <tr><th>Card Number:</th><td><input name="cardNumber"></td></tr>
  <tr><th>Expiration Month:</th><td><input name="expiryMonth"></td></tr>
  <tr><th>Expiration Year:</th><td><input name="expiryYear"></td></tr>
  <tr><th>Security Code:</th><td><input name="cardSecurityCode"></td></tr>
  <tr><th></th><td><input type="submit" value="Pay"></td></tr>
</table>
</form>

<script>
navigator.serviceWorker.addEventListener("message", e => {
  /* Note: message sent from payment app is available in e.data */
});

document.getElementById("form").addEventListener("submit", e => {
  const details = {};
  ["cardholderName", "cardNumber", "expiryMonth", "expiryYear", "cardSecurityCode"]
  .forEach(field => {
    details[field] = form.elements[field].value;
  });

  const paymentAppResponse = {
    methodName: "https://example.com/pay",
    details
  };

  navigator.serviceWorker.controller.postMessage(paymentAppResponse);
  window.close();
});
</script>

8. 応答

8.1 PaymentHandlerResponse 辞書

PaymentHandlerResponse は、次の辞書を用いて伝達される:
WebIDLdictionary PaymentHandlerResponse {
DOMString methodName;
object details;
DOMString? payerName;
DOMString? payerEmail;
DOMString? payerPhone;
AddressInit shippingAddress;
DOMString? shippingOption;
};

8.1.1 methodName 属性

取引を完了するためにユーザーが選択した 支払い方法識別子(当該 支払い方法のもの)。

8.1.2 details 属性

販売者が取引を処理し、資金移動の成功を判断するために用いる、支払い方法固有のメッセージを提供する、JSON で直列化可能なオブジェクト。

ユーザーエージェントは、対応する respondWith 関数に渡された Promise が解決されることで、支払いハンドラから成功応答を受け取る。 アプリケーションは、支払い応答を含む PaymentHandlerResponse インスタンスで Promise を解決することが期待される。ユーザーによるキャンセルやエラーの場合、アプリケーションは Promise を拒否して失敗を通知してもよい。

Promise が拒否された場合、ユーザーエージェントは MUST payment app failure algorithm を実行する。このアルゴリズムの正確な詳細は実装者に委ねられる。許容される動作には、次のようなものが含まれる(これらに限定されない):

  • 同じ支払いハンドラまたは別のものを使って、ユーザーに再試行させる。
  • PaymentRequest.show() によって作成された Promise を拒否する。

8.1.3 payerName 属性

ユーザーが提供した支払人の氏名。

8.1.4 payerEmail 属性

ユーザーが提供した支払人のメールアドレス。

8.1.5 payerPhone 属性

ユーザーが提供した支払人の電話番号。

8.1.6 shippingAddress 属性

ユーザーが提供した配送先住所。

8.1.7 shippingOption 属性

ユーザーが選択した配送オプションの識別子。

8.2 支払い方法変更アルゴリズム

このアルゴリズムが methodName および methodDetails のパラメータで呼び出されたとき、ユーザーエージェントは次の手順を MUST 実行する:

  1. payment method changed algorithm を、与えられた methodName および methodDetails パラメータを用いて構築した PaymentMethodChangeEvent event で実行する。
  2. event.updateWith(detailsPromise) が実行されなかった場合、null を返す。
  3. event.updateWith(detailsPromise) が例外を投げた場合、そのエラーを再スローする。
  4. event.updateWith(detailsPromise) がタイムアウトした場合(任意)、"InvalidStateError" の DOMException を投げる。
  5. event.updateWith(detailsPromise)detailsPromise から、PaymentRequestDetailsUpdate を構築して返す。

8.3 支払い詳細変更アルゴリズム

このアルゴリズムが shippingAddress または shippingOption で呼び出されたとき、ユーザーエージェントは次の手順を MUST 実行する:

  1. PaymentRequest updated algorithm を、更新された詳細(shippingAddress または shippingOption)を用いて構築した PaymentRequestUpdateEvent event で実行する。
  2. event.updateWith(detailsPromise) が実行されなかった場合、null を返す。
  3. event.updateWith(detailsPromise) が例外を投げた場合、そのエラーを再スローする。
  4. event.updateWith(detailsPromise) がタイムアウトした場合(任意)、"InvalidStateError" の DOMException を投げる。
  5. event.updateWith(detailsPromise)detailsPromise から、PaymentRequestDetailsUpdate を構築して返す。

8.4 PaymentRequest に応答するアルゴリズム

このアルゴリズムが event および handlerResponsePromise のパラメータで呼び出されたとき、ユーザーエージェントは次の手順を MUST 実行する:

  1. eventisTrusted が false の場合、"InvalidStateError" の DOMException を投げ、これらの手順を中止する。
  2. eventdispatch flag が未設定の場合、"InvalidStateError" の DOMException を投げ、これらの手順を中止する。
  3. event.[[respondWithCalled]] が true の場合、"InvalidStateError" の DOMException を投げ、これらの手順を中止する。
  4. event.[[respondWithCalled]] を true に設定する。
  5. eventstop propagation flageventstop immediate propagation flag を設定する。
  6. handlerResponsePromiseeventextend lifetime promises に追加する。
  7. eventpending promises count を 1 増やす。
  8. Upon rejectionhandlerResponsePromise が拒否されたとき):
    1. payment app failure algorithm を実行し、これらの手順を終了する。
  9. Upon fulfillmenthandlerResponsePromise が履行されたとき):
    1. handlerResponse を、value を IDL 値 PaymentHandlerResponse変換 したものとする。これが例外を投げた場合、payment app failure algorithm を実行し、これらの手順を終了する。
    2. handlerResponse に必須メンバーがすべて存在し、正しく整形されていることを検証する。
      1. handlerResponse.methodName が存在しない、または event.methodData の値のいずれにも設定されていない場合、 payment app failure algorithm を実行し、これらの手順を終了する。
      2. handlerResponse.details が存在しない、または JSON で直列化可能 でない場合、payment app failure algorithm を実行し、これらの手順を終了する。
      3. shippingRequired を、関連する PaymentRequest の requestShipping の値とする。shippingRequired であり、かつ handlerResponse.shippingAddress が存在しない場合、payment app failure algorithm を実行し、これらの手順を終了する。
      4. shippingRequired であり、かつ handlerResponse.shippingOption が存在しない、または event.shippingOptions の識別子のいずれにも設定されていない場合、payment app failure algorithm を実行し、これらの手順を終了する。
      5. payerNameRequired を、関連する PaymentRequest の requestPayerName の値とする。payerNameRequired であり、 handlerResponse.payerName が存在しない場合、payment app failure algorithm を実行し、これらの手順を終了する。
      6. payerEmailRequired を、関連する PaymentRequest の requestPayerEmail の値とする。payerEmailRequired であり、 handlerResponse.payerEmail が存在しない場合、payment app failure algorithm を実行し、これらの手順を終了する。
      7. payerPhoneRequired を、関連する PaymentRequest の requestPayerPhone の値とする。payerPhoneRequired であり、 handlerResponse.payerPhone が存在しない場合、payment app failure algorithm を実行し、これらの手順を終了する。
    3. handlerResponse の必須メンバーを直列化する(methodNamedetails は常に必須。 shippingRequired が true のときは shippingAddressshippingOption も必須。 payerNameRequiredpayerEmailRequiredpayerPhoneRequired がそれぞれ true のときは、 payerNamepayerEmailpayerPhone も必須。):
      1. handlerResponse の各 member について、 serializeMemberStructuredSerializehandlerResponse.member に対して実行した結果とする。発生した例外は再スローする。
    4. ユーザーエージェントは、[payment-request] で定義される user accepts the payment request algorithm を実行し、手順 9〜15 を以下の手順(または同等の手順)に置き換え MUST 実行する。
      1. 直列化されたメンバーを逆直列化する:
        1. serializeMember について、 memberStructuredDeserializeserializeMember に対して実行した結果とする。発生した例外は再スローする。
      2. 上記の手順でいずれかの例外が発生した場合、payment app failure algorithm を実行し、これらの手順を終了する。
      3. methodName を、関連する PaymentRequest の response.methodName に代入する。
      4. details を、関連する PaymentReqeust の response.details に代入する。
      5. shippingRequired の場合、関連する PaymentReqeust の shippingAddress 属性に shippingAddress を設定する。そうでない場合は null を設定する。
      6. shippingRequired の場合、関連する PaymentReqeust の shippingOption 属性に shippingOption を設定する。そうでない場合は null を設定する。
      7. payerNameRequired の場合、関連する PaymentReqeust の payerName 属性に payerName を設定する。そうでない場合は null を設定する。
      8. payerEmailRequired の場合、関連する PaymentReqeust の payerEmail 属性に payerEmail を設定する。そうでない場合は null を設定する。
      9. payerPhoneRequired の場合、関連する PaymentReqeust の payerPhone 属性に payerPhone を設定する。そうでない場合は null を設定する。
  10. Upon fulfillment または upon rejection のいずれかで handlerResponsePromise が完了したら、次の手順を実行するために マイクロタスクをキューに入れる:
    1. eventpending promises count を 1 減らす。
    2. registration を、 thisrelevant global object に関連付けられた service workercontaining service worker registration とする。
    3. registration が null でない場合、Try Activateregistration で呼び出す。

次の例は、支払い要求に応答する方法を示す:

Example 4: 支払い応答の送信
paymentRequestEvent.respondWith(new Promise(function(accept,reject) {
  /* ... processing may occur here ... */
  accept({
    methodName: "https://example.com/pay",
    details: {
      cardHolderName:   "John Smith",
      cardNumber:       "1232343451234",
      expiryMonth:      "12",
      expiryYear :      "2020",
      cardSecurityCode: "123"
     },
    shippingAddress: {
      addressLine: [
        "1875 Explorer St #1000",
      ],
      city: "Reston",
      country: "US",
      dependentLocality: "",
      organization: "",
      phone: "+15555555555",
      postalCode: "20190",
      recipient: "John Smith",
      region: "VA",
      sortingCode: ""
    },
    shippingOption: "express",
    payerEmail: "john.smith@gmail.com",
  });
}));

[payment-request] は、エコシステム内の関係者(支払いアプリ提供者や支払い先を含む)が、ネットワーク障害やその他の障害後の照合に用いることができる ID を定義している。

9. セキュリティおよびプライバシーに関する考慮事項

9.1 住所

Web Payments Working Group は、プライバシー上の問題により Payment Request API の初期版から配送先住所および請求先住所のサポートを削除しました(issue 842 を参照)。この機能を引き続きサポートする実装に関する文書を提供するため、作業部会はプライバシー問題に対処することを前提として当該機能を復元しています。その過程で、他の API(例:Content Picker API)の進化に基づき、Payment Request API に変更を加える可能性もあります。

9.2 ユーザー環境に関する情報

9.5 クロスオリジンでのデータ共有に関するユーザーの認識

9.6 安全な通信

9.7 認可された支払いアプリ

9.8 サポートされるオリジン

9.9 データ検証

9.10 プライベートブラウジングモード

10. 支払いハンドラの表示に関する考慮事項

このセクションは規範ではありません。

支払いハンドラの順序付けにおいて、ユーザーエージェントは他の優先度よりもユーザーの優先設定を尊重することが期待されます。ユーザーエージェントは、オリジン単位またはすべてのオリジンに対して、優先する支払いハンドラの表示順序を設定するなど、手動構成オプションを提供することが期待されます。

ユーザー体験に関する詳細は実装者に委ねられます。

11. 依存関係

本仕様は、いくつかの基礎となる仕様に依存します。

Payment Request API
用語 payment methodPaymentRequestPaymentResponsesupportedMethodsPaymentCurrencyAmountpaymentDetailsModifierpaymentDetailsInitpaymentDetailsBasePaymentMethodDataPaymentOptionsPaymentShippingOptionAddressInitAddressErrorsPaymentMethodChangeEventPaymentRequestUpdateEventIDcanMakePayment()show()updateWith(detailsPromise)user accepts the payment request algorithmpayment method changed algorithmPaymentRequest updated algorithm、および JSON-serializable は、 Payment Request API 仕様 [payment-request] によって定義されています。
ECMAScript
用語 internal slot および JSON.stringify は、 [ECMASCRIPT] によって定義されています。
Payment Method Manifest
用語 payment method manifestingest payment method manifestparsed payment method manifest、および supported origins は、Payment Method Manifest 仕様 [payment-method-manifest] によって定義されています。
Service Workers
用語 service workerservice worker registrationservice worker clientServiceWorkerRegistrationServiceWorkerGlobalScopefire functional eventextend lifetime promisespending promises countcontaining service worker registrationTry Clear RegistrationTry ActivateExtendableEventExtendableEventInit、 および scope URL は、 [SERVICE-WORKERS] で定義されています。

12. 準拠

非規範(non-normative)と明記されたセクションに加え、本仕様に含まれるすべてのオーサリングガイドライン、図、例、および注記は非規範です。それ以外のすべては規範です。

本文書におけるキーワード MAYMUSTSHOULD、 および SHOULD NOT は、 BCP 14 [RFC2119] および [RFC8174] に従って、ここに示すようにすべて大文字で記載されている場合に限り解釈されます。

本仕様に準拠を主張できる製品クラスは 1 種類のみです:ユーザーエージェント

ユーザーエージェントは、本仕様で示されるアルゴリズムとは異なる方法でそれらを実装してもよい(MAY)ですが、最終的な結果が仕様のアルゴリズムによって得られる結果と区別できないことが条件です。

ユーザーエージェントは、サービス妨害攻撃の防止、メモリ枯渇の防止、プラットフォーム固有の制限への対処などのため、その他は無制限の入力に実装固有の制限を課してもよい(MAY)。入力が実装固有の制限を超えた場合、ユーザーエージェントは MUST 例外を投げるか、Promise の文脈では TypeError で拒否し、特定の入力がどのように制限を超えたかを開発者に任意で知らせます。

A. IDL インデックス

WebIDLpartial interface ServiceWorkerRegistration {
  [SameObject] readonly attribute PaymentManager paymentManager;
};

[SecureContext, Exposed=(Window)]
interface PaymentManager {
  attribute DOMString userHint;
  Promise<undefined> enableDelegations(sequence<PaymentDelegation> delegations);
};

enum PaymentDelegation {
  "shippingAddress",
  "payerName",
  "payerPhone",
  "payerEmail"
};

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler oncanmakepayment;
};

[Exposed=ServiceWorker]
interface CanMakePaymentEvent : ExtendableEvent {
  constructor(DOMString type);
  undefined respondWith(Promise<boolean> canMakePaymentResponse);
};

partial interface ServiceWorkerGlobalScope {
  attribute EventHandler onpaymentrequest;
};

dictionary PaymentRequestDetailsUpdate {
  DOMString error;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  sequence<PaymentShippingOption> shippingOptions;
  object paymentMethodErrors;
  AddressErrors shippingAddressErrors;
};

[Exposed=ServiceWorker]
interface PaymentRequestEvent : ExtendableEvent {
  constructor(DOMString type, optional PaymentRequestEventInit eventInitDict = {});
  readonly attribute USVString topOrigin;
  readonly attribute USVString paymentRequestOrigin;
  readonly attribute DOMString paymentRequestId;
  readonly attribute FrozenArray<PaymentMethodData> methodData;
  readonly attribute object total;
  readonly attribute FrozenArray<PaymentDetailsModifier> modifiers;
  readonly attribute object? paymentOptions;
  readonly attribute FrozenArray<PaymentShippingOption>? shippingOptions;
  Promise<WindowClient?> openWindow(USVString url);
  Promise<PaymentRequestDetailsUpdate?> changePaymentMethod(DOMString methodName, optional object? methodDetails = null);
  Promise<PaymentRequestDetailsUpdate?> changeShippingAddress(optional AddressInit shippingAddress = {});
  Promise<PaymentRequestDetailsUpdate?> changeShippingOption(DOMString shippingOption);
  undefined respondWith(Promise<PaymentHandlerResponse> handlerResponsePromise);
};

dictionary PaymentRequestEventInit : ExtendableEventInit {
  USVString topOrigin;
  USVString paymentRequestOrigin;
  DOMString paymentRequestId;
  sequence<PaymentMethodData> methodData;
  PaymentCurrencyAmount total;
  sequence<PaymentDetailsModifier> modifiers;
  PaymentOptions paymentOptions;
  sequence<PaymentShippingOption> shippingOptions;
};

dictionary PaymentHandlerResponse {
DOMString methodName;
object details;
DOMString? payerName;
DOMString? payerEmail;
DOMString? payerPhone;
AddressInit shippingAddress;
DOMString? shippingOption;
};

B. 参考文献

B.1 規範的参照

[dom]
DOM Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMASCRIPT]
ECMAScript Language Specification. Ecma International. URL: https://tc39.es/ecma262/multipage/
[HTML]
HTML Standard. Anne van Kesteren; Domenic Denicola; Dominic Farolino; Ian Hickson; Philip Jägenstedt; Simon Pieters. WHATWG. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[payment-method-id]
Payment Method Identifiers. Marcos Caceres. W3C. 8 September 2022. W3C Recommendation. URL: https://www.w3.org/TR/payment-method-id/
[payment-method-manifest]
Payment Method Manifest. Dapeng(Max) Liu; Domenic Denicola; Zach Koch. W3C. 12 December 2017. FPWD. URL: https://www.w3.org/TR/payment-method-manifest/
[payment-request]
Payment Request API. Marcos Caceres; Rouslan Solomakhin; Ian Jacobs. W3C. 15 August 2025. CRD. URL: https://www.w3.org/TR/payment-request/
[RFC2119]
Key words for use in RFCs to Indicate Requirement Levels. S. Bradner. IETF. March 1997. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc2119
[RFC8174]
Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words. B. Leiba. IETF. May 2017. Best Current Practice. URL: https://www.rfc-editor.org/rfc/rfc8174
[SERVICE-WORKERS]
Service Workers. Yoshisato Yanagisawa; Monica CHINTALA. W3C. 6 March 2025. CRD. URL: https://www.w3.org/TR/service-workers/
[URL]
URL Standard. Anne van Kesteren. WHATWG. Living Standard. URL: https://url.spec.whatwg.org/
[WEBIDL]
Web IDL Standard. Edgar Chen; Timothy Gu. WHATWG. Living Standard. URL: https://webidl.spec.whatwg.org/

B.2 参考文献

[WebCryptoAPI]
Web Cryptography API. Mark Watson. W3C. 26 January 2017. W3C Recommendation. URL: https://www.w3.org/TR/WebCryptoAPI/