SCA 구현
SCA-compliant 예약을 생성하려면 Rapid API
Rapid API 를 공식 결제 대행사로 활용하든, 여행객이 도착 시 결제하도록 허용하든 상관없이 Rapid의 API 솔루션을 도입하여 SCA 규정을 준수하는 예약을 생성할 수 있습니다. 당사의 API는 예약 절차에서 3D-Secure(3DS) 2.0을 사용하여 SCA 준수를 지원합니다. 3DS 2.0을 통해 당사는 ‘ risk-based ’ 인증 방식을 지원하며, 이를 통해 은행이 여행자에게 안전한 인증을 요청할 시점을 재량에 따라 결정할 수 있게 함으로써 여행자의 불편을 줄여줍니다.
3DS 2.0을 위한 해결책은 다음 세 가지 단계로 구성됩니다:
여행객을 위한 발급 은행의 인증 절차를 호스팅하는 데 사용되는 check-out 페이지에 iframe을 추가하게 됩니다. 통합 문서에서는 이를 3DS iframe이라고 부릅니다.
>> iframe에 대해 자세히 알아보기또한 check-out 페이지에 새로운 client-side JavaScript 라이브러리를 포함시켜야 합니다. 이 라이브러리는 브라우저 데이터를 수집하고, iframe과 통신하며, iframe 내에서 SCA 환경을 표시하는 데 사용됩니다. 통합 설명서에서는 이를 ‘3DS 커넥터 라이브러리’라고 부릅니다.
Rapid API 은행의 납부자 정보를 수락하고, 보안 인증이 완료된 후 예약을 마무리합니다.
JavaScript 와 Rapid API 를 함께 사용할 경우, SCA가 적용된 예약 흐름에서는 이제 예약 API가 호출되기 전후로 몇 가지 추가 단계가 포함됩니다. 아래의 다이어그램은 업데이트된 예약 흐름입니다.

변경된 예약 흐름의 각 단계에서는 한 단계의 출력 정보가 다음 단계의 입력 데이터로 사용됩니다. 데이터가 브라우저의 JavaScript와 Rapid 간에 전달되어야 합니다.
통합 구성 요소 세부 정보
SCA 구현은 브라우저 기반 check-out 환경에서 시작되며, 이후 Rapid API 프로세스로 이어집니다.
브라우저
check-out 환경에 배치된 iframe은 사용자에게 표시되는 인증 절차를 호스팅하며, traveler-supplied 정보를 사용자의 은행으로 직접 전송합니다. 해당 콘텐츠는 여행자의 card-issuing 은행이 소유한 URL에서 제공됩니다. iframe은 처음에는 숨겨져 있어야 하며, 예약 시도가 이루어진 후 인증 절차가 필요할 때 이를 페이지 위에 중첩하여 표시할 수 있어야 합니다.
JavaScript 라이브러리
이 라이브러리는 ‘ check-out ’ 페이지에 추가되며, 인증 절차를 지원하기 위해 예약 시 호출됩니다. 이 라이브러리의 API는 아래에 설명된 기능을 지원합니다.
여행자 기기 정보
예약 시도를 하기 전에, 인증을 위한 예약 절차를 준비하기 위해 여행자의 기기에 대한 정보를 수집해야 합니다. 해당 정보는 여행자의 은행으로 전송되어 위험을 평가하고, 해당 거래에 3DS 2.0 인증이 필요한지 여부를 결정하며, 인증 화면이 올바르게 표시되도록 보장합니다. 3DS 2.0 사양에 따라, 여행자의 브라우저에서 언어, 색상 심도, 화면 높이, 화면 너비, 시간대, 사용자 에이전트 및 Java 활성화 여부 등의 데이터가 수집됩니다.
인증 화면
예약 시도가 완료된 후, 이 라이브러리를 사용하여 iframe 오버레이를 표시하고 은행의 콘텐츠를 해당 오버레이에 불러옵니다. 인증 과정에서 은행 측은 위험 평가를 뒷받침하기 위해 여행자의 기기에 대한 추가 정보를 수집할 수 있습니다. 이 절차는 예약을 완료하기 위해 필수적입니다.
Rapid API
Rapid API client-side # 라이브러리 와 연동되는 API를 포함합니다.JavaScript API는 아래에 설명된 기능을 지원합니다.
여행자 및 결제 정보
예약 시도를 하기 전에, Rapid API 은 인증 절차를 준비하기 위해 여행자에 대한 추가 정보를 수집해야 하며, 여기에는 판매처 및 결제 수단과 같은 여행자 관련 정보가 포함됩니다. 이 데이터는 이후 여행자의 은행으로 전송되어 위험도를 평가하고, 해당 거래에 보안 인증이 필요한지 여부를 결정합니다. Rapid Booking API의 일부인 Register Payment API를 살펴보시면 더 자세한 내용을 확인하실 수 있습니다.
결제 및 예약 확인
예약 시도를 한 후, 브라우저에서 SCA 프로세스가 완료되면 Rapid API 을 한 번 더 호출해야 합니다. 배경에서 인증이 성공적으로 완료되었는지 확인하여 예약이 확정될 수 있도록 하겠습니다. Rapid Booking API의 ‘결제 완료’ 섹션을 확인하여 자세한 내용을 알아보세요.
예약 흐름
다음은 여행자가 예약을 시작한 후 필요한 API 호출 순서를 보여주는 다이어그램입니다. 이 시퀀스에는 JavaScript 라이브러리에 대한 호출과 Rapid API.

