This is an auto-generated translation

API 설정

이 섹션에서는 API와 성공적으로 통합하기 위한 필수 단계를 설명합니다. 웹훅을 통해 푸시 이벤트를 수신하든, 엔드포인트에서 데이터를 가져와서 수신하든, 저희가 도와드릴 수 있습니다.

  • 푸시 API: TAAP 및 화이트 라벨 템플릿 파트너에게 적합한 푸시 이벤트는 near-real-time 업데이트를 시스템에 직접 전달합니다. 구독을 설정하고, 인증을 관리하고, 재시도를 처리하는 방법을 알아보세요.
  • 풀 API: 화이트 라벨 템플릿 파트너를 위해 설계된 이 API를 사용하면 필요할 때 데이터를 요청할 수 있습니다. 보안 액세스를 위해 token-based 인증을 설정하는 방법을 설명해 드리겠습니다.

원활한 통합과 안전한 데이터 전송을 위해 아래 지침을 따르세요.

Push-based 배달

TAAP 또는 화이트 라벨 템플릿 파트너로서 일정 데이터에 관심이 있는 경우 관련 정보가 도움이 될 수 있습니다. 푸시 이벤트는 웹훅을 통해 전달되며 사용자가 제공한 URL로 HTTP POST메시지로 전송됩니다.

이벤트 수신을 시작하려면 이벤트 유형에 가입하고 발신자로 익스피디아를 인증해야 합니다.

구독 및 이벤트

구독 API를 사용하면 push-based 배달 서비스를 통해 수신하려는 이벤트를 생성하고 관리할 수 있습니다. 현재 일정 업데이트 이벤트에 대한 구독을 생성하고 관리할 수 있으며, 사용 가능한 이벤트가 추가되는 대로 더 추가할 예정입니다.

상업 담당자가 제공할 수 있는 API 클라이언트 ID와 비밀번호가 필요합니다.

구독 API에 액세스하기

모든 API 요청에 비즈니스에 고유한 액세스 토큰을 포함하게 됩니다. HTTP 기본 인증 메커니즘을 통해 API 자격 증명을 사용하여 이 토큰을 요청하세요.

  1. 토큰 엔드포인트에 API 클라이언트 ID와 비밀번호의 Base64로 인코딩된 문자열이 포함된 권한 부여 헤더를 추가합니다 https://analytics.ean.com/*/v1/oauth/token. 파트너십에 따라 URL의 *template또는 taap으로 바꿉니다.
  2. 토큰 엔드포인트는 후속 API 요청에 사용할 액세스 토큰을 반환합니다. 자세한 내용은 구독 API 세부 정보 를 참조하세요.
  3. 향후 API 엔드포인트 요청에 액세스 토큰 값을 포함하세요.

초기 권한 부여 헤더 예시

Authorization: Basic base64.b64encode({client-id}:{client-secret})

토큰 요청 예시

securitySchemes:
  oauth:
    type: oauth2
    flows:
      clientCredentials:
        tokenUrl: https://analytics.ean.com/taap/v1/oauth/token

인증된 권한 부여 헤더 예시

Authorization: Bearer {access-token}

구독 관리하기

정기구독 API로 인증한 후에는 기존 정기구독 목록을 만들고, 새 정기구독을 만들고, 더 이상 적용되지 않는 정기구독을 삭제하는 등 정기구독을 관리할 수 있습니다.

구독 만들기

구독을 만들 때 지정해야 할 사항이 있습니다:

  • 이벤트를 수신할 엔드포인트 URL입니다.
  • 구독하려는 이벤트 유형(파트너십 표시 포함): taap.itinerary.change또는 template.itinerary.change.

참고: 여러 개의 구독을 만들 수 있지만, 중복 구독은 중복 이벤트 전달을 초래합니다. 이를 방지하려면 새 구독을 만들기 전에 기존 구독을 나열하세요.

구독이 생성되면 이벤트 전송에 포함된 HMAC(hash-based 메시지 인증 코드)의 유효성을 검사할 수 있는 고유한 비밀 키를 받게 됩니다.

Information

중요

비밀 키를 받으면 보안상의 이유로 다시 표시되지 않으므로 반드시 보안 파일에 저장하세요.

구독을 나열하거나 삭제하려면 각각 HTTP GET /subscriptions또는 HTTP DELETE /subscriptions/{subscription_id}엔드포인트를 사용하세요. 유효한 토큰을 사용해야 합니다.

