Service Worker での支払い情報(省略可)の処理

ウェブベースの支払いアプリをウェブ支払いに対応させて、ユーザー エクスペリエンスを向上させる方法。

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

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

お支払い方法の変更を販売者に伝える

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

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

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

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

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

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

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

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

[支払いハンドラ] 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() を呼び出す必要があります。

配送先住所の変更を販売者に伝える
配送先住所の変更を販売者に伝えます

[支払いハンドラ] 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);
      

販売者は 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 オブジェクトで解決されます。

[支払いハンドラ] 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() を呼び出す必要があります。

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

[支払いハンドラ] 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: 支払い方法固有のエラー オブジェクト。販売者に構造化エラーを提供するよう依頼できますが、Web Payments 仕様の作成者は、単純な文字列のままにすることを推奨しています。

サンプルコード

このドキュメントで紹介したサンプルコードのほとんどは、次の動作するサンプルアプリからの抜粋です。

https://paymenthandler-demo.glitch.me

[payment handler] service worker

[payment handler] フロントエンド

試すには:

  1. https://paymentrequest-demo.glitch.me/ にアクセスします。
  2. ページの一番下までスクロールします。
  3. [お支払い方法を追加] ボタンを押します。
  4. [Payment Method Identifier] フィールドに「https://paymenthandler-demo.glitch.me」と入力します。
  5. フィールドの横にある [支払い] ボタンを押します。