歐盟支付服務準則修正案 (PSD2)

歐洲經濟區支付卡法規對您業務上有何影響。

簡介

支付服務準則修正案 (Payment Services Directive 2,PSD2) 是歐洲經濟區 (EEA) 的法規,要求對於使用由 EEA 成員國核發的信用卡進行的各項交易,必須變更結帳與預訂流程以符合法規。

PSD2 提高安全且能防止詐騙,卻也完全改變了全歐洲的支付作業。根據法規,處理消費者電子支付時必須實行嚴格顧客驗證機制 (Strong Customer Authentication) 以符合規定。也就是全部發卡機構、收單機構和商店都必須支援嚴格顧客驗證機制。由於 EEA 銀行嚴格奉行此法,不符規定者將導致付款失敗。

本頁面為合作夥伴說明 Rapid API 支援的付款方式將受到哪些影響,以及您在服務旅客時可採行的做法。若想進一步了解 PSD2,請上歐洲執行委員會官方網站查詢法規細節。

合規要求

視正式商戶為何者、Rapid API 的支付方式為何,在 EEA 合法交易的做法有所不同。

當合作夥伴為正式商戶時

Expedia Affiliate Collect

使用 EAC 的預訂不受 PSD2 規定影響。付款流程和 Rapid API 整合都不需要變更,同樣能合法。然而,若您以商戶身分從旅客的信用卡、金融卡或其他符合歐盟法規的方式收費,就會受到一些影響。依法您可能必須支援符合 PSD2 的雙重身分驗證 (Two-Factor Authentication,2FA) 支付程序。請聯絡您的付款處理公司,看他們能如何幫助商戶符合 PSD2 規定、避免交易失敗。

合作夥伴支付卡

若貴公司是正式商戶,且使用 EEA 核發的公司信用卡或金融卡付款給 Rapid,則會受到 PSD2 的影響。符合 PSD2 規定的支付卡如下:

  • EEA 內核發的單次使用虛擬卡。
  • EEA 內核發的公司卡 (非個人卡)。
  • EEA 以外核發的任一支付卡。

若您從旅客的信用卡、金融卡或其他符合 EEA 法規的方式收費,也會受到影響。依法您可能必須支援符合 PSD2 的雙重身分驗證 (Two-Factor Authentication,2FA) 支付程序。請聯絡您的付款處理公司,看他們能如何幫助商戶符合 PSD2 規定、避免交易失敗。

若貴公司不願使用上列符合 PSD2 規定的支付卡,可逕向貴公司的發卡銀行申請豁免。一旦通過豁免,則使用該卡交易不需身分驗證,但可能需以 2FA 方式進行單次線上驗證。此單次線上驗證依各銀行而異。請注意,從申請到通過豁免可能需要很長時間;此外,若發生任何詐騙交易,銀行可能會要求貴公司負責。

當 Rapid 為正式商戶時

若貴公司以 Rapid 為商戶,並把旅客的支付卡傳送給 Rapid 的話,則會受到 PSD2 規定影響。當旅客自行 (不透過零售旅行業者) 線上預訂時,依規定 Rapid 會請旅客驗證付款是否來自本人。該付款驗證方式須為雙重身分驗證 (2FA),才符合 PSD2 規定。若合作夥伴想以 Rapid 為正式商戶,且使用 EEA 核發的信用卡或金融卡付款,則必須採用 Rapid 的 2FA 解決方案。

然而,透過零售旅行業者或客服中心專員預訂的交易,則不需進行 2FA。只要註明預訂是由專人協助辦理,交易就符合規定。如有需要,可在「供應情況 API」的 sales_channel 欄位加註。

當旅宿為正式商戶時

若貴公司使用入住時付款,則可能會受到 PSD2 規定影響。某些情況下,旅宿會在旅客不在場時從其信用卡收費,例如:「預訂後未入住」的費用或訂金。若收費前沒經過雙重身分驗證 (2FA),便不符合規定。若合作夥伴想讓持 EEA 核發信用卡或金融卡的旅客使用入住時付款付款,則必須採用 Rapid 的 2FA 解決方案。

Rapid API 解決方案簡介

運作方式

若合作夥伴以 Rapid 為正式商戶,或讓旅客以支付卡透過入住時付款付費,可使用 Rapid 的 API 來產生合規的預訂。API 在預訂流程中支援以 3DS 2.0 來進行雙重身分驗證,因此符合 PSD2 規定。我們採用 3DS 2.0 基於風險控管概念的驗證機制,讓銀行決定何時以 2FA 來驗證旅客身分,減少您與旅客之間的摩擦機會。

