付款交易流程

瞭解商家如何整合付款應用程式,以及付款交易如何與 Payment Request API 搭配運作。

Web Payments API 是首次內建在瀏覽器中的專屬付款功能。有了 Web Payments,商家就能更輕鬆地整合付款應用程式,同時讓客戶體驗更流暢、更安全。

如要進一步瞭解使用 Web Payments 的優點,請參閱「透過 Web Payments 強化付款應用程式」。

本文將逐步說明商家網站上的付款交易,並協助您瞭解付款應用程式整合作業的運作方式。

這項程序包含 6 個步驟:

  1. 商家發起付款交易。
  2. 商家會顯示付款按鈕。
  3. 客戶按下付款按鈕。

    奶酪商店網站的圖表,其中顯示 BobPay (付款應用程式) 按鈕。

  4. 瀏覽器會啟動付款應用程式。

    圖表顯示起司商店網站,其中 BobPay 應用程式已在模式視窗中啟動。這個模式會顯示運送選項和總費用。

  5. 如果消費者變更任何詳細資料 (例如運送選項或地址),商家會更新交易詳細資料,反映變更內容。

    圖表:顯示消費者在 BobPay 應用程式互動視窗中選擇其他運送選項。第二張圖表:商家更新 BobPay 中顯示的總費用。

  6. 消費者確認購買後,商家會驗證付款並完成交易。

    圖表顯示客戶按下

步驟 1:商家啟動付款交易

當消費者決定購買商品時,商家會透過建構 PaymentRequest 物件來啟動付款交易。這個物件包含交易的重要資訊:

  • 可接受的付款方式,以及處理交易時所需的相關資料。
  • 詳細資料,例如總價 (必要) 和商品資訊。
  • 商家可要求運送資訊 (例如運送地址和運送選項) 的選項。
  • 商家也可以要求取得帳單地址、付款者姓名、電子郵件和電話號碼。
  • 商家也可以在 PaymentRequest 中加入選用的運送類型 (shippingdeliverypickup)。付款應用程式可使用這項資訊做為提示,在 UI 中顯示正確的標籤。
const request = new PaymentRequest([{
  supportedMethods: 'https://bobpay.xyz/pay',
  data: {
    transactionId: '****'
  }
}], {
  displayItems: [{
    label: 'Anvil L/S Crew Neck - Grey M x1',
    amount: { currency: 'USD', value: '22.15' }
  }],
  total: {
    label: 'Total due',
    amount: { currency: 'USD', value : '22.15' }
  }
}, {
  requestShipping: true,
  requestBillingAddress: true,
  requestPayerEmail: true,
  requestPayerPhone: true,
  requestPayerName: true,
  shippingType: 'delivery'
});

部分付款處理方可能會要求商家提供交易 ID,並將其列為交易資訊的一部分。一般來說,整合作業包括商家與付款處理程式伺服器之間的通訊,以預留總價。這樣一來,惡意消費者就無法操弄價格,並在交易結束時透過驗證欺騙商家。

商家可以將交易 ID 傳遞至 PaymentMethodData 物件的 data 屬性。

提供交易資訊後,瀏覽器會根據付款方式 ID,透過 PaymentRequest 中的指定付款應用程式進行探索程序。這樣一來,瀏覽器就能在商家準備繼續交易時,決定要啟動的付款應用程式。

如要進一步瞭解探索程序的運作方式,請參閱「設定付款方式」。

步驟 2:商家顯示付款按鈕

商家可以支援多種付款方式,但只應顯示客戶實際可用的付款方式按鈕。顯示無法使用的付款按鈕會導致使用者體驗不佳。如果商家可預測 PaymentRequest 物件中指定的付款方式對消費者無效,可以提供備用方案,或完全不顯示該按鈕。

商家可以使用 PaymentRequest 例項,查詢消費者是否有可用的付款應用程式。

客戶是否有可用的付款應用程式?

如果客戶的裝置上有可用的付款應用程式,PaymentRequestcanMakePayment() 方法會傳回 true。「可用」表示系統已找到支援該付款方式的付款應用程式,並安裝了特定平台的付款應用程式,或是網路付款應用程式已準備好註冊

const canMakePayment = await request.canMakePayment();
if (!canMakePayment) {
  // Fallback to other means of payment or hide the button.
}

步驟 3:客戶按下付款按鈕

當消費者按下付款按鈕時,商家會呼叫 PaymentRequest 例項的 show() 方法,立即觸發付款 UI 的啟動。

如果最終總價是動態設定 (例如從伺服器擷取),商家可以延後啟動付款 UI,直到總價確定為止。

延後啟動付款 UI

請查看延後付款 UI 的示範,直到確定最終總價為止。

為了延遲付款 UI,商家會將 promise 傳遞至 show() 方法。在承諾解析並交易準備就緒前,瀏覽器會顯示載入指標。

const getTotalAmount = async () => {
  // Fetch the total amount from the server, etc.
};

