Service Worker でオプションの支払い情報を処理する

ウェブベースの決済アプリをウェブ決済に適応させ、顧客に優れたユーザー エクスペリエンスを提供する方法。

ウェブベースの決済アプリが支払いリクエストを受け取り、支払い取引を開始すると、サービス ワーカーは販売者と決済アプリ間の通信のハブとして機能します。この投稿では、決済アプリがサービス ワーカーを使用して、お支払い方法、配送先住所、連絡先情報を販売者に渡す方法について説明します。

サービス ワーカーでオプションのお支払い情報を処理する
サービス ワーカーでオプションのお支払い情報を処理する

販売者に伝える

以下の変更について販売者に伝えることが重要です。

お支払い方法の変更

決済アプリは、異なるお支払い方法で複数の支払い方法をサポートできます。

お客様 お支払い方法 支払い方法
A クレジット カード発行会社 1 ****1234
クレジット カード発行会社 1 ****4242
銀行 X ******123
B クレジット カード発行会社 2 ****5678
銀行 X ******456

たとえば、上の表では、顧客 A のウェブベースのウォレットに 2 枚のクレジット カードと 1 つの銀行口座が登録されています。この場合、アプリは 3 つの支払い方法(****1234、****4242、******123)と 2 つの支払い方法(クレジット カード発行会社 1 と銀行 X)を処理しています。支払い取引で、決済アプリは、顧客が支払い方法の 1 つを選択して、それを使用して販売者に支払うことができるようにします。

お支払い方法選択ツールの UI
お支払い方法選択ツールの UI

決済アプリは、完全な支払いレスポンスを送信する前に、購入者が選択したお支払い方法を販売者に通知できます。これは、たとえば、販売者が特定のお支払い方法ブランドの割引キャンペーンを実施する場合に便利です。

ウェブベースの Payment Handler API を使用すると、決済アプリはサービス ワーカーを介して「お支払い方法の変更」イベントを販売者に送信し、新しいお支払い方法の識別子を通知できます。サービス ワーカーは、新しいお支払い方法の情報を使用して PaymentRequestEvent.changePaymentMethod() を呼び出す必要があります。

お支払い方法の変更を販売者に通知する
お支払い方法の変更を販売者に通知する

決済アプリは、PaymentRequestEvent.changePaymentMethod() のオプションの 2 番目の引数として methodDetails オブジェクトを渡すことができます。このオブジェクトには、販売者が変更イベントを処理するために必要な任意の支払い方法の詳細を含めることができます。

[payment handler] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'PAYMENT_METHOD_CHANGED':
        const newMethod = e.data.paymentMethod;
        const newDetails = e.data.methodDetails;
        // Redact or check that no sensitive information is passed in
        // `newDetails`.
        // Notify the merchant of the payment method change
        details =
          await payment_request_event.changePaymentMethod(newMethod, newDetails);
      …

販売者は、Payment Request API から paymentmethodchange イベントを受け取ると、支払い情報を更新し、PaymentDetailsUpdate オブジェクトで応答できます。

[merchant]

request.addEventListener('paymentmethodchange', e => {
  if (e.methodName === 'another-pay') {
    // Apply $10 discount for example.
    const discount = {
      label: 'special discount',
      amount: {
        currency: 'USD',
        // The value being string complies the spec
        value: '-10.00'
      }
    };
    let total = 0;
    details.displayItems.push(discount);
    for (let item of details.displayItems) {
     total += parseFloat(item.amount.value);
    }
    // Convert the number back to string
    details.total.amount.value = total.toString();
  }
  // Pass a promise to `updateWith()` and send updated payment details
  e.updateWith(details);
});

販売者が応答すると、PaymentRequestEvent.changePaymentMethod() が返した Promise が PaymentRequestDetailsUpdate オブジェクトで解決されます。

[payment handler] service-worker.js

…
        // Notify the merchant of the payment method change
        details = await payment_request_event.changePaymentMethod(newMethod, newDetails);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

このオブジェクトを使用して、フロントエンドの UI を更新します。更新されたお支払い情報を反映するをご覧ください。

配送先住所の変更

決済アプリは、支払い取引の一環として、お客様の配送先住所を販売者に提供できます。

これは、住所の収集を決済アプリに委任できるため、販売者にとって便利です。また、住所データは標準のデータ形式で提供されるため、販売者は一貫した構造で配送先住所を受け取ることができます。

また、お客様は、お好みの決済アプリに住所情報を登録し、別の販売者で再利用することもできます。

配送先住所選択ツールの UI
配送先住所選択ツールの UI

決済アプリは、配送先住所を編集したり、決済取引でお客様の事前登録済みの住所情報を選択したりするための UI を提供できます。配送先住所が一時的に決定されると、決済アプリは、編集された住所情報を販売者に通知できます。これにより、販売者には次のようなメリットがあります。

  • 販売者は、購入者が商品の配送に関する地域制限(国内のみなど)を満たしているかどうかを判断できます。
  • 販売者は、配送先住所の地域に基づいて配送オプションのリストを変更できます(例: 国際通常配送、国際速達配送)。
  • 販売者は、住所に基づいて新しい送料を適用し、合計金額を更新できます。

ウェブベースの Payment Handler API を使用すると、決済アプリはサービス ワーカーから販売者に「配送先住所の変更」イベントを送信して、新しい配送先住所を通知できます。サービス ワーカーは、新しいアドレス オブジェクトを使用して PaymentRequestEvent.changeShippingAddress() を呼び出す必要があります。

配送先住所の変更を販売者に通知する
配送先住所の変更を販売者に通知する

[payment handler] service-worker.js

...
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_ADDRESS_CHANGED':
        const newAddress = e.data.shippingAddress;
        details =
          await payment_request_event.changeShippingAddress(newAddress);
      …

