與服務工作人員處理選擇性付款資訊

如何將網頁版付款應用程式改用 Web Payments,為客戶提供更優質的使用者體驗。

以網頁為基礎的付款應用程式收到付款要求並發起付款交易後,服務工作者就會擔任商家與付款應用程式之間通訊的樞紐。這篇文章將說明付款應用程式如何使用服務工作者,將付款方式、運送地址或聯絡資訊等資訊傳遞給商家。

使用服務工作者處理選用付款資訊
使用服務工作者處理選用付款資訊

通知商家付款方式已變更

付款應用程式可支援多種付款工具,並提供多種付款方式。

客戶 付款方式 付款方式
A 發卡機構 1 ****1234
發卡機構 1 ****4242
銀行 X ******123
B 發卡機構 2 ****5678
銀行 X ******456

舉例來說,在上述表格中,客戶 A 的網路錢包有兩張信用卡和一個已註冊的銀行帳戶。在本例中,應用程式會處理三種付款工具 (****1234****4242******123) 和兩種付款方式 (發卡機構 1 和銀行 X)。在付款交易中,付款應用程式可讓消費者選擇一種付款工具,並用於向商家付款。

付款方式挑選器 UI
付款方式選擇器 UI

付款應用程式可在傳送完整付款回應之前,讓商家知道客戶選擇了哪種付款方式。舉例來說,如果商家想針對特定付款方式品牌放送折扣廣告活動,這項功能就很實用。

透過 Payment Handler API,付款應用程式可透過服務工作者將「付款方式變更」事件傳送給商家,以通知新的付款方式 ID。服務工作者應使用新的付款方式資訊叫用 PaymentRequestEvent.changePaymentMethod()

通知商家付款方式已變更
通知商家付款方式已變更

付款應用程式可以將 methodDetails 物件傳遞為 PaymentRequestEvent.changePaymentMethod() 的選用第二個引數。這個物件可包含商家處理變更事件所需的任意付款方式詳細資料。

[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);
     

商家收到 PaymentRequest 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() 傳回的承諾會以 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);
     

商家會從 PaymentRequest 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);
});

商家回應後,系統會傳回承諾 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,付款應用程式可透過服務工作者向商家傳送「運送選項變更」事件。服務工作者應使用新的運送選項 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() 傳回的承諾會以 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() 傳回的承諾,會以常見的 PaymentRequestDetailsUpdate 物件解析。付款處理程式可以使用結果,將更新後的總價和運送選項反映在 UI 中。

商家可能會因以下幾個原因傳回錯誤:

  • 付款方式不符合規定。
  • 運送地址不在支援的地區範圍內。
  • 運送地址包含無效資訊。
  • 由於提供的運送地址或其他原因,無法選取運送選項。

請使用下列屬性反映錯誤狀態:

  • error:人類可讀的錯誤字串。這是向客戶顯示的最佳字串。
  • shippingAddressErrorsAddressErrors 物件,其中包含每個地址屬性的詳細錯誤字串。如果您想開啟表單,讓客戶編輯地址,並需要直接將他們導向無效欄位,這項設定就很實用。
  • paymentMethodErrors:付款方式專屬的錯誤物件。您可以要求商家提供結構化錯誤訊息,但 Web Payments 規格作者建議您將錯誤訊息保持為簡單字串。

程式碼範例

您在本文件中看到的大部分程式碼範例,都是從下列可運作的範例應用程式中摘錄而來:

https://paymenthandler-demo.glitch.me

[payment handler] 服務工作者

[payment handler] 前端

如要試用這項功能,請按照下列步驟操作:

  1. 前往 https://paymentrequest-demo.glitch.me/
  2. 前往頁面底部。
  3. 按下「新增付款按鈕」
  4. 在「付款方式 ID」欄位中輸入 https://paymenthandler-demo.glitch.me
  5. 按下欄位旁的「付款」按鈕。