예약이 인증을 위해 준비될 때, 인증이 항상 필요한 것은 아닙니다. 인증 필요 여부는 결제에 사용된 신용카드의 발급 은행에 따라 결정됩니다. 이러한 결정은 트랜잭션 진행 중에 이루어지며, ‘Create Booking’ API 응답에 표시됩니다.
Rapid Lodging API는 예약 보류 및 재개 기능도 제공합니다. 해당 기능에 필요한 API 호출 순서는 다음과 같습니다.

>> 숙박 API의 ‘보류’ 및 ‘재개’ 기능 알아보기
3DS 2.0 서비스 이용에 필요한 기술적 요구 사항에 대한 자세한 내용은 EMVCo의 3D Secure 프로토콜 및 핵심 기능 사양서를 참조하십시오.
3DS 2.0 통합 가이드
SCA를 지원하려면 Rapid API 를 ‘3DS 커넥터’라고 불리는 새로운 JavaScript 라이브러리와 통합해야 합니다. 이 두 가지는 ‘ check-out ’ 페이지에서 3DS 2.0을 표시하고 예약을 확정하는 데 함께 사용됩니다. 이 솔루션은 익스피디아의 ‘수령 후 결제’ 및 ‘후불’ 비즈니스 모델을 모두 지원합니다.
참고: 수정된 예약 절차를 적용하려면 Rapid Partner Support에서 개별 파트너 프로필에 대해 ‘ ’ 3DS 2.0 기능을 활성화해야 합니다.
1단계: 가용성 API 호출
규정에서 허용하는 경우 인증 면제를 받으려면 API 요청의 ‘ sales_channel ’ 필드 값이 정확해야 합니다. 이 수치는 다른 여러 요인과 함께 카드 발급 은행에서 예약 시 결정을 내리는 과정에서 검토됩니다. SCA의 적용에서 제외되는 것은 에이전트 도구뿐입니다. 이를 지정하려면 sales_channel 값을 agent_tool로 설정해 주세요.
JavaScript 라이브러리는 예약 절차의 나머지 단계들을 위한 선행 단계입니다. JavaScript API를 사용하여 결제 세션을 초기화한 다음, 다음을 통해 예약을 진행합니다. Rapid API.
>> JavaScript 라이브러리를 초기화하는 방법을 알아보세요
2단계: 가격 조회 또는 상세 정보 API 호출
Lodging API의 경우, SCA에 대한 Price Check API 응답에는 Register Payments API로 연결되는 링크가 포함됩니다.
Lodging API에 대한 3DS 2.0 응답 예시
{
"status": "matched",
"occupancies": {
//...(example omitted for length)
},
"links": {
"payment_session": {
"method": "POST",
"href": "/v3/payment-sessions?token=QldfCGlcUAVgBDRwdWXBBL"
}
}
}SCA 흐름에 대한 Car 및 Activities API의 Details 엔드포인트 응답은 해당 API의 non-SCA 흐름의 응답과 동일합니다.
3단계: Register Payments API 호출
Lodging API의 경우, 이 호출을 반드시 수행해야 합니다. Car 및 Activities API는 이 호출을 Details 또는 Create Booking API에 통합합니다. 이 요청에는 non-SCA 예약 절차의 일부인 결제 정보와, 인증을 성공적으로 수행할 수 있도록 지원하는 새로운 필드가 포함됩니다. 이 필드 중 두 개, 즉 encoded_browser_metadata 와 version``는 JavaScript API의 setup 메서드에서 반환됩니다.
응답에는 payment_session_id 및 encoded_init_config가 포함됩니다. 이는 JavaScript 라이브러리의 initSession 메서드에 입력으로 지정됩니다. 응답에 포함된 예약 링크는 initSession 메서드 실행 후에 사용해야 합니다.
Lodging API 요청 예시
{
"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": "2027-02-12T11:59:00.000Z",
"create_date": "2027-09-15",
"change_date": "2027-09-17",
"password_change_date": "2027-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": "2027",
"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": "2027-09-15"
}
]
}Lodging API 응답 예시
{
"payment_session_id": "76d6aaea-c1d5-11e8-a355-529269fb1459",
"encoded_init_config": "QSBiYXNlNjQgZW5jb2RlZCBvYmplY3Qgd2hpY2ggY29udGFpbnMgY29uZmlndXJhdGlvbiBuZWVkZWQgdG8gcGVyZm9ybSBkZXZpY2UgZmluZ2VycHJpbnRpbmcgYW5kL29yIDNEUyBNZXRob2Qu",
"links": {
"book": {
"method": "POST",
"href": "/v3/itineraries?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
}
}자동차 또는 활동 API 요청 예시
{
"type": "customer_card",
"number": "4111111111111111",
"security_code": "123",
"expiration_month": "08",
"expiration_year": "2028",
"billing_contact": {
"given_name": "John",
"family_name": "Smith",
"email": "smith@example.com",
"phone": {
"country_code": "1",
"area_code": "487",
"number": "5550077"
},
"address": {
"line_1": "555 1st St",
"city": "Seattle",
"state_province_code": "WA",
"postal_code": "98121",
"country_code": "US"
}
},
"strong_customer_authentication": {
"rapid": {
"version": "2.0.1",
"browser_accept_header": "*/*",
"encoded_browser_metadata": "ZW5jb2RlZF9icm93c2VyX21ldGFkYXRh",
"preferred_challenge_window_size": "medium",
"merchant_url": "https://server.adomainname.net",
"enrollment_date": "2024-05-08",
"customer_account_details": {
"authentication_method": "guest",
"authentication_timestamp": "2026-02-12T11:59:00.000Z",
"create_date": "2025-09-15",
"change_date": "2025-09-17",
"password_change_date": "2025-09-17",
"add_card_attempts": 1,
"account_purchases": 1
}
}
}
}자동차 또는 활동 API 응답 예시
{
"payment_token": "K~IjM455rG_zUnz9LlKCw8bbLfxqk2Kb...",
"expires": "2026-01-30T16:32:10.557287774Z",
"payment_session_id": "ern:pay:pa:sec::5bcca93d-cdae-00b7-2cd4-d72d84cb2665",
"encoded_init_config": "W3sicHJvdmlkZXJJZCI6IjEiLCJwYXlt..."
}4단계: 예약 생성 API 호출
이 요청에는 SCA를 위한 새로운 필드가 포함되지 않습니다. 필요한 모든 정보는 예약 링크의 토큰에 포함되어 있습니다. Lodging API의 경우, 이 정보는 Register Payment API 응답에서 확인할 수 있으며, Car 또는 Activities API의 경우 Details 엔드포인트에서 확인할 수 있습니다. 성공 시 응답에는 항상 itinerary_id가 포함됩니다. 그러나 3DS 2.0 인증이 필요할 수 있으므로, 이것만으로는 예약이 확정된 것으로 볼 수 없습니다.
필요한 경우, 응답에는 또한 .이 포함됩니다 encoded_challenge_config. Register Payment API에서 반환된 encoded_challenge_config 및 payment_session_id 는 JavaScript 챌린지 메서드의 매개변수로 전달되어야 합니다.
또한 이 답변에는 complete_payment_session (숙박 또는 활동) 또는 resume_after_payment_challenge (자동차)로 연결되는 새로운 링크도 포함될 예정입니다. 이 링크는 JavaScript 라이브러리의 challenge 메서드 실행 후에 사용해야 합니다.
3DS 2.0 인증이 필요하지 않은 경우, 예약이 확정되며 응답에는 retrieve, cancel 및 (Lodging API 요청의 경우) 링크가 포함됩니다 resume.
Lodging API 응답 예시
{
"itinerary_id": "8999989898988",
"links": {
"complete_payment_session": {
"method": "PUT",
"href": "/v3/itineraries/8999989898988/payment-sessions?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
},
"encoded_challenge_config": "ABElifsiejfacies2@033asfe="
}활동 API 요청 예시
{
"email": "traveler@example.com",
"payment_token": "K~xxxxxxxxxxxxxxxxxxxx",
"affiliate_reference_id": "AFF-REF-12345",
"primary_traveler": {
"name": {
"given_name": "Jane",
"family_name": "Doe"
},
"phone": {
"country_code": "1",
"number": "5551234567"
},
"ticket_id": "182552"
}
}챌린지가 포함된 예시 활동 API 응답
{
"itinerary_id": "9045006342737",
"encoded_challenge_config": "<opaque challenge config from issuing bank>",
"links": {
"complete_payment_session": {
"method": "PUT",
"href": "/v2/itineraries/9045006342737/activity/payment-sessions?token=<token>"
}
}
}5단계: 예약 완료하기
예약 절차 중 이 단계는 JavaScript 챌린지 메서드 실행 후에 진행됩니다. 결제를 완료하고, 성공 여부와 관계없이 보안 인증 시도가 이루어졌음을 Rapid API 에 알리기 위해서는 ‘전체 결제 세션 API(숙박 및 액티비티)’ 또는 ‘결제 후 재개 챌린지 API(자동차)’의 응답이 필요합니다.
이번 요청에는 SCA와 관련된 새로운 필드가 포함되지 않을 것입니다.
응답이 성공하면, 예약 확인 정보가 포함되며, 여기에는 예약 확인 번호( itinerary_id)와 retrieve, cancel, 그리고 (Lodging API 요청의 경우) 링크가 포함됩니다 resume.
Lodging API 응답 예시
{
"itinerary_id": "8999989898988",
"links": {
"retrieve": {
"method": "GET",
"href": "/v3/itineraries/8999989898988?token=MY5S3j36cOcLfLBZjPYQ1abhfc8CqmjmFVzkk7euvWaunE57LLeDgaxm516m"
}
}
}활동 예시 API 응답
{
"itinerary_id": "9045006342737",
"links": {
"retrieve": {
"method": "GET",
"href": "/v2/itineraries/9045006342737/activity"
}
}
}Iframe 및 JavaScript 라이브러리 구현
SCA 예약 워크플로를 사용할 때는 ‘ check-out ’ 페이지에 새로운 iframe과 JavaScript 라이브러리를 포함해야 합니다. ‘3DS iframe’이라고 불리는 이 iframe은 3D-Secure 2.0을 사용하여 인증 절차를 표시합니다. ‘3DS 커넥터 라이브러리’라고 불리는 JavaScript 라이브러리는 발급 은행으로의 정보 전송을 지원하고, 은행의 콘텐츠를 iframe에 불러옵니다.
Iframe 추가하기
3DS iframe은 처음에는 숨겨져 있다가 결제를 처리하기 위해 인증 요청이 필요할 때 표시될 수 있는 컨테이너에 있어야 합니다.
컨테이너 디자인은 호스팅 페이지에 맞게 사용자 설정할 수 있습니다. 아래는 부트스트랩 모달을 사용하여 안내용으로 제작된 구현 예시입니다.
<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의 소스는 다음 두 값 중 하나로 설정되어야 합니다.
| URL 유형 | URL | 참고 |
|---|---|---|
| 프로덕션 | https://static.pay.expedia.com/3ds/threeDsIframe.html | 생산 인증을 지원합니다 |
| 샌드박스 테스트 | https://static.pay.expedia.com/3ds/sandboxThreeDsIframe.html | 인증 테스트를 지원합니다 |
이 테스트 URL은 테스트를 지원합니다. 다음 명령어를 사용하면 테스트 중에 iframe의 콘텐츠를 샌드박스 내에서만 제한할 수 있습니다:
sandbox = 'allow-scripts allow-forms allow-same-origin';JavaScript 라이브러리 추가하기
3DS Connector 라이브러리는 3DS iframe과 통신하고 iframe 콘텐츠를 제공하는 발급 은행에 데이터를 전송합니다. 아래는 결제 페이지에 라이브러리를 추가하는 방법의 예입니다.
<head>
<script src="<<3DS connector script URL>>" integrity="<<actual integrity value>>"></script>
</head>Script 요소의 source 및 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 | |
| 2.0.1 | src | https://static.pay.expedia.com/3ds/2.0.1/pay-3ds-js-libs-connector.min.js |
| integrity | sha384-1ntftSOl8ZSqJ/m7qqxXTNGOx3JLbF7Uw5YX8i/ageTjgmTnUMZ3ROpxxMiUkYma |
참고: 향후 새 버전이 출시되면 소스 URL 및 무결성 값이 변경될 수 있습니다. 최신 버전이 기존 통합을 중단해서는 안 됩니다. 이전 버전의 스크립트에는 계속 액세스할 수 있습니다.
SCA를 위해 3DS와 JavaScript 활용하기
3DS 커넥터 라이브러리를 사용하려면 JavaScript 프로미스를 사용해야 합니다. 아래 예제는 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 | Mastercard Identity Check | 마스터카드 브랜드 가이드라인 |
| Visa | Visa Secure | Visa 브랜드 가이드라인 |
참고: 다른 카드 브랜드의 로고 및 안내 사항은 정보가 확보되는 대로 순차적으로 추가될 예정입니다.