자세한 내용은 구독 API 세부 정보 를 참조하세요.

발신자로 Expedia 인증하기

제공한 엔드포인트에 푸시 이벤트를 보내드리며, 각 이벤트에는 권한 부여 헤더에 HMAC 서명이 포함됩니다. 안전하고 신뢰할 수 있는 데이터 전송을 위해 제공될 공유 비밀번호를 사용하여 이 서명의 유효성을 검사해야 합니다.

권한 부여 헤더 예시

"authorization": "MAC ts='1731524372777',nonce='f88e57ed-aaf5-4edd-8e58-9105817fb4cb',bodyhash='8YLHy71r5dx3PQjdcOkRuVYXaakjhbJSROEnlreQEIA=',mac='bDxvx41INtDxtkbZwTmAMADZGiFl6/xyXC1lE5ixPuY='"

1단계: 유효성 검사 구성

푸시 API 엔드포인트에 이러한 HMAC 구성 설정을 추가하세요:

hmac.validator.sharedSecretKey={mySecretKey}
hmac.validator.endpoint=https:{//example.com}
hmac.validator.methodType=POST

2단계: 유효성 검사 모듈 추가

이 공개 클래스 코드를 엔드포인트에 추가하여 HMAC 서명의 유효성을 검사합니다:

@Component
public class HmacValidator {
    private static final String HMAC_SHA256 = "HmacSHA256";
    private static final String DEFAULT_PORT = "443";
    private final String sharedSecretKey;
    private final String endpoint;
    private final String methodType;

    // Constructor for initialization
    public HmacValidator(@Value("${hmac.validator.sharedSecretKey}") String sharedSecretKey,
                         @Value("${hmac.validator.endpoint}") String endpoint,
                         @Value("${hmac.validator.methodType:POST}") String methodType) {
        this.sharedSecretKey = sharedSecretKey;
        this.endpoint = endpoint;
        this.methodType = methodType; // Default to POST if not provided
    }

    public boolean validate(String signature) {
        //Validation logic here
    }
}

3단계: 유효성 검사 로직 구현하기

서명 유효성 검사 로직은 다음 단계를 따라야 합니다:

  1. 권한 헤더를 구문 분석하여 구성 요소를 추출합니다.
  2. 추출한 구성 요소와 sharedSecretKey를 사용하여 HMAC 서명을 생성합니다.
  3. 생성된 서명을 권한 부여 헤더의 서명과 비교합니다.

코드 샘플

// Validate the signature
    public boolean validate(String signature) {
        Map<String, String> components = parseSignature(signature);
        if (components == null || components.isEmpty()) {
            return false; // Invalid format or empty signature
        }

        String generatedHmacSignature = generateHmacSignature(components);
        System.out.println("Generated HMAC Signature: " + generatedHmacSignature);
        System.out.println("Received HMAC Signature: " + components.get("mac"));
        return generatedHmacSignature.equals(components.get("mac"));
    }

    // Parse the signature into its components
    private Map<String, String> parseSignature(String signature) {
        // Define the pattern for each key-value pair in the format "key='value'"
        Pattern pattern = Pattern.compile("([a-zA-Z]+)='([^']*)'");
        Matcher matcher = pattern.matcher(signature);

        // Store results in a map
        Map<String, String> components = new HashMap<>();

        // Extract each key-value pair
        while (matcher.find()) {
            components.put(matcher.group(1), matcher.group(2));
        }
        return components;
    }

    // Generate the HMAC signature using components
    public String generateHmacSignature(Map<String, String> components) {
        try {
            URL url = new URL(endpoint);
            String signature = String.format("%s/n%s/n%s/n%s/n%s/n%s/n%s/n",
                    components.get("ts"),
                    components.get("nonce"),
                    methodType.toUpperCase(),
                    url.getPath(),
                    url.getHost(),
                    url.getPort() == -1 ? DEFAULT_PORT : String.valueOf(url.getPort()),
                    components.get("bodyhash"));

            return calculateHMAC(signature);
        } catch (Exception e) {
            throw new RuntimeException("Failed to generate HMAC signature", e);
        }
    }

    // Calculate the HMAC from the signature string
    private String calculateHMAC(String signature) {
        try {
            Mac mac = Mac.getInstance(HMAC_SHA256);
            SecretKeySpec secretKeySpec = new SecretKeySpec(sharedSecretKey.getBytes(StandardCharsets.UTF_8), HMAC_SHA256);
            mac.init(secretKeySpec);
            byte[] hmacBytes = mac.doFinal(signature.getBytes(StandardCharsets.UTF_8));
            return bytesToBase64(hmacBytes);
        } catch (Exception e) {
            throw new RuntimeException("Failed to calculate HMAC", e);
        }
    }

    // Convert byte array to Base64 string
    private String bytesToBase64(byte[] bytes) {
        return Base64.getEncoder().encodeToString(bytes);
    }
}