2FA 解決方案由三大不同部分組成:

  • 合作夥伴新增到付款頁面的 iframe,用來載入發卡銀行向旅客執行的 2FA,在整合相關文件中的名稱是 3DS iframe。
  • 裝載於付款頁面的新用戶端 JavaScript Library,用來收集瀏覽器資料、與 iframe 溝通,並於 iframe 中提供 2FA 使用者體驗。其在整合相關文件中的名稱是 3DS Connector Library。
  • Rapid 代替銀行接受付款人資料,並於通過 2FA 後完成預訂。

同時使用 JavaScript 和 Rapid 時,納入 2FA 後的預訂流程在呼叫「預訂 API」前後,即會多出一些步驟。下圖為更新後的預訂流程:

準備預訂的步驟為:先在 Rapid API 上登記付款,然後在 JavaScript API 收集資料。下一個步驟是在 Rapid API 進行預訂。最後的步驟為完成預訂:先在 JavaScript API 顯示 2FA,接著在 Rapid API 完成預訂。

更新後的預訂流程中,上一步驟的輸出資料用做下一步驟的輸入資料。也就是資料會在瀏覽器的 JavaScript 和 Rapid 之間傳輸。

請注意:上圖為實際 API 流程的簡化版,做為初步說明之用。完整 API 流程請參閱整合相關文件。

整合所需元件詳細說明

瀏覽器 iframe

iframe 用在付款頁面中,內有來自旅客發卡銀行的 URL。該 URL 會顯示頁面讓旅客進行 2FA,並把旅客輸入的資料直接傳給銀行。iframe 一開始應設為隱藏,當旅客預訂時被要求進行 2FA,再將驗證網頁覆蓋在原頁面上。

瀏覽器 JavaScript Library

新增於付款頁面,並於預訂時調用出來支援 2FA 程序。其 API 支援以下功能:

自動收集旅客裝置上的資料

預訂前須先收集旅客裝置資料,為預訂時所需的 2FA 做準備。資料收集好後會傳送給旅客發卡銀行審查,由銀行決定交易是否需經 2FA,並確認資料顯示無誤。根據 3DS 2.x 規範,API 會從旅客的瀏覽器收集以下資料:語言、色彩深度、螢幕長寬、時區、使用者代理,和是否啟用 Java。

在瀏覽器 iframe 中讓使用者進行 2FA

進行預訂後,JavaScript Library 會用來顯示 iframe 置入的網頁,並將銀行網頁內容載入 iframe。在 2FA 過程中,銀行的內容可能會再收集旅客裝置的其他資料,以支援其風險評估。此為完成預訂的必要過程。

Rapid

Rapid 加入了幾個新的 API,可和用戶端的 JavaScript Library 接合。這些 API 目前支援以下功能:

登記旅客及付款詳情

預訂前須先收集其他旅客資料,為預訂時所需的 2FA 做準備。這些資料包括銷售點和付款等旅客帳戶詳情。資料收集好後會傳送給旅客發卡銀行審查,由銀行決定交易是否需經 2FA。詳情請見 Rapid 的「註冊付款 API」。

完成付款並確認預訂

使用 Rapid 進行預訂並於瀏覽器完成 2FA 程序後,必須再調用出 Rapid。我們會在後台確認成功通過 2FA,並確認預訂。詳情請見 Rapid 的完成付款工作階段 (Complete Payments Session)

預訂流程

簡介

若 Partner Profile Rapid Support 中啟動了 2FA,則「價格檢查 API」會回傳連結到「註冊付款 API」,而不是到「建立預訂 API」。下圖所示為旅客下訂後的 API 所需呼叫順序,包括對 JavaScript Library 和對 Rapid 的呼叫。

先初始化 JavaScript Library,然後用 Rapid API「建立付款工作階段 (Create Payment Session)」。流程返回 JavaScript 來初始化「付款工作階段 (Payment Session)」,接著用 Rapid API 進行「預訂 (Book)」。如果不需要 2FA,則預訂完成。如果需要 2FA,則用 JavaScript 在 iframe 顯示 2FA 程序,最後再用 Rapid API「完成付工作階段 (Complete Payment Session)」。

雖會事先做好準備,但不是每筆預訂都需要進行 2FA。是否需要 2FA,是由旅客用來付費的信用卡發卡銀行決定。銀行會在交易過程中做出決定,結果則顯示在「建立預訂 API」的回應。

下圖所示為使用「暫停與繼續處理 API」所需的呼叫順序:

