APIの設定
このセクションでは、当社のAPIとの連携を成功させるために必要な手順について解説します。Webhookを介してプッシュイベントを受信する場合でも、当社のエンドポイントからデータをプルする場合でも、どちらにも対応しております。
- プッシュAPI: TAAPおよびホワイトラベル旅行プラットフォームのパートナー様に最適なプッシュイベントにより、real-timeの最新情報を貴社のシステムに直接配信いたし ます。サブスクリプションの設定方法、認証の管理方法、およびリトライの処理方法について学びましょう。
- Pull API: ホワイトラベル旅行プラットフォームのパートナー向けに設計されており、必要な時にデータをリクエストすることができます。安全なアクセスを実現するためのtoken-based認証の設定方法についてご説明いたします。
円滑な統合と安全なデータ転送を確保するため、以下のガイダンスに従ってください。
Push-based配送
TAAPまたはホワイトラベル旅行プラットフォームのパートナーで、旅程データに関心をお持ちの方には、本情報が役立つかもしれません。プッシュイベントはWebhookを介して配信され、ご指定いただいたURL宛てにHTTP POST メッセージとして送信されます。
イベントの受信を開始するには、イベントタイプを購読し、送信元としてエクスペディアを認証する必要があります。
定期購読とイベント
当社のサブスクリプションAPIをご利用いただくと、push-based配信サービスを通じて受信したいイベントを作成・管理することができます。現在、旅程の更新イベントに関するサブスクリプションを作成・管理することができます。今後、利用可能になり次第、さらに追加していく予定です。
APIクライアントIDとシークレットが必要となりますが、これらは担当の営業担当者からご提供いただけます。
サブスクリプションAPIへのアクセス
すべてのAPIリクエストには、御社専用のアクセストークンを含めてください。APIの認証情報を使用して、HTTP基本認証の仕組みを通じてこのトークンをリクエストしてください。
- APIクライアントIDとシークレットをBase64エンコードした文字列を、Authorizationヘッダーとしてトークンエンドポイントに追加してください
https://analytics.ean.com/*/v1/oauth/token。URL内の「*」を、ご契約内容に応じて「template」または「taap」のいずれかに置き換えてください。 - トークンエンドポイントからは、その後のAPIリクエストで使用するアクセストークンが返されます。
- 今後の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}定期購読の管理
Subscription APIでの認証が完了すると、既存のサブスクリプションの一覧表示、新規サブスクリプションの作成、不要になったサブスクリプションの削除など、サブスクリプションの管理を行うことができます。
サブスクリプションの作成
サブスクリプションを作成する際には、以下の項目を指定する必要があります:
- イベントを受信したいエンドポイントのURLです。
- 購読したいイベントの種類と、パートナーシップの区分(
taap.itinerary.changeまたはtemplate.itinerary.change)をご指定ください。
注:複数のサブスクリプションを作成することは可能ですが、重複したサブスクリプションを作成すると、イベントの配信が重複してしまいます。これを避けるため、新しいサブスクリプションを作成する前に、既存のサブスクリプションを一覧にまとめておきましょう。
サブスクリプションが作成されると、イベント配信に添付されるHMAC(hash-basedメッセージ認証コード)を検証するための一意のシークレットキーが発行されます。
サブスクリプションの一覧表示や削除を行うには、それぞれHTTP GET /subscriptions またはHTTP DELETE /subscriptions/{subscription_id} のエンドポイントをご利用ください。有効なトークンを使用する必要があります。
エクスペディアを送信元として認証する
ご指定いただいたエンドポイントにプッシュイベントを送信いたします。各イベントには、認証ヘッダーにhash-basedメッセージ認証コード(HMAC)による署名が含まれます。サブスクリプションの作成時に当社から提供される共有秘密鍵を使用して、安全かつ信頼性の高いデータ転送を確保するため、この署名を検証してください。
Authorizationヘッダーの例
"authorization": "MAC ts='1731524372777',nonce='f88e57ed-aaf5-4edd-8e58-9105817fb4cb',bodyhash='8YLHy71r5dx3PQjdcOkRuVYXaakjhbJSROEnlreQEIA=',mac='bDxvx41INtDxtkbZwTmAMADZGiFl6/xyXC1lE5ixPuY='"プッシュイベントを受信するエンドポイントに、以下のロジックを追加して、HMAC署名を検証してください。これにより、お客様が受け取るイベント情報がエクスペディアからのものであり、送信中に改ざんされていないことが保証されます。
注: この例では、この検証ロジックをJavaで実装する方法を示しています。このロジックは、お好みのプログラミング言語に合わせて調整できますが、基本的な手順は変わりません。
手順1:認証ヘッダーを解析する
文字列を構成要素ごと に解析し、認証ヘッダーから必要な情報を抽出します。
コードサンプル
/**
* Parse the signature string into components
* @param signature The signature string in format "MAC ts='...', nonce='...', bodyhash='...', mac='...'"
* @return Map of signature components
*/
private Map<String, String> parseSignature(String signature) {
// Pattern for key='value' or key="value"
Pattern pattern = Pattern.compile("([a-zA-Z]+)=['\"]([^'\"]*)['\"]");
Matcher matcher = pattern.matcher(signature);
Map<String, String> components = new HashMap<>();
while (matcher.find()) {
components.put(matcher.group(1), matcher.group(2));
}
return components;
}ステップ2:必要なコンポーネントの検証
必要なコンポーネントであるts (タイムスタンプ)、nonce、bodyhash、およびmac が存在し、正しい形式になっていることを確認してください。
コードサンプル
private Boolean validateSignatureComponents(Map<String, String> components) {
if (components.isEmpty()) {
return false;
}
return components.containsKey("ts") &&
components.containsKey("nonce") &&
components.containsKey("bodyhash") &&
components.containsKey("mac");
}ステップ3:本文のハッシュを生成し、検証する
HMAC SHA-256およびsharedSecretKey を使用してボディのハッシュを生成し、リクエストボディのハッシュと一致することを確認して、データの整合性を確保してください。
コードサンプル
/**
* Compute body hash (HMAC-SHA256 of the request body)
* @param body The raw request body
* @return Base64 encoded body hash
*/
private String computeBodyHash(String body) {
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(body.getBytes(StandardCharsets.UTF_8));
return bytesToBase64(hmacBytes);
} catch (Exception e) {
throw new RuntimeException("Failed to compute body hash", e);
}
}
private Boolean validateBodyHash(String requestBody, String bodyHashFromHeader) {
String computedBodyHash = computeBodyHash(requestBody != null ? requestBody : "");
return computedBodyHash.equals(components.get('bodyhash'));
}ステップ4:HMAC署名の生成と検証
タイムスタンプ、ノンセ、HTTPメソッド、リクエストパス、ホストドメイン、ポート、および生成されたボディハッシュを含めたHMAC署名を生成し、ヘッダーで受信した値と照合して検証を行い、真正性を確認してください。
コードサンプル
/**
* Generate HMAC signature using the provided components
* @param components Parsed signature components
* @param computedBodyHash Computed body hash
* @param method HTTP method (e.g., "POST", "GET")
* @param path Request path (e.g., "/api/webhooks/events")
* @param host Host name (e.g., "api.example.com")
* @param port Port number
* @return Base64 encoded HMAC signature
*/
private String generateHmacSignature(Map<String, String> components, String computedBodyHash,
String method, String path, String host, int port) {
try {
// Normalize port (use 443 for standard HTTPS ports)
String portString = (port == 80 || port == 443) ? DEFAULT_PORT : String.valueOf(port);
// Build signature string with newline-delimited components
String signatureString = String.format("%s\n%s\n%s\n%s\n%s\n%s\n%s\n",
components.get("ts"),
components.get("nonce"),
method.toUpperCase(),
path,
host,
portString,
computedBodyHash);
return calculateHMAC(signatureString);
} catch (Exception e) {
throw new RuntimeException("Failed to generate HMAC signature", e);
}
}
/**
* Calculate HMAC-SHA256
* @param data Data to hash
* @return Base64 encoded HMAC
*/
private String calculateHMAC(String data) {
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(data.getBytes(StandardCharsets.UTF_8));
return bytesToBase64(hmacBytes);
} catch (Exception e) {
throw new RuntimeException("Failed to calculate HMAC", e);
}
}
private Boolean validateHmacSignature(Map<String, String> components, String computedBodyHash,
String method, String path, String host, int port) {
String generatedHmacSignature = generateHmacSignature(components, computedBodyHash, method, path, host, port);
return generatedHmacSignature.equals(components.get("mac"));
}イベントの失敗に対する再試行
イベントが失敗した場合、システムは7日間にわたり指数関数的なバックオフパターンに従って再試行を行います。最初は5分間隔、次に60分間隔、その後は12時間ごとに再試行を行います。以下の理由による失敗については、再試行を行います:
- 200以外のHTTPステータスコード
- タイムアウト
- エンドポイントからの例外
サブスクリプションAPIの詳細
Subscriptions APIの詳細については、OpenAPI仕様書をダウンロードしてください。
Pull-based配送
ホワイトラベルの旅行プラットフォームサイトをお持ちの場合は、ご利用中のAPIに応じて、旅程およびロイヤルティのEarnデータについて、pull-basedによる配信を実装することができます。
ロイヤルティ の「Earn」および「Itineraries」エンドポイントにアクセスするには、APIクライアントIDおよびシークレットが必要となります。これらは、担当の営業担当者から入手できます。すべてのAPIリクエストには、御社専用のアクセストークンを含めてください。APIの認証情報を使用して、HTTP基本認証の仕組みを通じてこのトークンをリクエストしてください。
- APIクライアントIDとシークレットをBase64エンコードした文字列を、Authorizationヘッダーとして、トークンエンドポイント
https://analytics.ean.com/template/v1/oauth/tokenに追加してください。 - トークンエンドポイントからは、その後のAPIリクエストで使用するアクセストークンが返されます。詳細については、OpenAPI仕様書をご参照ください。
- 今後の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}トークンを受け取ったら、ロイヤルティ の「Earn」または「Itineraries」エンドポイントのいずれに対してもリクエストを送信できるようになります。
本サービスをご利用の際は、APIのバージョンを指定していただく必要があります。ダウンロード可能なOpenAPI仕様ファイルの上部に記載されている「servers.url」の値をご使用ください。これは、常にテスト対象のAPIサービスのバージョン番号と一致します。
URLは以下の形式に従う必要があります:
https://analytics.ean.com/[product]/[API version]/[path]
パスを変更することでエンドポイントを切り替えることができますが、OpenAPI仕様書に記載されている通り、プロトコル、ドメイン指定、製品名、およびAPIバージョン番号は必ずそのままにしてください。
エンドポイントの例
https://analytics.ean.com/template/v1/loyalty/earn/last_update
https://analytics.ean.com/template/v1/itinerariesデータの範囲やAPIの設定について確認するには、API配信用のスキーマをご参照ください:
>> 旅程APIの提供に関する詳細はこちら
>> ロイヤルティ について詳しく知るAPI配信で収益を得る