이벤트 실패 재시도

이벤트가 실패하면 시스템은 7일 동안 기하급수적인 백오프 패턴을 사용하여 처음 5분, 60분, 그 후 12시간마다 재시도합니다. 다음과 같은 이유로 실패한 경우 다시 시도합니다:

  • 200이 아닌 HTTP 상태 코드
  • 시간 초과
  • 엔드포인트의 예외

구독 API 세부 정보

구독 API에 대한 자세한 내용을 보려면 OpenAPI 사양을 다운로드하세요.




Pull-based 배달

화이트 라벨 템플릿 사이트가 있는 경우, 사용 중인 API에 따라 일정 및 로열티 적립 데이터에 대해 pull-based 전달을 구현할 수 있습니다.

로열티 적립 및 일정 엔드포인트에 액세스하려면 API 클라이언트 ID와 비밀번호가 필요하며, 이는 담당 영업 담당자에게 문의하여 얻을 수 있습니다. 모든 API 요청에 비즈니스에 고유한 액세스 토큰을 포함하게 됩니다. HTTP 기본 인증 메커니즘을 통해 API 자격 증명을 사용하여 이 토큰을 요청하세요.

  1. 토큰 엔드포인트 https://analytics.ean.com/template/v1/oauth/token에 API 클라이언트 ID와 비밀번호의 Base64로 인코딩된 문자열이 포함된 권한 부여 헤더를 추가합니다.
  2. 토큰 엔드포인트는 후속 API 요청에 사용할 액세스 토큰을 반환합니다. 자세한 내용은 OpenAPI 사양을 참조하세요.
  3. 향후 API 엔드포인트 요청에 액세스 토큰 값을 포함하세요.

초기 권한 부여 헤더 예시

Authorization: Basic base64.b64encode({client-id}:{client-secret})

토큰 요청 예시

securitySchemes:
    oauth:
      type: oauth2
      flows:
        clientCredentials:
          tokenUrl: https://analytics.ean.com/template/v1/oauth/token

인증된 권한 부여 헤더 예시

Authorization: Bearer {token}

토큰을 받으면 로열티 적립 또는 일정 엔드포인트 중 하나에 요청을 시작할 수 있습니다.

Information

중요

모든 파트너에게 안정적이고 유지보수 가능한 서비스를 제공하기 위해 모든 API 호출에 요금 제한 을 적용합니다. 저희 시스템은 비정상적인 API 트래픽을 모니터링하고 시스템 보호를 위한 조치를 자동으로 취합니다. API 호출을 변경하거나 API 액세스 권한으로 성능 테스트를 수행하기 전에 익스피디아 커머셜 담당자와 요금제를 검토하세요.

서비스를 요청할 때 API 버전을 지정해야 합니다. 다운로드 가능한 OpenAPI 사양 파일 상단에 있는 servers.url값을 사용합니다. 이 번호는 항상 테스트 중인 API 서비스의 버전 번호와 일치합니다.

URL은 이 구조를 따라야 합니다:

https://analytics.ean.com/[product]/[API version]/[path]

경로를 교체하여 엔드포인트 간에 전환할 수 있지만 프로토콜, 도메인 지정, 제품 및 API 버전 번호는 OpenAPI 사양에 명시된 대로 유지해야 합니다.

엔드포인트 예제

https://analytics.ean.com/template/v1/loyalty/earn/last_update
https://analytics.ean.com/template/v1/itineraries

데이터 범위와 API 구성을 살펴보려면 API 제공 스키마를 참조하세요:
일정 API 제공
로열티 적립 API 제공

이 페이지가 도움이 되었나요?
이 콘텐츠를 어떻게 개선하면 좋을까요?
더 나은 Developer Hub를 만드는 데 도움을 주셔서 감사합니다!