重要用語: 削除された住所。この場合、販売者に配送先住所のすべてを伝える必要はなく、お客様のプライバシーを侵害するリスクがあります。販売者には、送料の決定に必要な住所の一部のみが提供されます。具体的には、ブラウザは、販売者の DOM で shippingaddresschange イベントを発生させる前に、決済アプリから提供されたアドレスの organization、phone、recipient、addressLine フィールドをクリアします。

販売者は Payment Request API から shippingaddresschange イベントを受け取り、更新された PaymentDetailsUpdate で応答できます。

[merchant]

request.addEventListener('shippingaddresschange', e => {
  // Read the updated shipping address and update the request.
  const addr = request.shippingAddress;
  const details = getPaymentDetailsFromShippingAddress(addr);
  // `updateWith()` sends back updated payment details
  e.updateWith(details);
});

販売者が応答すると、返された Promise PaymentRequestEvent.changeShippingAddress() が PaymentRequestDetailsUpdate オブジェクトで解決されます。

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping address change
        details = await payment_request_event.changeShippingAddress(newAddress);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

このオブジェクトを使用して、フロントエンドの UI を更新します。更新されたお支払い情報を反映するをご覧ください。

配送オプションの変更について販売者に通知する

配送方法とは、販売者が購入された商品をお客様に配送するために使用する方法です。一般的な配送方法には、次のようなものがあります。

  • 送料無料
  • エクスプレス配送
  • 国外配送について
  • プレミアム国際配送

それぞれに費用がかかります。通常、より高速な方法やオプションほど費用が高くなります。

Payment Request API を使用する販売者は、この選択を決済アプリに委任できます。決済アプリは、この情報を使用して UI を構築し、購入者が配送オプションを選択できるようにします。

配送オプション選択ツールの UI
配送オプション選択ツールの UI

販売者の Payment Request API で指定された配送オプションのリストは、PaymentRequestEvent のプロパティとして決済アプリのサービス ワーカーに伝播されます。

[merchant]

const request = new PaymentRequest([{
  supportedMethods: 'https://bobbucks.dev/pay',
  data: { transactionId: '****' }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  shippingOptions: [{
    id: 'standard',
    label: 'Standard',
    amount: { value: '0.00', currency: 'USD' },
    selected: true
  }, {
    id: 'express',
    label: 'Express',
    amount: { value: '5.00', currency: 'USD' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {  requestShipping: true });

決済アプリは、購入者が選択した配送オプションを販売者に知らせることができます。配送オプションを変更すると合計金額も変わるため、これは販売者と購入者の両方にとって重要です。販売者は、後でお支払い確認のために最新の価格を通知する必要があります。また、お客様も変更を認識する必要があります。

Payment Handler API を使用すると、決済アプリは Service Worker から販売者に「配送オプションの変更」イベントを送信できます。サービス ワーカーは、新しい配送オプション ID を指定して PaymentRequestEvent.changeShippingOption() を呼び出す必要があります。

配送オプションの変更について販売者に通知する
配送オプションの変更について販売者に通知する

[payment handler] service-worker.js

…
// Received a message from the frontend
self.addEventListener('message', async e => {
  let details;
  try {
    switch (e.data.type) {
      …
      case 'SHIPPING_OPTION_CHANGED':
        const newOption = e.data.shippingOptionId;
        details =
          await payment_request_event.changeShippingOption(newOption);
      …

販売者は、Payment Request API から shippingoptionchange イベントを受け取ります。販売者は、この情報を使用して合計金額を更新し、更新された PaymentDetailsUpdate を返します。

[merchant]

request.addEventListener('shippingoptionchange', e => {
  // selected shipping option
  const shippingOption = request.shippingOption;
  const newTotal = {
    currency: 'USD',
    label: 'Total due',
    value: calculateNewTotal(shippingOption),
  };
  // `updateWith()` sends back updated payment details
  e.updateWith({ total: newTotal });
});

販売者が応答すると、PaymentRequestEvent.changeShippingOption() が返した Promise が PaymentRequestDetailsUpdate オブジェクトで解決されます。

[payment handler] service-worker.js

…
        // Notify the merchant of the shipping option change
        details = await payment_request_event.changeShippingOption(newOption);
        // Provided the new payment details,
        // send a message back to the frontend to update the UI
        postMessage('UPDATE_REQUEST', details);
        break;
…

このオブジェクトを使用して、フロントエンドの UI を更新します。更新されたお支払い情報を反映するをご覧ください。

更新されたお支払い情報を反映する

販売者が支払い情報の更新を完了すると、.changePaymentMethod()、.changeShippingAddress()、.changeShippingOption() から返された Promise は、共通の PaymentRequestDetailsUpdate オブジェクトで解決されます。支払いハンドラは、この結果を使用して、更新された合計金額と配送オプションを UI に反映できます。

販売者がエラーを返す理由はいくつかあります。

  • お支払い方法が利用できない。
  • 配送先住所がサポート対象の地域外である。
  • 配送先住所に無効な情報が含まれている。
  • 指定された配送先住所またはその他の理由により、配送オプションを選択できません。

次のプロパティを使用して、エラー ステータスを反映します。

  • error: 人が読める形式のエラー文字列。これは、お客様に表示するのに最適な文字列です。
  • shippingAddressErrors: AddressErrors オブジェクト。アドレス プロパティごとの詳細なエラー文字列が含まれます。これは、お客様が住所を編集できるフォームを開き、無効なフィールドを直接示す必要がある場合に便利です。
  • paymentMethodErrors: お支払い方法固有のエラー オブジェクト。販売者に構造化エラーを提供するよう依頼することもできますが、ウェブ決済仕様の作成者は、シンプルな文字列にすることをおすすめしています。