PSD2 European compliance
Understand the impact of new EEA card payment regulations on your business.
Overview
The Payment Services Directive 2 (PSD2) is an EEA regulation that requires changes to the check-out and booking process for all transactions involving a credit card issued by an EEA state.
PSD2 increases security and reduces fraud however it also fundamentally changes the way payments work across Europe. As a part of these regulations, a solution for strong customer authentication is required when handling electronic consumer payments within the scope of the regulations. All card issuers, acquiring banks, and merchants are required to support a strong customer authentication solution. Non-compliance will result in failed payments as banks within the EEA are enforcing the regulations.
This page explains how supported Rapid API payment types are impacted and what actions partners can take to be compliant when serving their travelers. If you would like to learn about the directive in more detail, please review the legislation on the official European Commission site.
Compliance requirements
The steps to enable compliant transactions in the EEA will vary depending on who the merchant of record is and how payments are made to the Rapid API.
Partner is merchant of record
Expedia Affiliate Collect
Bookings that use EAC are unaffected by the PSD2 regulations. No payment process or API integration changes with Rapid are needed to reach compliance. However, you may be impacted by the regulations if you are the merchant of record and charge travelers' credit card, debit card, or other form of payment within the scope of the EU regulations. The regulations likely require you to support a PSD2-compliant version of two-factor authentication, or 2FA, in the payment process. Please reach out to your payment processor to learn more about their capabilities to help merchants reach PSD2-compliance and avoid failed transactions.
Partner cards
If your company is the merchant of record and pays Rapid with an EEA-issued credit or debit card owned by your company, you may be impacted by the regulations. The list of PSD2-compliant cards is:
- Single-use virtual cards issued in the EEA.
- Corporate cards issued to your company, not to an individual, and issued in the EEA.
- Any card issued outside the EEA.
You may also be impacted by the regulations if you charge travelers’ credit card, debit card, or other form of payment within the scope of the EEA regulations. The regulations likely require you to support a PSD2-compliant version of two-factor authentication, or 2FA, in the payment process. Please reach out to your payment processor to learn more about their capabilities to help merchants reach PSD2-compliance and avoid failed transactions.
If the above PSD2-compliant partner cards are not preferable, your organization can request an exemption directly from the bank that has issued your partner card. If an exemption is granted, transactions on that card will not require authentication except for a possible one-time online verification using 2FA. This one-time requirement can vary by bank. Please note that obtaining an exemption can be lengthy process and it will also mean that your bank may hold you liable for any fraudulent payments.
Rapid is the merchant of record
If your company uses Rapid as the merchant of record by sending travelers' cards to Rapid, you may be impacted by the regulations. When travelers book online, without a retail agent, the regulations require that Rapid let travelers verify whether they initiated the payment. The PSD2-compliant process for this requirement is two-factor authentication, or 2FA, during the payment process. Partners that want to use Rapid as the merchant of record with any EEA-issued credit or debit card will need to adopt our Rapid solution for 2FA.
However, transactions that are booked through a retail agent or call center agent are exempt from the 2FA requirement. Compliance for these transactions only requires an explicit indication that that booking was made with the assistance of an agent. Use the Availability API’s sales_channel
field for this indication.
Property is the merchant of record
If your company uses Property Collect you may be impacted by the regulations. There are circumstances where a property may try to charge a traveler's card without the traveler present, e.g. 'no show' fees or deposits. These charges are not compliant without two-factor authentication, or 2FA, being performed prior to the charge. Partners that want to use Property Collect for travelers using an EEA-issued credit or debit card will need to adopt our Rapid solution for 2FA.
Overview of the Rapid API solution
How does it work?
Partners that use Rapid merchant of record or property collect with traveler cards can adopt Rapid’s API solution to generate bookings that are compliant with the regulations. The APIs support PSD2 compliance by supporting two-factor authentication with 3DS 2.0 in the booking flow. With 3DS 2.0 we support risk-based authentication, which reduces friction with travelers by granting the banks discretion about when to challenge travelers with 2FA and when to not.
The solution for 2FA is comprised of three distinct components:
- An iframe that partners add to the check-out page. It’s used to host an issuing bank’s 2FA experience for the traveler. In the integration documentation it’s referred to as the 3DS iframe.
- A new client-side JavaScript library that resides on the check-out page. It’s used to collect browser data, communicate with the iframe, and display the 2FA experience within the iframe. In the integration documentation it’s referred to as the 3DS Connector Library.
- Rapid accepts payer information for the bank and completes the booking after 2FA.
When using JavaScript and Rapid together, the booking flow with 2FA will now include a few additional steps before and after the Booking API is called. Below is a diagram that depicts this updated booking flow.
During each step of the revised booking flow, the output of one step contains data that is used as input into the next step. Data will need to be passed between the JavaScript on the browser and Rapid.
Note: The diagram above is a simplification of the actual API flow meant for introductory purposes. Reference the integration documentation to learn more about the complete API flow.
Integration component details
Browser iframe
The iframe, placed in the check-out experience, hosts a URL owned by the traveler's card-issuing bank. This URL will display the 2FA experience to the user and transfer any traveler-supplied information directly to their bank. The iframe should be hidden initially, with the ability to overlay it on top of the page when a 2FA challenge is required after a booking attempt.
Browser JavaScript library
This library is added to the check-out page and is invoked at the time of booking to support the 2FA process. The library’s APIs support the capabilities described below.
Automatic collection of traveler’s device information
Before a booking attempt, information about the traveler’s device must be collected to prepare a booking for 2FA. It is later sent to the traveler’s issuing-bank for review so the bank can assess risk, decide if 2FA is required for the transaction, and ensure that it’s displayed correctly. In accordance with the 3DS 2.x specifications the following data will be collected from the traveler’s browser: language, color depth, screen height, screen width, time zone, user agent, and whether Java is enabled.
Display the 2FA experience in the browser iframe
After a booking attempt, the library is used to display iframe overlay and load the bank’s content into the iframe. During the 2FA process, the bank’s content may collect additional information about the traveler’s device to support their risk assessment. This process is needed to complete a booking.
Rapid
Rapid includes APIs that work in conjunction with the client-side JavaScript library. The APIs now support the capabilities described below.
Registration of traveler and payment details
Before a booking attempt, additional information about the traveler must be collected to prepare a booking for 2FA. This data includes details of the traveler’s account with the point of sale and the traveler’s payment. This data is later sent to the traveler’s issuing-bank for review so the bank can assess risk and decide if 2FA is required for the transaction. Learn more by reviewing Register Payment API in Rapid.
Completion of a payment and confirmation of booking
After a booking attempt with Rapid and the 2FA process is completed on the browser, Rapid must be invoked once more. Behind the scenes, we’ll confirm that the 2FA was actually successful, so the booking can be confirmed. Learn more by reviewing the Complete Payments Session in Rapid.
Booking flow
Overview
If 2FA is enabled in Partner Profile Rapid Support, the Price Check API will return a link to the Register Payments API instead of the Create Booking API. Below is a diagram of the API call sequence that will be required after a booking is initiated by a traveler. The sequence involves both calls to the JavaScript Library and Rapid.
When a booking is prepared for 2FA, it may not always be required. The need for 2FA is determined by the issuing bank of the credit card used for payment. This determination occurs during the transaction and is indicated in the in the Create Booking API response.
Below is a diagram of the API call sequence required when using Hold and Resume.
Note: The diagrams above are a simplification of the actual API flow meant for introductory purposes. Reference the integration documentation to learn more about the complete API flow.
More information
For further information on the technical requirements for the 2FA experience, review the EMVCo’s 3D secure protocol and core functions specification.
Rapid and two-Factor authentication integration guide
Overview
Supporting two-factor authentication, or 2FA, will require integration with a new JavaScript library, referred to as the 3DS Connector, and Rapid. The two are used in conjunction to present 2FA on the check-out page and confirm a booking. This solution supports both Expedia collect and property collect business models.
The sequence of API calls needed to support a booking with 2FA are outlined below and detailed in the following sections:
- JavaScript set-up method
- Rapid Register Payment API
- JavaScript initialize session method
- Rapid Book API
- JavaScript challenge method
- Rapid Complete Payment API
To allow this sequence, 2FA must be enabled for individual partner profiles by Rapid Partner Support.
Rapid
If two-factor authentication is enabled for a partner profile, API responses will differ to allow a revised booking flow with 2FA.
Availibility API
The value of the sales_channel
field in the API request must be accurate to obtain an exemption from 2FA when it’s permissible by the regulations. This value, along with many other factors, is reviewed by the card’s issuing bank to make their decision during the time of booking. Only agent tools are exempt from 2FA. To specify this, set the value of sales_channel
to agent_tool
.
Price Check API
The API response will include a link to the Register Payments API instead of the Create Booking API.
Example response when 2FA is enabled:
{
"status": "matched",
"occupancies": {
//...(example omitted for length)
},
"links": {
"payment_session": {
"method": "POST",
"href": "/v3/payment-sessions?token=QldfCGlcUAVgBDRwdWXBBL"
}
}
}
Register Payments API
This will be the second step in the JavaScript-Rapid PSD2 booking flow and occurs after the JavaScript setup
method.
The request will include payment details that are part of the non-PSD2 booking flow and new fields that support a successful 2FA. Two of these fields, encoded_browser_metadata
and version
, are returned from the JavaScript API’s setup method
.
The response will include a payment_session_id
and encoded_init_config
. These are specified as inputs into the initSession
method of the JavaScript library. The book link included in the response should be used after the initSession
method.
Example request:
{
"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"
}
]
}
Example response:
{
"payment_session_id": "76d6aaea-c1d5-11e8-a355-529269fb1459",
"encoded_init_config": "QSBiYXNlNjQgZW5jb2RlZCBvYmplY3Qgd2hpY2ggY29udGFpbnMgY29uZmlndXJhdGlvbiBuZWVkZWQgdG8gcGVyZm9ybSBkZXZpY2UgZmluZ2VycHJpbnRpbmcgYW5kL29yIDNEUyBNZXRob2Qu",
"links": {
"book": {
"method": "POST",
"href": "/v3/itineraries?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
}
}
Create Booking API
This will be the fourth step in the JavaScript-Rapid PSD2 booking flow and occurs after the JavaScript initSession
method. The request will not include any new fields for PSD2, all needed information is contained within the token of the Book link returned by the Register Payment API. The response, if successful, will always contain an itinerary_id
. However, this alone does not indicate that a booking is confirmed because 2FA may be required.
If 2FA is required, the response will also include an encoded_challenge_config
. The encoded_challenge_config
and payment_session_id
returned from Register Payment will need to be passed as parameters into the JavaScript challenge
method.
The response will also include a new link for complete_payment_session
. This link should be used after challenge
method of the JavaScript library.
If 2FA is not required, the booking is confirmed and the response will include links for retrieve
,cancel
, and, optionally, resume
.
Example Create Booking response if 2FA is required:
{
"itinerary_id": "8999989898988",
"links": {
"complete_payment_session": {
"method": "PUT",
"href": "/v3/itineraries/8999989898988/payment-sessions?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
},
"encoded_challenge_config": "ABElifsiejfacies2@033asfe="
}
Complete Payment Session API
This will be the sixth step in the JavaScript-Rapid PSD2 booking flow and occurs after the JavaScript challenge
method. This API is required to complete the payment and inform Rapid that a 2FA attempt was completed, successfully or not.
The request will not include any new fields for PSD2.
The response, if successful, will contain an itinerary_id
and links for retrieve
, cancel
, and, optionally, resume
. A successful response that a booking is confirmed.
Example response:
{
"itinerary_id": "8999989898988",
"links": {
"retrieve": {
"method": "GET",
"href": "/v3/itineraries/8999989898988?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
}
}
3DS connector JavaScript library and 3DS iframe
When using the PSD2 booking workflow, the check-out page must include a new iframe and JavaScript library. The iframe, referred to as the 3DS iframe, will display the authentication experience using 3D-Secure 2.x to the traveler. The JavaScript library, refered to as the 3DS Connector Library, will support the transfer of information to issuing banks and load the banks’ content into the iframe.
Adding the 3DS iframe and JavaScript library
Adding the 3DS iframe
The 3DS iframe should be wrapped in a container that is initially hidden but can be displayed when an authentication challenge is required to process a payment.
The design of the container can be customized to suit the hosting page. The sample below shows an example implementation meant for guidance only, using a bootstrap modal.
<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>
The source of the iframe must be set to one of two values:
URL type | URL | Notes |
---|---|---|
Production | https://static.pay.expedia.com/3ds/threeDsIframe.html | Supports production 2FA |
Testing sandbox | https://static.pay.expedia.com/3ds/sandboxThreeDsIframe.html | Supports testing of 2FA |
The test URL supports testing and this topic is reviewed later in this document. To restrict the contents of the iframe during testing, iframe can be attributed with sandbox however it must allow the following:
sandbox = 'allow-scripts allow-forms allow-same-origin';
Adding the 3DS connector JavaScript library
The 3DS connector library communicates with the 3DS iframe and sends data to the issuing bank, which provides the iframe content. The sample below shows an example of how to add the library to the check-out page.
<head>
<script src="<<3DS connector script URL>>" integrity="<<actual integrity value>>"></script>
</head>
The source and integrity values of the script element should be set to the below values:
Library version | Attribute | Value |
---|---|---|
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 |
Note: The source URL and integrity will change as future versions are available for adoption. Newer versions should not break existing integration. Older versions of the script will still be accessible.
Using the 3DS iframe and JavaScript library
The library requires the use of JavaScript promises. The sample below shows an example implementation meant for guidance only and demonstrates how data is exchanged between the JavaScript methods and 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 => {
...
});
Note: References to the RapidIntegration
class are part of the example and not part of the 3DS connector library. They are meant to demonstrate a wrapper that supports the transfer of information to the APIs.
The sample uses static values for parameters that should be determined at run time, e.g. referenceId
.
Check-out page guidelines
Card brands that support 2FA may require that their logos and branding be displayed in accordance with their guidelines.
Card brand | 2FA branding | Logos and guidance |
---|---|---|
Mastercard | Mastercard identity check | (https://brand.mastercard.com/debit/mastercard-brand-mark/downloads.html))] |
Visa | Visa secure | [https://www.merchantsignage.visa.com/brand_guidelines |
Note: Logos and guidance for other card brands will be included as they become available.
3DS connector JavaScript library documentation
Class: ThreeDSConnector
Constructor
new ThreeDSConnector(threeDsIFrameId, threeDsIFrameOrigin)
Parameters:
Name | Type | Description |
---|---|---|
threeDsIFrameOrigin | string | The ID of the 3DS iframe. |
threeDsIFrameOrigin | string | The origin of the 3DS iframe. Used to target outgoing window messages and filter incoming messages when communicating with the 3DS iframe. |
Method
Setup
Sets up the payment session by collecting basic details about the browser needed by backend 3DS service, such as screen size, color depth, etc.
Method signature:
setup(setupRequest)
Parameters:
Name | Type |
---|---|
setupRequest | SetupRequest |
Returns:
Promise for a SetupResponse
Intialize session
Initializes the session for authentication with 3DS. As a part of the initialization, additional data may be collected from the browser. If required by the card issuer, a 3DS method URL could be loaded into the iframe to enable the card issuer’s access control server to collect data from the browser directly. The client doesn’t have to wait for the completion callback to be invoked before the order can be created.
Method signature:
initSession(initSessionRequest)
Parameters:
Name | Type |
---|---|
initSessionRequest | InitSessionRequest |
Returns: Promise for an InitSessionResponse
Challenge
Loads the 3DS authentication experience, if required by the card issuer.
Method signature:
challenge(challengeRequest)
Parameters:
Name | Type |
---|---|
challengeRequest | ChallengeRequest |
Returns: Promise for a ChallengeResponse
Class: SetupRequest
Request structure for the setup call.
Properties:
Name | Type | Description |
---|---|---|
referenceId | string | The reference ID to identify the traveler’s check-out session. Used for logging and tracing. Use a concatenation of your APIKey and Customer-Session-ID using an underscore. Example: [APIKey]_[SessionID] |
Class: SetupResponse
Response from the setup call.
Properties:
Name | Type | Description |
---|---|---|
version | string | The version of this library. This is the same version present in the URL path to the library. |
encodedBrowserMetadata | string | An encoded object containing the collected browser details. The client should treat this as opaque data to be passed to the backend payment services without parsing. |
Class: InitSessionRequest
Request structure for the initSession
method.
Properties:
Name | Type | Description |
---|---|---|
paymentSessionId | string | A unique ID returned by the Rapid Register Payments API. |
encodedInitConfig | string | An encoded list of config objects containing data required for initialization, returned by the Rapid Register Payments API. |
Class: InitSessionResponse
Response structure for the initSession
method.
Properties:
Name | Type | Description |
---|---|---|
statusCode | string | Status of the initSession call. |
message | string | Optional. Indicates the failure reason. |
Possible values for statusCode
:
Value | Description |
---|---|
SUCCESS | Initialization completed successfully. |
SKIPPED | No initialization was done. |
FAILED | Initialization failed. The message field contains additional information regarding the failure. |
TIMEOUT | Initialization was not completed within the available time. Timeout duration is 10 seconds. |
Note: For all initSessionresponse
statusCode
values, proceed with Rapid Book API.
Class: ChallengeRequest
Request structure for the challenge method.
Properties:
statusCode value | Test encoded_Challenge_config value | Description |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | Without user iframe interaction |
SUCCESS / FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | Without user iframe interaction |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | Without user iframe interaction |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
Possible values for statusCode
Value | Description |
---|---|
SUCCESS | 3DS challenge was completed successfully. |
SKIPPED | External application error. |
FAILED | 3DS challenge was not completed successfully due to card holder’s inability to correctly respond to the authentication challenge. |
TIMEOUT | Challenge was not completed in the available time. Timeout duration is 1200 seconds. |
Note: For all challengeResponse
statusCode
values, proceed with Rapid for complete payment session.
Testing with Rapid and two-factor authentication
Your integration with Rapid and the 3DS connector methods can be tested with input parameter values that correspond to specific scenarios supported by the APIs.
Rapid
To test Rapid, include an additional HTTP header named test in the HTTP request and use one of the supported values for that API to test a supported scenario.
Within the PSD2 booking flow, test responses from Rapid can also be used to test the 3DS connector library methods.
Register payments
The following test header values result in different encoded_init_config
values in the API response and different HTTP response codes. The encoded_init_config
can be passed in to the initSession
call of the JavaScript library to trigger different test cases within the 3DS connector library.
Test header value | HTTP code & response | initSession test case |
---|---|---|
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 |
Note: init_skip
different test cases within the 3DS Connector Library.t_config
that can be passed to initSession
and force a statusCode
of SKIPPED.
Create booking
In addition to the test headers defined in Rapid Booking Test Requests for the non-PSD2 booking flow, additional test header values are supported for the PSD2 workflow.
The test header values result in differerent encodedChallengeConfig
values which can be passed in to the challenge
call of the JavaScript library to trigger different test cases.
Test header value | HTTP code & response | initSession test case |
---|---|---|
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 |
Complete payment session
The test header values result in differerent error cases that can occur when trying to complete a payment and confirm a booking.
Test header value | HTTP code & response |
---|---|
payment_declined | 400 - Payment declined response |
price_mismatch | 409 - Price mismatch response |
rooms_unavailable | 410 - Rooms unavailable response |
3DS connector library and iframe
To test the 3DS connector without external dependencies, specific parameter values correspond to supported method responses. This behaviour is only supported when the iframe is loaded with the test sandbox URL.
Initialize session
The supported values of the InitSessionResponse statusCode
can be tested by varying the initSessionRequest encodedInitConfig
.
statusCode value | Test encodedInitConfig value |
---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJTVUNDRVNTIn1d |
FAILED | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJGQUlMRUQifV0= |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDAsICJz YW5kYm94SW5pdE91dHB1dENvbmZpZyI6ICJUSU1FT1VUIn1d |
SKIPPED | Not supported at this time. |
Note: The encoded_init_config
values can also be generated with the supported test headers of the Register Payments API.
Challenge
The supported values of the challengeResponse statusCode
can be tested by varying the challengeRequest encondedChallengeConfig
.
statusCode value | Test encoded_Challenge_config value | Description |
---|---|---|
SUCCESS | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNVQ0NFU1MifV0 | Without user iframe interaction |
SUCCESS / FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlNIT1cifV0 | Without user iframe interaction |
FAILED | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIkZBSUxFRCJ9XQ | Without user iframe interaction |
TIMEOUT | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmd lT3V0cHV0Q29uZmlnIjogIlRJTUVPVVQifV0 | |
ERROR | W3sicHJvdmlkZXJJZCI6IDA sICJzYW5kYm94Q2hhbGxlbmdlT3V0cHV0Q29uZmlnIjogIkVSUk9SIn1d |
Note: The encodedInitConfig
values can also be generated with the supported test headers for the PSD2 flow of the Booking API.
Note: When testing for challenge status code value of SUCCESS or FAILED based on user input with the iframe, the challenge method response will wait on the completion of the simulated authentication UI in the iframe.
Example of UI in 3DS iframe:
Example usage
The sample below shows an example implementation meant for guidance only. The sample demonstrates how to use the pre-defined parameter values to test the library for a 3DS challenge without the user needing to interact with the 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
});
Two-factor authentication and property collect
About two-factor authentication for property collect
When booking with property collect Expedia does not charge the card, we simply send it to the property for handling. The property may use this information to validate the card ahead of check-in. At check-in, the traveler is expected to pay in person.
However, sometimes travelers cannot check in and properties may charge a no-show fee. These charges can be impacted by PSD2 regulations because they involve charging a card when the traveler is not present.
If transactions are impacted, payments can fail or properties can face penalties from card brands if the charge is non-compliant.
To protect our relationship with properties and continue to serve our partners, Expedia Group is offering properties an optional path to compliance. Impacted properties can now leverage Expedia Group to provide 2FA on their behalf. This allows properties to protect their business and ensures that Rapid can continue to offer the same diverse range properties.
Rapid provides the flag of <payment_registration_recommended=true>
in the Property Content File and in Property Content, which can help you to identify a property when it is potentially involved in the project.
Note: Only properties within the European Economic Area, or EEA, are eligible for 2FA and the set of properties that may require 2FA is not static – it can grow as additional properties choose to enable this capability.
How can 2FA for property collect impact an integration?
If a partner wants to offer properties that can require 2FA, then the booking path should support 2FA. Without supporting 2FA, booking these properties may fail if the card-issuing bank determines 2FA is needed for the transaction, e.g. cards issued in the EEA.
When a no-show fee is charged by the property, Rapid will be the merchant of record. The charge’s descriptor on the card’s billing statement will not be defined by the property. The value of the descriptor is defined by the partner. To customize this text, contact Rapid Partner Support.
To remain compliant the requirements of card brands and the Rapid launch process, use the Accepted Payments API to display the processing_country
on the check-out page in case of no-show. This is required for all transactions where Rapid is the merchant of record and this may occur if 2FA is used and a no-show occurs.
How can impact to an integration be mitigated
If a Rapid integration does not support 2FA in the booking flow, the risk of failed bookings can be reduced by not selling these properties.
Contact Rapid Partner Support to have these impacted property collect rates removed from Availability API responses.
When using an agent tool, the transaction is exempted from 2FA in accordance with the regulations. Use the Availability API’s sales_channel
field to indicate this.
Error handling
The Create Booking API and Complete Payment Session API may result in confirmed bookings and payment transactions.
Your integration should consider the following instructions to avoid financial loss and customer operation cases:
Source | Function | Suggested timeout setup | Error recovery process | Actions needed |
---|---|---|---|---|
Rapid API | Pre-Book Price Check for Register Payment Token | 10 seconds | Retry or select another property, room or rate | - |
JavaScript | 3DS Connector Setup | 10 seconds | Retry the same request | - |
Rapid API | Register Payment Session | 10 seconds | Retry the same request without "Expect: 100-Continue" process | - |
JavaScript | Initiate Payment Session | 10 seconds | Retry the same request | - |
Rapid API | Create Booking | 90 seconds | Retry the same request | For all errors: Retrieve Booking with affiliate_reference_id |
JavaScript | Display 2FA Challenge | 10 seconds | Retry the same request | - |
JavaScript | Wait for challenge.statusCode | 180 ~ 1200 seconds | Request Complete Payment Session | - |
Rapid API | Complete Payment Session | 90 seconds | Retry the same request | For all errors: Retrieve Booking withaffiliate_reference_id |
Rapid API | For all errors: Retrieve Booking withaffiliate_reference_id | 30 seconds | Retry the same request | For all errors: Wait 90 seconds before retrying, to confirm the final status of bookings by API Response Code 404 or 200 |