先初始化 JavaScript Library,然後用 Rapid API 建立付款工作階段 (Create Payment Session)。接下來用 JavaScript API 初始化付款工作階段 (Payment Session),再用 Rapid API 進行預訂 (Book)。如果不需要 2FA,請繼續使用 Rapid API 預訂。如果需要 2FA,則用 JavaScript API 在 iframe 顯示 2FA 程序,接著用 Rapid API 完成付款工作階段,最後再用 Rapid API 繼續預訂。

請注意:以上圖示皆為實際 API 流程的簡化版,做為初步說明之用。完整 API 流程請參閱整合相關文件。

更多資訊

若想進一步了解提供 2FA 程序所需技術,請參閱 EMVCo 的 3D 安全協定與主要功能說明

Rapid 與雙重身分驗證整合指南

簡介

若要支援雙重身分驗證 (簡稱 2FA),需整合新的 JavaScript Library (稱為 3DS Connector) 和 Rapid。二者合併使用於付款頁面供旅客進行 2FA,並確認預訂。此解決方案支援 Expedia Collect 和入住時付款兩種商業模式。

下列為支援預訂時進行 2FA 所需的 API 呼叫順序,並於下個段落詳細說明:

  1. JavaScript 設定方法
  2. Rapid 註冊付款 API
  3. JavaScript 初始化工作階段方法
  4. Rapid 預訂 API
  5. JavaScript Challenge 方法
  6. Rapid 完成付款 API

若想允許上述呼叫順序,需由 Rapid 合作夥伴服務 (Rapid Partner Support) 幫您啟動設定檔 (Partner Profile) 裡的 2FA。

Rapid

若合作夥伴的設定啟動了 2FA,則 API 回應會變更,預訂流程也修改成包含 2FA。

供應情況 API

API 要求中 sales_channel 欄位裡的值必須正確無誤,才能在規定允許時取得 2FA 豁免。預訂過程中,支付卡發卡銀行會需要查看此 (以及其他) 欄位裡的值,以決定是否進行 2FA。唯有在使用旅行業者工具時才能免進行 2FA。若需註明此項目,請把 sales_channel 的值設為 agent_tool

價格檢查 API

API 會回傳連結到「註冊付款 API」,而不是到「建立預訂 API」。

啟用 2FA 時的回應範例:

{
    "status": "matched",
    "occupancies": {
        //...(example omitted for length)
    },
    "links": {
        "payment_session": {
            "method": "POST",
            "href": "/v3/payment-sessions?token=QldfCGlcUAVgBDRwdWXBBL"
        }
    }
}

註冊付款 API

這是為符合 PSD2 而併用 JavaScript-Rapid 修改後,預訂流程中的第二個步驟,出現在 JavaScriptsetup 方法之後。

要求中包含 PSD2 合規前預訂流程裡的付款詳情,再加上一些成功支援 2FA 的新欄位。其中兩個欄位:encoded_browser_metadataversion 是從 JavaScript API 的 setup method 回傳。

回應中會包括 payment_session_idencoded_init_config,並成為 JavaScript Library initSession 方法的輸入資料。回應中的預訂連結應於 initSession 方法後使用。

請求範例:

{
    "version": "1",
    "browser_accept_header": "*/*",
    "encoded_browser_metadata": "ZW5jb2RlZF9icm93c2VyX21ldGFkYXRh",
    "preferred_challenge_window_size": "medium",
    "merchant_url": "https://server.adomainname.net",
    "customer_account_details": {
        "authentication_method": "guest",
        "authentication_timestamp": "2018-02-12T11:59:00.000Z",
        "create_date": "2018-09-15",
        "change_date": "2018-09-17",
        "password_change_date": "2018-09-17",
        "add_card_attempts": 1,
        "account_purchases": 1
    },
    "payments": [
        {
            "type": "customer_card",
            "card_type": "VI",
            "number": "4111111111111111",
            "security_code": "123",
            "expiration_month": "08",
            "expiration_year": "2025",
            "billing_contact": {
                "given_name": "John",
                "family_name": "Smith",
                "email": "smith@example.com",
                "phone": "4875550077",
                "address": {
                    "line_1": "555 1st St",
                    "line_2": "10th Floor",
                    "line_3": "Unit 12",
                    "city": "Seattle",
                    "state_province_code": "WA",
                    "postal_code": "98121",
                    "country_code": "US"
                }
            },
            "enrollment_date": "2018-09-15"
        }
    ]
}

回應範例:

