遵守严格的客户身份验证规定
了解网上信用卡支付的身份验证规定。
概述
监管机构和卡网络正在引入新的要求,以加强在线支付的安全性并保护消费者免受欺诈。许多法规都要求在线支付时使用强客户身份验证 (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 联盟伙伴收款
使用 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 流程的更多信息。
集成组件详细信息
浏览器内嵌框架
放置在 check-out 体验中的 iframe 托管着旅行者 card-issuing 银行拥有的 URL。此 URL 将向用户显示身份验证体验,并将任何 traveler-supplied 信息直接传输到他们的银行。Iframe 最初应该是隐藏的,当预订尝试后需要进行身份验证质询时,可以将其覆盖在页面顶部。
浏览器 JavaScript 库
该库被添加到 check-out 页面,并在预订时调用以支持身份验证过程。该库的 API 支持下述功能。
自动收集旅客的设备信息
在尝试预订之前,必须收集有关旅行者设备的信息,以准备进行身份验证的预订。该信息被发送到旅行者的 issuing-bank 进行审查,以便银行可以评估风险,决定交易是否需要 3DS 2.0 身份验证,并确保其正确显示。根据 3DS 2.0 规范,将从旅行者的浏览器中收集以下数据:语言、颜色深度、屏幕高度、屏幕宽度、时区、用户代理以及是否启用 Java。
在浏览器 iframe 中显示身份验证体验
尝试预订后,该库用于显示内嵌框架覆盖并将银行的内容加载到内嵌框架中。在身份验证过程中,银行的内容可能会收集有关旅行者设备的其他信息,以支持他们的风险评估。完成预订需要此流程。
Rapid API
Rapid API 包含与 client-side JavaScript 库协同工作的 API。这些 API 现在支持下述功能。
旅客及付款详情注册
在尝试预订之前,必须收集有关旅行者的其他信息,以准备进行预订验证。这些数据包括旅客在销售网站的账户和旅客付款的详细信息,这些数据随后被发送到旅行者的 issuing-bank 进行审查,以便银行可以评估风险并决定交易是否需要安全认证。请查看 Rapid 中的注册付款信息 API,了解更多信息。
完成付款和确认预订
使用 Rapid API 尝试预订并在浏览器上完成 SCA 流程后,必须再次调用 Rapid。我们将在后台确认身份验证是否确实成功,以便确认预订。请查看 Rapid 中的完成付款会话,了解更多信息。
预订流程
如果在合作伙伴资料快速支持中启用了 3DS 2.0,则价格查询API 将返回一个链接注册付款API 而不是创建预订API。以下是旅客发起预订后所需的 API 调用序列图。该序列涉及对 JavaScript 库和 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 并确认预订。这种解决方案同时支持预付和住宿收款业务模式。
支持使用 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 库 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 库的 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 库又称 3DS 连接器库,将支持向发卡银行传输信息并将银行的内容加载到内嵌框架。
添加 iframe
应将 3DS 内嵌框架包装在一个容器中,最初为隐藏状态,但在需要身份验证挑战以处理付款时可以显示。
容器的设计可以自定义,以适应托管页面需求。以下例子展示了一个使用 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>
内嵌框架的源必须设置为以下两个值之一:
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 连接器库与 3DS 内嵌框架通信并将数据发送到提供内嵌框架内容的发卡银行。下面的例子展示了如何将库添加到付款页面的示例。
<head>
<script src="<<3DS connector script URL>>" integrity="<<actual integrity value>>"></script>
</head>
脚本元素的源和 integrity 值应设置为以下值:
库版本 | 属性 | 值 |
---|---|---|
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 |
注:随着未来新版本的推出和采用,源 URL 和 integrity 将发生变化。较新的版本应该不会破坏现有的集成。较旧版本的脚本仍然可以访问。
使用 3DS 和 JavaScript 进行 SCA
库需要使用 JavaScript Promises。下面的例子展示了一个仅供参考的实施示例,演示了数据是如何在 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 连接器库的一部分,旨在演示支持将信息传输到 API 的包装器。
此例子对应在运行时确定的参数使用了静态值,例如:referenceId
Check-out 页面设计指南
支持 3DS 认证的卡品牌可能要求按照其指南显示其徽标和品牌。
信用卡品牌 | 认证品牌 | 徽标和指南 |
---|---|---|
万事达卡 | Mastercard identity check | https://brand.mastercard.com/debit/mastercard-brand-mark/downloads.html |
维萨卡 | Visa secure | https://www.merchantsignage.visa.com/brand_guidelines |
注:其他信用卡品牌的徽标和指南一旦可用即将包含在内。
3DS 连接器 JavaScript 库文档
类:ThreeDSConnector
构造函数: new ThreeDSConnector(threeDsIFrameId, threeDsIFrameOrigin)
参数:
名称 | 类型 | 说明 |
---|---|---|
threeDsIFrameId | 字符串 | 3DS 内嵌框架的 ID。 |
threeDsIFrameOrigin | 字符串 | 3DS 内嵌框架的源。用于在与 3DS 内嵌框架通信时以传出窗口消息为目标和筛选传入消息。 |
设置
通过收集后端 3DS 服务所需的浏览器基本详细信息(例如屏幕尺寸、颜色深度等)来设置支付会话。
方法签名: setup(setupRequest)
参数:
名称 | 类型 |
---|---|
setupRequest | SetupRequest |
返回: 承诺 SetupResponse
初始化
初始化会话以使用 3DS 进行身份验证。作为初始化的一部分,可能会从浏览器收集其他数据。如果发卡机构要求,可以将 3DS 方法 URL 加载到内嵌框架中,以使发卡机构的访问控制服务器能够直接从浏览器收集数据。客户端不需要等待调用完成回调,就可以创建订单。
方法签名: initSession(initSessionRequest)
参数:
名称 | 类型 |
---|---|
initSessionRequest | InitSessionRequest |
返回: 承诺 InitSessionResponse
挑战
如果发卡机构要求,请加载 3DS 身份验证体验。
方法签名: challenge(challengeRequest)
参数:
名称 | 类型 |
---|---|
challengeRequest | ChallengeRequest |
返回: 承诺 ChallengeResponse
类:SetupRequest
设置调用的请求结构。
属性:
名称 | 类型 | 说明 |
---|---|---|
referenceId | string | 用于标识旅客付款会话的参考 ID。用于记录和跟踪。使用下划线连接您的 APIKey 和 Customer-Session-ID 。示例:[APIKey]_[SessionID] |
类:SetupResponse
来自设置调用的响应。
属性:
名称 | 类型 | 说明 |
---|---|---|
version | 字符串 | 此库的版本,与库的 URL 路径中显示的版本相同。 |
encodedBrowserMetadata | 字符串 | 包含收集的浏览器详细信息的编码对象。客户端应将此视为不公开数据,无需解析即可传递给后端付款服务。 |
类:InitSessionRequest
initSession
方法的请求结构。
属性:
名称 | 类型 | 说明 |
---|---|---|
paymentSessionId | 字符串 | Rapid 注册付款信息 API 返回的唯一 ID。 |
encodedInitConfig | 字符串 | 包含初始化所需数据的配置对象的编码列表,由 Rapid 注册付款信息 API 返回。 |
类:InitSessionResponse
initSession
方法的响应结构。
属性:
名称 | 类型 | 说明 |
---|---|---|
statusCode | 字符串 | initSession 调用的状态。 |
message | 字符串 | 可选。指明失败原因。 |
statusCode
的可能值:
值 | 说明 |
---|---|
SUCCESS | 初始化成功完成。 |
SKIPPED | 没有进行初始化。 |
FAILED | 初始化失败。消息字段包含有关失败的其他信息。 |
TIMEOUT | 初始化未在有效时间内完成。超时持续时间为 10 秒。 |
注意:对于所有 initSessionresponse
statusCode
值,请继续使用快速预订 API。
类:ChallengeRequest
挑战方法的请求结构。
属性:
statusCode 值 | 测试 encoded_Challenge_config 值 | 说明 |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | 没有用户内嵌框架互动 |
SUCCESS/FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | 没有用户内嵌框架互动 |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | 没有用户内嵌框架互动 |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
statusCode 的可能值
值 | 说明 |
---|---|
SUCCESS | 3DS 挑战成功完成。 |
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 连接器库方法。
注册付款
以下测试标头值会在 API 响应中产生不同的 encoded_init_config
值和不同的 HTTP 响应代码。encoded_init_config
可以传递到 JavaScript 库的 initSession
调用中,以触发 3DS 连接器库中的不同测试案例。
测试标头值 | HTTP 代码和响应 | initSession 测试案例 |
---|---|---|
standard | 201 – Standard Response | SUCCESS |
init_skip | 201 - Response Without encodedInitConfig | Not supported |
init_fail | 201 – Standard Response | FAILED |
init_timeout | 201 – Standard Response | TIMEOUT |
internal_server_error | 500 – Internal Server Error | |
internal_server_error | 503 - Server Unavailable |
注:3DS 连接器 Library.t_config
中不同的 init_skip
测试案例可以传递给 initSession
并强制执行 SKIPPED 的 statusCode
。
创建预订
除了快速预订测试请求中为 non-SCA 预订流程定义的测试标头之外,SCA 工作流还支持其他测试标头值。
测试标头值会产生不同的 encodedChallengeConfig
值,这些值可以传递至 JavaScript 库的 challenge
调用中,以触发不同的测试案例。
测试标头值 | HTTP 代码和响应 | initSession 测试案例 |
---|---|---|
complete_payment_session | 201 – Response with complete payment session link | SUCCESS without user iframe interaction |
complete_payment_session_show | 201 – Response with complete payment session link | SUCCESS/FAILED with user iframe interaction |
complete_payment_session_fail | 201 – Response with complete payment session link | FAILED without user iframe interaction |
complete_payment_session_timeout | 201 – Response with complete payment session link | TIMEOUT |
complete_payment_session_error | 201 – Response with complete payment session link | ERROR |
完成付款会话
测试标头值会产生不同错误案例,可能会在尝试完成付款和确认预订时发生。
测试标头值 | HTTP 代码和响应 |
---|---|
payment_declined | 400 - Payment declined response |
price_mismatch | 409 - Price mismatch response |
rooms_unavailable | 410 - Rooms unavailable response |
3DS 连接器库和内嵌框架
要在没有外部依赖因素的情况下测试 3DS 连接器,特定的参数值应对应于支持的方法响应。仅当内嵌框架使用测试沙盒 URL 加载时才支持此行为。
初始化会话
InitSessionResponse statusCode
的受支持值可以通过改变 initSessionRequest encodedInitConfig
来进行测试。
statusCode 值 | 测试 encodedInitConfig 值 |
---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJTVUNDRVNTIn1d |
FAILED | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJGQUlMRUQifV0= |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJUSU1FT1VUIn1d |
SKIPPED | 目前不支持。 |
注:encoded_init_config
值也可以使用注册付款信息 API 的受支持测试标头生成。
挑战
challengeResponse statusCode
的受支持值可以通过改变 challengeRequest encondedChallengeConfig
来进行测试。
statusCode 值 | 测试 encoded_Challenge_config 值 | 说明 |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | 没有用户内嵌框架互动 |
SUCCESS/FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | 没有用户内嵌框架互动 |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | 没有用户内嵌框架互动 |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
这encodedInitConfig
还可以使用 Booking API 的 SCA 流支持的测试标头生成值。
注意:当根据用户使用 iframe 的输入测试质询状态代码值为 SUCCESS 或 FAILED 时,质询方法响应将等待 iframe 中模拟的身份验证界面完成。
3DS 内嵌框架中的 UI 示例:

示例用法
以下例子展示了一个实施示例,仅作参考。该例子演示了如何使用预定义的参数值来针对 3DS 挑战对库进行测试,而无需用户与内嵌框架互动。
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 法规的影响,因为它们涉及在旅行者不在场时向卡收费。
如果交易受到影响,付款可能会失败,如果收费不符合规定,住宿也可能会面临信用卡品牌方的处罚。
为了保护我们与住宿之间的关系并继续为我们的合作伙伴服务,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 连接器设置 | 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 | 完成付款会话 | 90 秒 | 重试相同的请求 | 对于所有错误:使用 affiliate_reference_id 检索预订 |
Rapid API | 对于所有错误:使用 affiliate_reference_id 检索预订 | 30 秒 | 重试相同的请求 | 对于所有错误:等待 90 秒后再重试,以通过 API 响应代码 404 或 200 确认预订的最终状态 |