遵守嚴格的客戶身份驗證規定
了解網路信用卡支付的身份驗證規定。
簡介
監管機構和卡片網路正在引入新的要求,以加強線上支付的安全性並保護消費者免受詐騙。許多法規都要求在線上支付時使用強客戶身份驗證 (SCA)。
- 歐洲:《修訂後的支付服務指示》(PSD2)要求線上支付交易必須使用 SCA,除非有特定豁免或 out-of-scope 情況。
- **日本:**日本的 SCA 法規要求線上信用卡交易必須使用 3D 安全性 (3DS) 驗證,但某些交易類型除外。
3D Secure 2 (3DS 2.0) 是由 EMVCo 和卡支付處理行業共同開發的技術,旨在確保合規性,同時兼顧安全性和流暢的結帳體驗。3DS 2.0 是 Rapid API 中使用的解決方案,旨在確保符合 SCA 法規。
本頁解釋了受支援的 Rapid API 付款類型會受到怎樣的影響,以及您在為旅客提供服務時可以採取哪些措施來確保合規。
合規要求
在需要 SCA 的國家/地區啟用合規交易的步驟將根據記錄的商家是誰以及向 Rapid API 付款的方式而有所不同。
當您的組織是記錄商家時
Expedia Affiliate Collect
使用 Expedia Affiliate Collect 進行的預訂不受 SCA 法規的影響。無需使用 Rapid API 進行任何付款流程或 API 整合變更即可達到合規性。
但是,如果您是記錄商家,並且向旅客的信用卡、金融卡或其他屬於 SCA 法規範圍內的付款方式收費,則您可能會受到法規的影響。法規可能要求在支付過程中使用 3DS 2.0 作為 SCA-compliant 解決方案。請聯絡您的支付處理商,以了解更多有關其幫助商家達到 SCA 合規性並避免交易失敗的能力的資訊。
公司卡
如果您的公司是記錄商家,並使用在強制實施 SCA 的國家/地區發行的信用卡或金融卡支付 Rapid API,則以下卡類型可免於 SCA 要求:
- 一次性虛擬卡
- 向您的公司發行公司卡,而不是向個人發行
如果列出的 SCA-exempt 卡不是首選,您的組織可以直接向發卡銀行申請豁免。如果獲得豁免,該卡上的交易將無需身份驗證,但可能需要使用 3DS 2.0 進行 one-time 線上驗證。此 one-time 要求可能因銀行而異。請注意,從申請到通過豁免可能需要很長時間;此外,若發生任何詐騙交易,銀行可能會要求貴公司負責。
當 Rapid API 是記錄商家時
如果您的公司使用 Rapid API 作為記錄商家,向 Rapid 發送旅行者卡,您可能會受到法規的影響。當旅行者在沒有零售代理的情況下在線預訂時,法規要求旅行者透過 SCA 對支付交易進行身份驗證。此要求的 SCA-compliant 流程是在付款過程中使用 3DS 2.0。如果您的組織希望將 Rapid API 用作在強制實施 SCA 的國家/地區發行的任何信用卡或金融卡的記錄商家,則需要採用我們的 SCA 解決方案。
透過零售代理或呼叫中心代理預訂的交易不受 SCA 要求的約束。只要註明預訂是由專人協助辦理,交易就符合規定。如有需要,可在「供應情況 API」的 sales_channel
欄位加註。
當財產是記錄商家時
如果您的公司使用財產收集,您可能會受到法規的影響。在某些情況下,飯店可能會在旅客不在場的情況下嘗試從旅客卡中扣款,例如收取「未入住」費用或押金。如果在收費前未進行 3DS 2.0 驗證,這些收費將不屬於 SCA-compliant。如果您的組織希望使用在強制實施 SCA 的國家/地區發行的任何信用卡或金融卡為旅客提供財產收集服務,則需要採用我們的 SCA 解決方案。
Rapid API 解決方案
運作方式
如果您使用 Rapid API 作為記錄商家或使用旅行者卡進行財產收集,您可以採用 Rapid 的 API 解決方案來產生符合 SCA 規定的預訂。我們的 API 透過在預訂流程中使用 3DS 2.0 來支援 SCA 合規性。透過 3DS 2.0,我們支援 risk-based 身份驗證,透過授予銀行自行決定何時要求旅行者進行安全身份驗證的權力,可以減少與旅行者之間的摩擦。
3DS 2.0 的解決方案由三個不同的步驟組成:
- 您將向 check-out 頁面添加一個 iframe,該頁面用於為旅行者提供發卡銀行的身份驗證體驗。在整合文件中,這被稱為 3DS iframe。
- 您還將在 client-side JavaScript 頁面上包含一個新的 check-out 庫,用於收集瀏覽器資料、與 iframe 通訊以及在 iframe 中顯示 SCA 體驗。在整合文件中,這被稱為 3DS 連接器庫。
- Rapid API 將接受銀行的付款人信息,並在安全認證完成後完成預訂。
當一起使用 JavaScript 和 Rapid API 時,SCA 的預訂流程現在將在呼叫預訂 API 之前和之後包含一些額外的步驟。下圖為更新後的預訂流程:

更新後的預訂流程中,上一步驟的輸出資料用做下一步驟的輸入資料。也就是資料會在瀏覽器的 JavaScript 和 Rapid 之間傳輸。
請注意:上圖為實際 API 流程的簡化版,做為初步說明之用。完整 API 流程請參閱整合相關文件。
整合所需元件詳細說明
瀏覽器 iframe
放置在 check-out 體驗中的 iframe 託管著旅行者 card-issuing 銀行擁有的 URL。此 URL 將向使用者顯示身份驗證體驗,並將任何 traveler-supplied 資訊直接傳輸到他們的銀行。Iframe 最初應該是隱藏的,當預訂嘗試後需要進行身份驗證質詢時,可以將其覆蓋在頁面頂部。
瀏覽器 JavaScript Library
該庫被添加到 check-out 頁面,並在預訂時調用以支援身份驗證過程。其 API 支援以下功能:
自動收集旅客裝置上的資料
在嘗試預訂之前,必須收集有關旅行者設備的信息,以準備進行身份驗證的預訂。這些資訊被發送到旅行者的 issuing-bank 進行審查,以便銀行可以評估風險,決定交易是否需要 3DS 2.0 身份驗證,並確保其正確顯示。根據 3DS 2.0 規範,將從旅客的瀏覽器收集以下資料:語言、色彩深度、螢幕高度、螢幕寬度、時區、使用者代理程式以及是否啟用 Java。
在瀏覽器 iframe 中顯示身份驗證體驗
進行預訂後,JavaScript Library 會用來顯示 iframe 置入的網頁,並將銀行網頁內容載入 iframe。在身份驗證過程中,銀行的內容可能會收集有關旅行者設備的其他信息,以支援他們的風險評估。此為完成預訂的必要過程。
Rapid API
Rapid API 包含與 client-side JavaScript 函式庫協同工作的 API。這些 API 目前支援以下功能:
登記旅客及付款詳情
在嘗試預訂之前,必須收集有關旅行者的其他信息,以準備進行預訂驗證。這些資料包括銷售點和付款等旅客帳戶詳情。這些數據隨後被發送到旅行者的 issuing-bank 進行審查,以便銀行可以評估風險並決定交易是否需要安全認證。詳情請見 Rapid 的「註冊付款 API」。
完成付款並確認預訂
使用 Rapid API 嘗試預訂並在瀏覽器上完成 SCA 流程後,必須再次呼叫 Rapid。我們將在後台確認身份驗證是否確實成功,以便確認預訂。詳情請見 Rapid 的完成付款工作階段 (Complete Payments Session)。
預訂流程
如果在合作夥伴資料快速支援中啟用了 3DS 2.0,則價格查詢API 將傳回一個連結註冊付款API 而不是建立預訂API。下圖所示為旅客下訂後的 API 所需呼叫順序,包括對 JavaScript Library 和對 Rapid 的呼叫。

當準備對預訂進行身份驗證時,可能並不總是需要進行身份驗證。是否需要身份驗證由用於付款的信用卡的發卡銀行決定。銀行會在交易過程中做出決定,結果則顯示在「建立預訂 API」的回應。
下圖所示為使用「暫停與繼續處理 API」所需的呼叫順序:

請注意:以上圖示皆為實際 API 流程的簡化版,做為初步說明之用。完整 API 流程請參閱整合相關文件。
有關 3DS 2.0 體驗的技術要求的更多信息,請查看 EMVCo 的 3D 安全協議和核心功能規範。
Rapid API 和 3DS 2.0 整合指南
支援 SCA 需要將 Rapid API 與新的 JavaScript 庫 (稱為 3DS 連接器) 整合。兩者搭配使用,在 check-out 頁面上展示 3DS 2.0 並確認預訂。此解決方案支援 Expedia Collect 和入住時付款兩種商業模式。
支援使用 3DS 2.0 進行預訂所需的 API 呼叫順序概述如下,並在以下章節中詳細說明:
- JavaScript 設定方法
- Rapid 註冊付款 API
- JavaScript 初始化工作階段方法
- Rapid 預訂 API
- JavaScript Challenge 方法
- Rapid 完成付款 API
為了允許此序列,快速合作夥伴支援必須為各個合作夥伴設定檔啟用 3DS 2.0。
Rapid API
如果為合作夥伴資料啟用了身份驗證,API 回應將會有所不同,以允許使用 3DS 2.0 修改預訂流程。
可用性 API
API 請求中sales_channel
欄位的值必須準確,以便在法規允許的情況下獲得身分驗證豁免。發卡銀行會在預訂時審查該價值以及許多其他因素以做出決定。只有代理工具可以免於 SCA。若需註明此項目,請把 sales_channel
的值設為 agent_tool
。
價格檢查 API
API 會回傳連結到「註冊付款 API」,而不是到「建立預訂 API」。
啟用 3DS 2.0 時的範例回應:
{
"status": "matched",
"occupancies": {
//...(example omitted for length)
},
"links": {
"payment_session": {
"method": "POST",
"href": "/v3/payment-sessions?token=QldfCGlcUAVgBDRwdWXBBL"
}
}
}
註冊付款 API
這將是 SCA 預訂流程中的第二步,發生在 JavaScript setup
方法之後。
該請求將包括 non-SCA 預訂流程的付款詳情以及支援成功身份驗證的新欄位。其中兩個欄位:encoded_browser_metadata
和 version
是從 JavaScript API 的 setup method
回傳。
回應中會包括 payment_session_id
和 encoded_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
這將是 SCA 預訂流程中的第四步,發生在 JavaScript initSession
方法之後。該請求將不包含任何 SCA 的新欄位——所有必要資訊都包含在註冊付款 API 返回的預訂連結的令牌中。若回應成功,一定會包含 itinerary_id
。但是,僅憑這一點並不能表明預訂已確認,因為可能需要 3DS 2.0 身份驗證。
如果需要,響應還將包含一個encoded_challenge_config
。從「註冊付款」回傳的 encoded_challenge_config
和 payment_session_id
必須用為參數傳入 JavaScript challenge
方法。
回應還會包括用來 complete_payment_session
的新連結。此連結應於 JavaScript Library 的 challenge
方法之後使用。
如果不需要 3DS 2.0 身份驗證,則預訂得到確認,並且回應將包含 retrieve
、cancel
以及可選的 resume
的連結。
如果需要 3DS 2.0 驗證,則建立預訂回應範例:
{
"itinerary_id": "8999989898988",
"links": {
"complete_payment_session": {
"method": "PUT",
"href": "/v3/itineraries/8999989898988/payment-sessions?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
},
"encoded_challenge_config": "ABElifsiejfacies2@033asfe="
}
完成付款工作階段 API
這將是 SCA 預訂流程中的第六步,發生在 JavaScript challenge
方法之後。需要此 API 來完成付款並通知 Rapid API 安全性驗證嘗試已完成 (無論成功與否)。
該請求將不包含 SCA 的任何新欄位。
如果成功,回應將包含預訂的確認訊息,包括 itinerary_id
和 retrieve
、cancel
以及可選的 resume
的連結。
回應範例:
{
"itinerary_id": "8999989898988",
"links": {
"retrieve": {
"method": "GET",
"href": "/v3/itineraries/8999989898988?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
}
}
Iframe 和 JavaScript 庫實現
使用 SCA 預訂工作流程時,check-out 頁面必須包含新的 iframe 和 JavaScript 庫。此 iframe (稱為 3DS iframe) 將顯示使用 3D-Secure 2.0 的身份驗證體驗。而 JavaScript Library (稱為 3DS Connector Library) 則負責傳送資料給發卡銀行,並把銀行的內容載入 iframe。
添加 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 | 支援生產認證 |
測試沙箱 | https://static.pay.expedia.com/3ds/sandboxThreeDsIframe.html | 支援身份驗證測試 |
上列測試 URL 可支援測試,下文會再回到這個主題。為了在測試期間限制 iframe 的內容,可以將 iframe 歸為沙盒,但必須允許以下內容:
sandbox = ’allow-scripts allow-forms allow-same-origin’;
新增 JavaScript 庫
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.39 | src | https://static.pay.expedia.com/3ds/1.3.39/pay-3ds-js-libs-connector.min.js |
integrity | sha384-par0I4Q5cfljwzqw2mAggM4dKdYzGyj4uZiL4cMviGjI3qVzEgWGuZ2075mYutbT | |
1.3.65 | src | https://static.pay.expedia.com/3ds/1.3.65/pay-3ds-js-libs-connector.min.js |
integrity | sha384-gYopPw6xE5DZwnZXGavkwnvs3NkDOobnHqjroUnSHpGXvs/J9xjHX/8aGzKtSgWI |
請注意:日後有更新版本可用時,這裡的 source URL 和 integrity 也會變更。新版不會破壞現有的整合。舊版的 script 元素仍可存取。
使用 3DS 和 JavaScript 進行 SCA
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
。
Check-out 頁面設計指南
支援 3DS 認證的卡片品牌可能要求按照其指南顯示其徽標和品牌。
支付卡類別 | 認證品牌 | 商標和使用方法 |
---|---|---|
MasterCard (萬事達卡) | 萬事達卡 ID Check | https://brand.mastercard.com/debit/mastercard-brand-mark/downloads.html |
Visa | Visa 驗證 | https://www.merchantsignage.visa.com/brand_guidelines |
備註:待其他卡別的商標和使用辦法公布時會再納入此表。
3DS Connector JavaScript Library 相關文件
類別 (Class):ThreeDSConnector
構造函數: new ThreeDSConnector(threeDsIFrameId, threeDsIFrameOrigin)
參數:
名稱 | 類型 | 說明 |
---|---|---|
threeDsIFrameId | 字串 | 3DS iframe 的 ID。 |
threeDsIFrameOrigin | 字串 | 3DS iframe 的原點 (Origin)。在與 3DS iframe 溝通使用以傳出視窗訊息並過濾接受訊息。 |
設定
透過收集後端 3DS 服務所需的瀏覽器基本詳細資訊 (例如螢幕尺寸、色彩深度等) 來設定支付工作階段。
方法簽名: setup(setupRequest)
參數:
名稱 | 類型 |
---|---|
setupRequest | SetupRequest |
返回: 承諾 SetupResponse
初始化
初始化與 3DS 進行身份驗證的會話。進行初始化可能需要從瀏覽器收集其他資料。若發卡機構提出要求,iframe 可載入 3DS URL 來啟動發卡機構的存取控制伺服器 (Access Control Server),直接從瀏覽器收集資料。用戶端不必等待回呼完成,於建立命令前即可調用。
方法簽名: initSession(initSessionRequest)
參數:
名稱 | 類型 |
---|---|
initSessionRequest | InitSessionRequest |
返回: 承諾 InitSessionResponse
挑戰 (Challenge)
如果發卡機構要求,請載入 3DS 驗證體驗。
方法簽名: challenge(challengeRequest)
參數:
名稱 | 類型 |
---|---|
challengeRequest | ChallengeRequest |
返回: 承諾 ChallengeResponse
類別 (Class):SetupRequest
設定呼叫的需求架構。
性質:
名稱 | 類型 | 說明 |
---|---|---|
referenceId | string | 辨識旅客付款頁面工作階段的參考 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
值,請繼續使用快速預訂 API。
類別 (Class):ChallengeRequest
挑戰 (Challenge) 方法的需求架構。
性質:
statusCode 值 | 測試 encoded_Challenge_config 值 | 說明 |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | 無使用者 iframe 互動 |
SUCCESS / FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | 無使用者 iframe 互動 |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | 無使用者 iframe 互動 |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
statusCode 可能會有以下的值:
值 | 說明 |
---|---|
SUCCESS | 3DS 挑戰 (Challenge) 成功完成。 |
SKIPPED | 外部應用程式錯誤。 |
FAILED | 由於持卡人無法正確回應身分驗證挑戰,故 3DS 挑戰未成功完成。 |
TIMEOUT | 挑戰未在時間內完成。時限為 1200 秒。 |
注意:對於所有 challengeResponse
statusCode
值,請繼續使用 Rapid API 完成付款會話。
使用 Rapid API 和 3DS 2.0 進行測試
您可以使用與 API 支援的特定場景相對應的輸入參數值來測試與 Rapid API 和 3DS 連接器方法的整合。
Rapid API
要測試 Rapid API,請在 HTTP 請求中包含一個名為 test
的附加 HTTP 標頭,並使用該 API 支援的值之一來測試支援的場景。
在 SCA 預訂流程中,來自 Rapid API 的測試回應也可用於測試 3DS 連接器庫方法。
註冊付款 (Register Payments)
以下測試標頭值在 API 回應中會產生不同 encoded_init_config
,以及不同 HTTP 回應碼。encoded_init_config
可傳入 JavaScript Library 的 initSession
呼叫,以啟動 3DS Connector Library 中的不同測試用例。
測試標題值 | HTTP 代碼與回應 | initSession 測試用例 |
---|---|---|
standard | 201 – 標準回應 | SUCCESS |
init_skip | 201 - 不含 encodedInitConfig 的回應 | Not supported |
init_fail | 201 – 標準回應 | FAILED |
init_timeout | 201 – 標準回應 | TIMEOUT |
internal_server_error | 500 – 內部伺服器錯誤 | |
internal_server_error | 503 - 伺服器無法使用 |
備註:init_skip
3DS Connector Library.t_config
裡的不同測試案例可傳到 initSession
,便會強行產生名為 SKIPPED 的 statusCode
。
建立預訂
除了快速預訂測試請求中為 non-SCA 預訂流程定義的測試標頭之外,SCA 工作流程還支援其他測試標頭值。
測試標頭值會產生不同的 encodedChallengeConfig
值,這些值可傳入 JavaScript Library 的 challenge
呼叫,以觸發不同的測試案例。
測試標題值 | HTTP 代碼與回應 | initSession 測試用例 |
---|---|---|
complete_payment_session | 201 – 含完成付款工作階段連結的回應 | SUCCESS 無使用者 iframe 互動 |
complete_payment_session_show | 201 – 含完成付款工作階段連結的回應 | SUCCESS/FAILED 有使用者 iframe 互動 |
complete_payment_session_fail | 201 – 含完成付款工作階段連結的回應 | FAILED 無使用者 iframe 互動 |
complete_payment_session_timeout | 201 – 含完成付款工作階段連結的回應 | TIMEOUT |
complete_payment_session_error | 201 – 含完成付款工作階段連結的回應 | ERROR |
完成付款工作階段
在試著完成付款並確認預訂時,測試標頭值會產生不同錯誤情況。
測試標題值 | HTTP 代碼與回應 |
---|---|
payment_declined | 400 - 付款遭拒回應 |
price_mismatch | 409 - 房價不符回應 |
rooms_unavailable | 410 - 無空房回應 |
3DS Connector Library 和 iframe
在無外部相依關係下測試 3DS Connector 時,需使用符合支援方法回應的特定參數值。僅限 iframe 用測試沙箱 URL 載入時才支援這種做法。
初始化工作階段
InitSessionResponse statusCode
所支援的值可用變更 initSessionRequest encodedInitConfig
的方法來測試。
statusCode 值 | 測試 encodedInitConfig 值 |
---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJTVUNDRVNTIn1d |
FAILED | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJGQUlMRUQifV0= |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJUSU1FT1VUIn1d |
SKIPPED | Not supported at this time. |
注意:encoded_init_config
值也可以使用「註冊付款 API」支援的測試標頭產生。
挑戰 (Challenge)
challengeResponse statusCode
所支援的值可用變更 challengeRequest encondedChallengeConfig
的方法來測試。
statusCode 值 | 測試 encoded_Challenge_config 值 | 說明 |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | 無使用者 iframe 互動 |
SUCCESS / FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | 無使用者 iframe 互動 |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | 無使用者 iframe 互動 |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
這encodedInitConfig
也可以使用 Booking API 的 SCA 流支援的測試標頭產生值。
注意:根據使用者使用 iframe 的輸入測試質詢狀態代碼值為 SUCCESS 或 FAILED 時,質詢方法回應將等待 iframe 中模擬的驗證介面完成。
3DS iframe 中的 UI 範例:

用法範例
以下為執行範例,僅供參考。範例中可看到如何使用預先定義的值來測試 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
});
3DS 身份驗證和財產收集
透過飯店自取預訂時,Expedia 不會從卡片中扣款。相反,我們會將其送至酒店進行處理。旅宿可能會用收到的資訊在入住前先進行信用卡驗證。預計旅客將親自前往 check-in 付款。
然而,有些旅客在預訂後卻沒有入住,此時旅宿就會收取未入住罰款。這些費用可能會受到 SCA 法規的影響,因為它們涉及在旅行者不在場時向卡片收費。
當交易受 PSD2 影響而收款手續卻不符規定,則可能會導致交易失敗,旅宿也可能會面臨信用卡公司的罰款。
Expedia Group 為了維持與旅宿的良好關係,並繼續服務我們的合作夥伴,因此提供給旅宿另一項合規辦法:受影響的財產現在可以利用 Expedia Group 代表他們提供身份驗證。這使得飯店能夠保護他們的業務,並確保 Rapid API 可以繼續提供同樣多樣化的飯店服務。
Rapid API 提供<payment_registration_recommended=true>
在屬性內容檔案和屬性內容中,這可以幫助您在專案中可能涉及的屬性時識別該屬性。
對整合的可能影響
如果您想提供需要安全身份驗證的住宿,那麼預訂路徑應該支援 3DS。如果不支援 3DS,且 card-issuing 銀行確定交易需要身份驗證,則預訂這些房產可能會失敗。
當飯店收取 no-show 費用時,Rapid API 將成為記錄商家。信用卡帳單上的費用描述將由您的組織而非飯店定義。若想自訂此名稱,請聯絡 Rapid 合作夥伴服務。
為了符合卡片品牌的要求和 Rapid API 啟動流程,請使用接受付款 API 顯示processing_country
如果是 no-show,則在 check-out 頁面上。對於所有以 Rapid API 為記錄商家的交易,這都是必需的,並且如果使用 3DS 並且發生 no-show,則可能會發生這種情況。
如何減輕對整合的影響
如果 Rapid API 整合不支援預訂流程中的安全身份驗證,則可以透過不出售這些房產來降低預訂失敗的風險。聯絡快速合作夥伴支持,從可用性 API 回應中刪除受影響的房產收費率。
使用代理工具時,交易依規定免除 SCA。如有需要,可在「供應情況 API」的 sales_channel
欄位加註。
錯誤處理
「建立預訂 API」和「完成付款工作階段 API」可能會產生預訂確認和付款交易。
系統整合時請考慮以下說明,以避免財物損失和客戶操作的情形。
來源 | 功能 | 建議時限 | 錯誤復原做法 | 需採取的行動 |
---|---|---|---|---|
Rapid API | 註冊付款的預訂前價格檢查記號 | 10 秒 | 重試或選擇其他住宿、客房或房價 | - |
JavaScript | 3DS Connector 設定 | 10 秒 | 重試相同的要求 | - |
Rapid API | 註冊付款工作階段 | 10 秒 | 重試相同的請求,無需 [“Expect: 100-Continue”進程](https://tools.ietf.org/html/rfc7231#section-6.2.1 ’Follow link’) | - |
JavaScript | 初始化付款工作階段 | 10 秒 | 重試相同的要求 | - |
Rapid API | 建立預訂 | 90 秒 | 重試相同的要求 | 所有錯誤:用 affiliate_reference_id 取回預訂 |
JavaScript | 顯示身份驗證挑戰 | 10 秒 | 重試相同的要求 | - |
JavaScript | 等待 challenge.statusCode | 180 ~ 1200 秒 | 要求完成付款工作階段 | - |
Rapid API | 完成付款工作階段 (Complete Payment Session) | 90 秒 | 重試相同的要求 | 所有錯誤:用 affiliate_reference_id 取回預訂 |
Rapid API | 所有錯誤:用 affiliate_reference_id 取回預訂 | 30 秒 | 重試相同的要求 | 所有錯誤:等待 90 秒後再重試,用 API 回應碼 404 或 200 確認預訂最後狀態 |