try {
  const result = await request.show(getTotalAmount());
  // Process the result…
} catch(e) {
  handleError(e);
}

如果沒有指定為 show() 的引數的承諾,瀏覽器會立即啟動付款 UI。

步驟 4:瀏覽器啟動付款應用程式

瀏覽器可以啟動特定平台或網路付款應用程式。如要進一步瞭解 Chrome 如何決定要啟動哪個付款應用程式,請參閱相關文章。

開發人員可以自行決定如何建構付款應用程式,但商家之間傳送的事件,以及與這些事件一併傳送的資料結構,都已標準化。

付款應用程式啟動時,會接收在步驟 1 中傳遞至 PaymentRequest 物件的交易資訊,包括:

  • 付款方式資料
  • 總價
  • 付款方式

付款應用程式會使用交易資訊為 UI 標示。

步驟 5:商家如何根據消費者的操作更新交易詳細資料

消費者可以在付款應用程式中變更交易詳細資料,例如付款方式和運送選項。在消費者變更資料時,商家會收到變更事件,並更新交易詳細資料。

商家可接收四種類型的事件:

  • 付款方式變更事件
  • 運送地址變更事件
  • 運送選項變更事件
  • 商家驗證事件

付款方式變更事件

付款應用程式可支援多種付款方式,商家可能會根據消費者的選擇提供特別折扣。為了涵蓋這類用途,付款方式變更事件可將新付款方式通知商家,讓他們更新含折扣的總價,並將其傳回至付款應用程式。

request.addEventListener('paymentmethodchange', e => {
  e.updateWith({
    // Add discount etc.
  });
});

運送地址變更事件

付款應用程式可選擇提供消費者的運送地址。這對消費者來說很方便,因為他們不必手動在表單中輸入任何詳細資料,而且可以將運送地址儲存在偏好的付款應用程式中,而非多個不同的商家網站。

如果消費者在交易開始後,在付款應用程式中更新運送地址,系統就會將 'shippingaddresschange' 事件傳送給商家。這項事件可協助商家根據新地址判斷運費,並更新總價,然後傳回至付款應用程式。

request.addEventListener('shippingaddresschange', e => {
  e.updateWith({
    // Update the details
  });
});

如果商家無法將商品運送至更新的地址,可以在傳回至付款應用程式的交易詳細資料中新增錯誤參數,以提供錯誤訊息。

運送選項變更事件

商家可以向消費者提供多種運送選項,並將選擇權交給付款應用程式。運送選項會以價格和服務名稱的清單形式顯示,供消費者選取。例如:

  • 標準配送服務 - 免運費
  • 快捷配送服務 - 5 美元

當消費者在付款應用程式中更新運送選項時,系統會將 'shippingoptionchange' 事件傳送給商家。商家接著可以決定運費、更新總價,然後傳回至付款應用程式。

request.addEventListener('shippingoptionchange', e => {
  e.updateWith({
    // Update the details
  });
});

商家也可以根據消費者的運送地址動態修改運送選項。當商家想為國內和國際客戶提供不同的運送選項時,這項功能就非常實用。

商家驗證事件

為提供額外安全性,付款應用程式可以在繼續付款流程之前,先執行商家驗證。驗證機制的設計取決於付款應用程式,但商家驗證事件可讓商家瞭解可用於驗證的網址。

request.addEventListener('merchantvalidation', e => {
  e.updateWith({
    // Use `e.validateURL` to validate
  });
});

步驟 6:商家驗證付款並完成交易

當客戶成功授權付款時,show() 方法會傳回解析為 PaymentResponse 的承諾。PaymentResponse 物件包含下列資訊:

  • 付款結果詳細資料
  • 運送地址
  • 運送選項
  • 聯絡資訊

此時,瀏覽器 UI 可能仍會顯示載入指標,表示交易尚未完成。

如果付款失敗或發生錯誤,付款應用程式就會終止,從 show() 傳回的承諾會遭到拒絕,瀏覽器也會終止付款交易。

處理及驗證付款

PaymentResponse 中的 details 是付款憑證物件,由付款應用程式傳回。商家可以使用憑證處理或驗證付款。這項重要程序的運作方式取決於付款處理程式。

完成或重試交易

商家判斷交易是否成功或失敗後,可以採取以下行動:

  • 呼叫 .complete() 方法即可完成交易,並關閉載入指標。
  • 呼叫 retry() 方法,讓客戶重試。
async function doPaymentRequest() {
  try {
    const request = new PaymentRequest(methodData, details, options);
    const response = await request.show();
    await validateResponse(response);
  } catch (err) {
    // AbortError, SecurityError
    console.error(err);
  }
}

async function validateResponse(response) {
  try {
    const errors = await checkAllValuesAreGood(response);
    if (errors.length) {
      await response.retry(errors);
      return validateResponse(response);
    }
    await response.complete("success");
  } catch (err) {
    // Something went wrong…
    await response.complete("fail");
  }
}
// Must be called as a result of a click
// or some explicit user action.
doPaymentRequest();

後續步驟