{
    "payment_session_id": "76d6aaea-c1d5-11e8-a355-529269fb1459",
    "encoded_init_config": "QSBiYXNlNjQgZW5jb2RlZCBvYmplY3Qgd2hpY2ggY29udGFpbnMgY29uZmlndXJhdGlvbiBuZWVkZWQgdG8gcGVyZm9ybSBkZXZpY2UgZmluZ2VycHJpbnRpbmcgYW5kL29yIDNEUyBNZXRob2Qu",
    "links": {
        "book": {
            "method": "POST",
            "href": "/v3/itineraries?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
        }
    }
}

建立預訂 API

這是為符合 PSD2 而併用 JavaScript-Rapid 修改後,預訂流程中的第四個步驟,出現在 JavaScriptinitSession 方法之後。要求中沒有因 PSD2 而新增的欄位,所需資訊都已包含在「註冊付款 API」回傳預訂連結的記號裡。若回應成功,一定會包含 itinerary_id。單有此 ID 不表示預訂已確認,因為可能會需要經過 2FA。

如果需要 2FA,則回應還會包含 encoded_challenge_config。從「註冊付款」回傳的 encoded_challenge_configpayment_session_id 必須用為參數傳入 JavaScript challenge 方法。

回應還會包括用來 complete_payment_session 的新連結。此連結應於 JavaScript Library 的 challenge 方法之後使用。

如果不需要 2FA,則預訂確認,回應中會包含用來 retrievecancelresume (非必要) 的連結。

需要 2FA 的建立預訂回應範例:

{
    "itinerary_id": "8999989898988",
    "links": {
        "complete_payment_session": {
            "method": "PUT",
            "href": "/v3/itineraries/8999989898988/payment-sessions?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
        }
    },
    "encoded_challenge_config": "ABElifsiejfacies2@033asfe="
}

完成付款工作階段 API

這是為符合 PSD2 而併用 JavaScript-Rapid 修改後,預訂流程中的第六個步驟,出現在 JavaScriptchallenge 方法之後。需要此 API 來完成付款並通知 Rapid 已完成 2FA (無論是否通過)。

要求中沒有因 PSD2 而新增的欄位。

回應若成功,會包含 itinerary_id 和用來 retrievecancelresume (非必要) 的連結。成功回應即確認預訂。

回應範例:

{
    "itinerary_id": "8999989898988",
    "links": {
        "retrieve": {
            "method": "GET",
            "href": "/v3/itineraries/8999989898988?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
        }
    }
}

3DS Connector JavaScript Library 和 3DS iframe

使用 PSD2 預訂流程時,付款頁面必須包含新的 iframe 和 JavaScript Library。其中 iframe (稱為 3DS iframe) 會用 3D-Secure 2.x 驗證程序顯示出,供旅客進行驗證。而 JavaScript Library (稱為 3DS Connector Library) 則負責傳送資料給發卡銀行,並把銀行的內容載入 iframe。

新增 3DS iframe 和 JavaScript Library

新增 3DS iframe

3DS iframe 應包在開始時為隱藏的容器中,當付款程序判定為必須進行驗證時,則會再顯示。

容器設計可配合裝載頁面來自訂。以下為使用 Bootstrap 模態框顯示的執行範例,僅供參考。

<div id="threeDsIframeModal" class="modal" role="dialog">
    <div class="modal-dialog" role="document">
        <div class="modal-content">
            <div class="modal-body iframe-container">
                <div class="embed-responsive embed-responsive-16by9">
                    <iframe id="threeDsIframe" src="<<3DS iframe URL>>"> </iframe>
                </div>
            </div>
        </div>
    </div>
</div>

iframe 的源 (source) 必須設為以下兩個值之一:

URL 類型URL備註
正式環境https://static.pay.expedia.com/3ds/threeDsIframe.html支援 2FA 正式環境
測試沙箱https://static.pay.expedia.com/3ds/sandboxThreeDsIframe.html支援 2FA 測試

上列測試 URL 可支援測試,下文會再回到這個主題。為了在測試時限制 iframe 的內容,可在沙箱擬真環境裡測試,但必須容許以下:

sandbox = 'allow-scripts allow-forms allow-same-origin';

新增 3DS Connector JavaScript Library

3DS Connector Library 負責和 3DS iframe 溝通,並傳送資料給發卡銀行;銀行為 iframe 內容提供者。以下範例顯示如何將 3DS Connector Library 新增到付款頁面。

<head>
    <script src="<<3DS connector script URL>>" integrity="<<actual integrity value>>"></script>
</head>

script 元素的 source 和 integrity 值應設為如下所示:

Library 版本屬性
1.3.39srchttps://static.pay.expedia.com/3ds/1.3.39/pay-3ds-js-libs-connector.min.js
integritysha384-par0I4Q5cfljwzqw2mAggM4dKdYzGyj4uZiL4cMviGjI3qVzEgWGuZ2075mYutbT
1.3.65srchttps://static.pay.expedia.com/3ds/1.3.65/pay-3ds-js-libs-connector.min.js
integritysha384-gYopPw6xE5DZwnZXGavkwnvs3NkDOobnHqjroUnSHpGXvs/J9xjHX/8aGzKtSgWI

請注意:日後有更新版本可用時,這裡的 source URL 和 integrity 也會變更。新版不會破壞現有的整合。舊版的 script 元素仍可存取。

使用 3DS iframe 和 JavaScript Library

JavaScript Library 需使用 JavaScript Promise 物件。下圖為執行範例,顯示 JavaScript 方法和 Rapid 之間如何交換數據,僅供參考。

// Initialize the library
let connector = new PayThreeDSConnector.ThreeDSConnector("threedsiframe", "https://static.pay.expedia.com");
RapidIntegration.priceCheck(priceCheckLink)
  .then(priceCheckResponse => {
    paymentSessionLink = priceCheckResponse.links.payment_session.href;
    // Setup an authentication session with the library
    return connector.setup({ referenceId: '1000' })
  }).then(setupResponse => {
    console.log("Setup Response: ", setupResponse);

    // Send information from setup to Rapid's Register Payments API
    return RapidIntegration.registerPayment(paymentSessionLink,
           setupResponse);
  }).then(paymentSessionResponse => {
    console.log("Register Payments Response: ", paymentSessionResponse);
    paymentSessionId = paymentSessionResponse.paymentSessionId;
    bookLink = paymentSessionResponse.links.book.href;
    if (paymentSessionResponse.encoded_init_config) {
      // If the payment session response contains an encoded_init_config
      // field, initialize an authentication session with the library
      // using information returned from Rapid's Register Payments API
      connector.initSession({
        paymentSessionId: paymentSessionId,
        encodedInitConfig: paymentSessionResponse.encodedInitConfig
      }).then(initSessionResponse => {
        console.log("Init Session Response: ", initSessionResponse);
        // Then create a booking with Rapid's Book API
        return RapidIntegration.createBooking(bookLink,
               paymentSessionId);
      })
    } else {
      // Otherwise, create a booking with Rapid's Book API directly
      return RapidIntegration.createBooking(bookLink, paymentSessionId);
    }
  }).then(createBookingResponse => {
    console.log("Create Booking Response: ", createBookingResponse);
    itineraryId = createBookingResponse.itinerary_id;
    if (createBookingResponse.encoded_challenge_config) {
      // If the Create Booking API contains an encoded_challenge_config field,
      // display the authentication challenge window
      $('#threeDsIframeModal).modal('show');
      completePaymentSessionLink = createBookingResponse.links.complete_payment_session.href;
      // Perform the challenge using the information returned from Rapid's Register Payments API
      // and Create Booking API
      connector.challenge({
        paymentSessionId: paymentSessionId,
        encodedChallengeConfig: createBookingResponse.encodedChallengeConfig
      }).then(challengeResponse => {
        console.log("Challenge Response: ", challengeResponse);
        // Complete a booking with Rapid's Complete Payment Session API
        return RapidIntegration.completePaymentSession(completePaymentSessionLink, itineraryId);
      }).then(completePaymentSessionResponse => {
        console.log("Complete Payment Session Response: ", completePaymentSessionResponse);
        return completePaymentSessionResponse;
      }).finally(() => {
        // Close the authentication challenge window
        $('#threeDsIframeModal').modal('hide');
      });
    } else {
      return createBookingResponse;
    }
  }).then(bookingResponse => {
    ...
  });

備註:RapidIntegration 類別的參考也是範例內容,而非 3DS Connector Library 內容,旨在示範可支援資料傳輸到 API 的封套資料。

範例中使用靜態變數為參數,執行時應另行決定,如 referenceId

付款頁面指南

支援 2FA 的支付卡公司可能會要求把品牌名稱和商標顯示出來,以符合其公司規定。

支付卡類別2FA 品牌名稱商標和使用方法
MasterCard (萬事達卡)萬事達卡 ID Check(https://brand.mastercard.com/debit/mastercard-brand-mark/downloads.html))]
VisaVisa 驗證[https://www.merchantsignage.visa.com/brand_guidelines

備註:待其他卡別的商標和使用辦法公布時會再納入此表。

3DS Connector JavaScript Library 相關文件

類別:ThreeDSConnector

建構函式 (Constructor)

new ThreeDSConnector(threeDsIFrameId, threeDsIFrameOrigin)

參數:

名稱類型說明
threeDsIFrameOrigin字串3DS iframe 的 ID。
threeDsIFrameOrigin字串3DS iframe 的原點 (Origin)。在與 3DS iframe 溝通使用以傳出視窗訊息並過濾接受訊息。

方法

設定

透過收集後端 3DS 服務所需的瀏覽器基本資料 (如螢幕尺寸、色彩深度等) 來設定付款工作階段。

方法簽章 (Method signature):

setup(setupRequest)

參數:

名稱類型
setupRequestSetupRequest

回傳:

SetupResponse 的 Promise 物件

初始化工作階段

初始化與 3DS 間的工作階段,以進行驗證。進行初始化可能需要從瀏覽器收集其他資料。若發卡機構提出要求,iframe 可載入 3DS URL 來啟動發卡機構的存取控制伺服器 (Access Control Server),直接從瀏覽器收集資料。用戶端不必等待回呼完成,於建立命令前即可調用。

方法簽章 (Method signature):

initSession(initSessionRequest)

參數:

名稱類型
initSessionRequestInitSessionRequest

回傳:InitSessionResponse 的 Promise 物件

挑戰 (Challenge)

若發卡機構要求進行驗證,則載入 3DS 安全認證機制。

方法簽章 (Method signature):

challenge(challengeRequest)

參數:

名稱類型
challengeRequestChallengeRequest

回傳:ChallengeResponse 的 Promise 物件

類別 (Class):SetupRequest

設定呼叫的需求架構。

性質:

名稱類型說明
referenceIdstring辨識旅客付款頁面工作階段的參考 ID,用於記錄和追蹤。請使用 APIKey 和 Customer-Session-ID 的序連字元,中間以下劃線連接,例如:[APIKey]_[SessionID]

類別 (Class):SetupResponse

來自設定呼叫的回應。

性質:

名稱類型說明
version字串函式庫版本,和連往函式庫的 URL 所示版本相同。
encodedBrowserMetadata字串編碼物件,內含從瀏覽器收集的資料。用戶端應將此視為不透明數據,無需解析即可傳給後端支付服務。

類別 (Class):InitSessionRequest

initSession 方法的需求架構。

性質:

名稱類型說明
paymentSessionId字串「Rapid 註冊付款 API」傳回的唯一識別碼。
encodedInitConfig字串編碼物件組態清單,內含初始化所需資料,由「Rapid 註冊付款 API」傳回。

類別 (Class):InitSessionResponse

initSession 方法的回應結構。

性質:

名稱類型說明
statusCode字串initSession 呼叫的狀態。
message字串可選用。標示失敗原因。

statusCode 可能會有以下的值:

說明
SUCCESS初始化成功完成。
SKIPPED沒有進行初始化。
FAILED初始化失敗。訊息欄位包含更多失敗相關的訊息。
TIMEOUT初始化未在時間內完成。時限為 10 秒。

備註:若需完整 initSessionresponse statusCode,請查看「Rapid 預訂 API」。

類別 (Class):ChallengeRequest

挑戰 (Challenge) 方法的需求架構。

性質:

statusCode 值測試 encoded_Challenge_config 值說明
SUCCESSW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0無使用者 iframe 互動
SUCCESS / FAILEDW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0無使用者 iframe 互動
FAILEDW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ無使用者 iframe 互動
TIMEOUTW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0
ERRORW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d

statusCode 可能會有以下的值:

說明
SUCCESS3DS 挑戰 (Challenge) 成功完成。
SKIPPED外部應用程式錯誤。
FAILED由於持卡人無法正確回應身分驗證挑戰,故 3DS 挑戰未成功完成。
TIMEOUT挑戰未在時間內完成。時限為 1200 秒。

備註:若需完整 challengeResponse statusCode,請查看 Rapid 完成付款對話 (Complete Payment Session)。

Rapid 與雙重身分驗證測試

若想測試與 Rapid 和 3DS Connector 方法的整合,可輸入符合 API 支援特定環境的參數值進行測試。

Rapid

若要測試 Rapid,請在 HTTP 要求中加上名為 Test 的 HTTP 標頭,再使用 API 支援的其中一個值來測試所支援的環境。

在 PSD2 預訂流程中,Rapid 的測試回應也可用來測試 3DS Connector Library 方法。

註冊付款 (Register Payments)

以下測試標頭值在 API 回應中會產生不同 encoded_init_config,以及不同 HTTP 回應碼。encoded_init_config 可傳入 JavaScript Library 的 initSession 呼叫,以啟動 3DS Connector Library 中的不同測試用例。

測試標題值HTTP 代碼與回應initSession 測試用例
standard201 – 標準回應SUCCESS
init_skip201 - 不含 encodedInitConfig 的回應Not supported
init_fail201 – 標準回應FAILED
init_timeout201 – 標準回應TIMEOUT
internal_server_error500 – 內部伺服器錯誤
internal_server_error503 - 伺服器無法使用

備註:init_skip 3DS Connector Library.t_config 裡的不同測試案例可傳到 initSession,便會強行產生名為 SKIPPED 的 statusCode

建立預訂

除了在 Rapid 預訂測試要求為非 PSD2 預訂流程定義的不同測試標頭外,還有其他支援 PSD2 流程的測試標頭值。

測試標頭值會產生不同的 encodedChallengeConfig 值,這些值可傳入 JavaScript Library 的 challenge 呼叫,以觸發不同的測試案例。

測試標題值HTTP 代碼與回應initSession 測試用例
complete_payment_session201 – 含完成付款工作階段連結的回應SUCCESS 無使用者 iframe 互動
complete_payment_session_show201 – 含完成付款工作階段連結的回應SUCCESS/FAILED 有使用者 iframe 互動
complete_payment_session_fail201 – 含完成付款工作階段連結的回應FAILED 無使用者 iframe 互動
complete_payment_session_timeout201 – 含完成付款工作階段連結的回應TIMEOUT
complete_payment_session_error201 – 含完成付款工作階段連結的回應ERROR

完成付款工作階段

在試著完成付款並確認預訂時,測試標頭值會產生不同錯誤情況。

測試標題值HTTP 代碼與回應
payment_declined400 - 付款遭拒回應
price_mismatch409 - 房價不符回應
rooms_unavailable410 - 無空房回應

3DS Connector Library 和 iframe

在無外部相依關係下測試 3DS Connector 時,需使用符合支援方法回應的特定參數值。僅限 iframe 用測試沙箱 URL 載入時才支援這種做法。

初始化工作階段

InitSessionResponse statusCode 所支援的值可用變更 initSessionRequest encodedInitConfig 的方法來測試。

statusCode 值測試 encodedInitConfig 值
SUCCESSW3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJTVUNDRVNTIn1d
FAILEDW3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJGQUlMRUQifV0=
TIMEOUTW3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJUSU1FT1VUIn1d
SKIPPEDNot supported at this time.

注意:encoded_init_config 值也可以使用「註冊付款 API」支援的測試標頭產生。

挑戰 (Challenge)

challengeResponse statusCode 所支援的值可用變更 challengeRequest encondedChallengeConfig 的方法來測試。

statusCode 值測試 encoded_Challenge_config 值說明
SUCCESSW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0無使用者 iframe 互動
SUCCESS / FAILEDW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0無使用者 iframe 互動
FAILEDW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ無使用者 iframe 互動
TIMEOUTW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0
ERRORW3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d

備註:encodedInitConfig 值也可用「預訂 API」的 PSD2 付款流程支援的測試標頭來產生。

備註:當以使用者在 iframe 中輸入的資料來測試挑戰狀態碼值 SUCCESS 或 FAILED 時,挑戰方法回應會在 iframe 中等待擬真驗證 UI 完成。

3DS iframe 中的 UI 範例:

3DS iframe 範例

用法範例

以下為執行範例,僅供參考。範例中可看到如何使用預先定義的值來測試 Library 進行 3DS 挑戰,而不需要使用者與 iframe 互動。

var c = new PayThreeDSConnector.ThreeDSConnector('threedsiframe', 'https://static.pay.expedia.com'); // change to match the 3DS iframe ID
c.setup({ referenceId: '1000' })
    .then((setupResponse) => {
        console.log('Setup Output: ', setupResponse);
        return c.initSession({
            paymentSessionId: 1,
            encodedInitConfig: ' W3sicHJvdmlkZXJJZCI6IDAsICJzYW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJTVUNDRVNTIn1d',
        }); // SUCCESS
    })
    .then((initResponse) => {
        console.log('InitSession Output: ', initResponse);
        $('#threedsIframeModal').modal(); // replace with code to show the modal containing the 3DS iframe
        return c.challenge({
            paymentSessionId: 1,
            encodedChallengeConfig:
                ' W3sicHJvdmlkZXJJZCI6IDAsICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0=',
        }); // SUCCESS
    })
    .then((challengeResponse) => {
        console.log('Challenge Output: ', challengeResponse);
    })
    .finally(() => {
        $('#threedsIframeModal').modal('hide'); // replace with code to hide the modal containing the 3DS iframe
    });

雙重身分驗證與入住時付款

入住時付款的雙重身分驗證簡介

使用入住時付款預訂時,Expedia 不會從支付卡扣款,而是傳給旅宿處理付款。旅宿可能會用收到的資訊在入住前先進行信用卡驗證。旅客則在辦理入住時親自付款。

然而,有些旅客在預訂後卻沒有入住,此時旅宿就會收取未入住罰款。像這樣的費用也可能受 PSD2 規定影響,因為是在旅客不在場時從支付卡收費。

當交易受 PSD2 影響而收款手續卻不符規定,則可能會導致交易失敗,旅宿也可能會面臨信用卡公司的罰款。

Expedia Group 為了維持與旅宿的良好關係,並繼續服務我們的合作夥伴,因此提供給旅宿另一項合規辦法:現在開始,受 PSD2 規定影響的旅宿可用 Expedia Group 的名義提供 2FA。如此一來,旅宿的業務不受影響,而 Rapid 也可繼續提供各式各樣的住宿選擇。

Rapid 在 Property Content File 和 Property Content 中提供了 <payment_registration_recommended=true> 旗標,方便您辨識出可能涉及上述情形的旅宿。

請注意:僅有位於歐洲經濟區 (簡稱 EEA) 內的旅宿才需進行 2FA,而設成需要 2FA 的旅宿並非固定不變,當有更多旅宿選擇啟用此功能時,數量就會增加。

入住時付款的 2FA 對系統整合有何影響?

合作夥伴若想提供需 2FA 的旅宿,則您的預訂路徑必須支援 2FA。若預訂路徑不支援 2FA,一旦發卡銀行決定交易需要 2FA 時 (例如 EEA 內核發的卡),則可能導致預訂失敗。

當旅宿收取未入住罰款時,是以 Rapid 為正式商戶。該筆交易列在信用卡明細上的請款商戶名稱非旅宿所能決定。請款商戶名稱係由合作夥伴來決定。若想自訂此名稱,請聯絡 Rapid 合作夥伴服務。
為符合信用卡公司及 Rapid 的啟用規定,收取未入住罰款時,請使用 Accepted Payments API 在付款頁面顯示 processing_country。所有以 Rapid 為正式商戶時的交易都需要這項顯示;在使用 2FA 收取未入住罰款的情況下,Rapid 是交易的正式商戶。

如何減輕對系統整合的影響

若整合後的 Rapid 不支援預訂流程的 2FA,為降低失敗風險,可考慮不開放這些旅宿給旅客預訂。

請聯絡 Rapid 合作夥伴支援,將這些受影響的入住時付款旅宿從「供應情況 API」回應中移除。

根據規定,使用旅行業者工具交易時不需進行 2FA。如有需要,可在「供應情況 API」的 sales_channel 欄位加註。

錯誤處理

「建立預訂 API」和「完成付款工作階段 API」可能會產生預訂確認和付款交易。

系統整合時請考慮以下說明,以避免財物損失和客戶操作的情形。

來源功能建議時限錯誤復原做法需採取的行動
Rapid API註冊付款的預訂前價格檢查記號10 秒重試或選擇其他住宿、客房或房價-
JavaScript3DS Connector 設定10 秒重試相同的要求-
Rapid API註冊付款工作階段10 秒重試相同要求,拿掉 "Expect: 100-Continue" process-
JavaScript初始化付款工作階段10 秒重試相同的要求-
Rapid API建立預訂90 秒重試相同的要求所有錯誤:用 affiliate_reference_id 取回預訂
JavaScript顯示 2FA 挑戰10 秒重試相同的要求-
JavaScript等待 challenge.statusCode180 ~ 1200 秒要求完成付款工作階段-
Rapid API完成付款工作階段 (Complete Payment Session)90 秒重試相同的要求所有錯誤:用 affiliate_reference_id 取回預訂
Rapid API所有錯誤:用 affiliate_reference_id 取回預訂30 秒重試相同的要求所有錯誤:等待 90 秒後再重試,用 API 回應碼 404 或 200 確認預訂最後狀態
這個頁面有幫助嗎?
我們能如何改善內容?
感謝您協助我們進行改善!