Data Plan Agent API

目的

概要で説明したように、オペレーターがサポートするユースケースに応じて、DPA は Google Mobile Data Plan Sharing API と Data Plan Agent API の組み合わせを実装する必要があります。このドキュメントでは、Google がユーザーのモバイル データプランを特定し、プランに関する情報を取得して、データプランを購入するために使用する Data Plan Agent API について説明します。

認証

GTAF が呼び出す前に、DPA は GTAF を認証する必要があります。オペレーターのオンボーディング プロセスの一環として、DPA SSL 証明書の有効性を確認します。現在、相互認証には OAuth2 の使用が必須となっています。

API の説明

GTAF は、通信事業者の DPA をクエリする際に、通信事業者の加入者を識別するユーザーキーを使用します。GTAF が MSISDN にアクセスできるアプリに代わって DPA にクエリを実行する場合、GTAF は MSISDN を使用しても構いません。大まかに表現すると、提案された Data Plan Agent API は次のコンポーネントで構成されています。

  1. ユーザーのデータプランのステータスをクエリするメカニズム。
  2. ユーザーのデータプランの提案について DPA にクエリを行うメカニズム。
  3. ユーザーのデータプランを変更するメカニズム(新しいプランの購入など)。
  4. ユーザーが特定のデータプランを購入できるかどうかを確認するメカニズム。
  5. GTAF が MSISDN を DPA に登録するメカニズム。
  6. GTAF が DPA の健全性を確認するためのメカニズム。

このドキュメントの残りの部分では、これらの API コンポーネントについて詳しく説明します。明示的に記載されていない限り、すべての通信は HTTPS 経由で行われなければなりません(有効な DPA SSL 証明書を使用)。サポートされる実際の機能に応じて、オペレーターはこれらの API コンポーネントのすべてまたはサブセットを実装することを選択できます。

データプランのステータスのクエリ

GTAF-DPA のインタラクション

GTAF-DPA のインタラクション

図 4. ユーザーのデータプラン情報をリクエストして受け取るためのコールフロー。

図 4 は、ユーザーのデータプランのステータスやその他のデータプラン情報についてクライアントが問い合わせる際のコールフローを示しています。この呼び出しフローは、UE のクライアントによってトリガーされた API 呼び出しで共有されます。

  1. クライアントは、非公開の Google API を呼び出して、データプランのステータスやその他の情報をリクエストします。クライアントは、GTAF へのリクエストにユーザーキーを含めます。
  2. GTAF は、ユーザーキーとクライアント識別子を使用して、事業者の DPA をクエリします。サポートされているクライアント ID は mobiledataplanyoutube です。DPA は、これらのクライアント ID のいずれかを含む呼び出しを受信した場合、クライアントが使用できるプラン情報を返さなければなりません。
  3. GTAF はリクエストされた情報をクライアントに返し、DPA で指定された有効期限までプラン情報をキャッシュに保存します。

図 4 のステップ 1 と 3 は非公開の Google API であるため、これ以上の説明は省略します。ステップ 2 は、後述する公開 API です。DPA は、GTAF からこれらの API 呼び出しを処理する際に、Cache-Control: no-cache HTTP ヘッダーを尊重しなければなりません。

プランのステータス

GTAF は、プランのステータスを取得するために次の HTTP リクエストを発行します。

GET DPA_URL/{userKey}/planStatus?key_type={CPID,MSISDN}&client_id=CLIENT_ID

GTAF が DPA に連絡するクライアントは、CLIENT_ID を使用して識別されます。Google クライアントと携帯通信会社間の契約に応じて、DPA は GTAF へのレスポンスをカスタマイズできます。レスポンスの形式は、PlanStatus を表す JSON オブジェクトです。

{
  "plans": [{
    "planName": "ACME1",
    "planId": "1",
    "planCategory": "PREPAID",
    "expirationTime": "2017-01-29T01:00:03.14159Z", // req.
    "planModules": [{
      "moduleName": "Giga Plan", // req.
      "trafficCategories": ["GENERIC"],
      "expirationTime": "2017-01-29T01:00:03.14159Z", // req.
      "overUsagePolicy": "BLOCKED",
      "maxRateKbps": "1500",
      "description": "1GB for a month", // req.
      "coarseBalanceLevel": "HIGH_QUOTA"
    }]
  }],
  "languageCode": "en-US", // req.
  "expireTime": "2018-06-14T08:41:27-07:00", // req.
  "updateTime": "2018-06-07T07:41:22-07:00", // req.
  "title": "Prepaid Plan"
  "planInfoPerClient": {
    "youtube": {
      "rateLimitedStreaming": {
        "maxMediaRateKbps": 256
      }
    }
  }
}

リクエストには、人が読める文字列(プランの説明など)の言語を示す Accept-Language ヘッダーを含めなければなりません。

後払いプランの場合、expirationTime はプランの定期購入日(データ残高が更新/再読み込みされる日)でなければなりません。

各プラン モジュールには複数のプラン モジュール トラフィック カテゴリを含めることができます(PMTCs)。複数のアプリでプラン モジュールが共有されるケースをモデル化するため(例: ゲームと音楽の場合は 500 MB)。次の PMTC は事前定義されています。GENERIC, VIDEO, VIDEO_BROWSING, VIDEO_OFFLINE, MUSIC, GAMING, SOCIAL and MESSAGING. オペレーターは、個々の Google チームに連絡して、さまざまな Google アプリケーションに関連するトラフィック カテゴリのセットとそのセマンティクスについて合意することが想定されています。

プランの提案をクエリする

GTAF は、次の HTTP リクエストを発行して、携帯通信会社からプランの提案を取得します。

GET DPA_URL/{userKey}/planOffer?key_type={CPID,MSISDN}&client_id=CLIENT_ID&context={purchaseContext}

GTAF が DPA に連絡するクライアントは、CLIENT_ID を使用して識別されます。Google クライアントと携帯通信会社間の契約に応じて、DPA は GTAF へのレスポンスをカスタマイズできます。省略可能なコンテキスト パラメータは、リクエストが作成されるアプリのコンテキストを提供します。通常、これはアプリケーションが GTAF を介してオペレーターに渡す文字列です。

レスポンスの本文には PlanOffer のインスタンスが含まれます。

{
    "offers": [
      {
        "planName": "ACME Red", // req.
        "planId": "turbulent1", // req.
        "planDescription": "Unlimited Videos for 30 days.", // req.
        "promoMessage": "Binge watch videos.",
        "languageCode": "en_US", // req.
        "overusagePolicy": "BLOCKED",
        "cost": { // req.
          "currencyCode": "INR",
          "units": "300",
          "nanos": 0
        },
        "duration": "2592000s",
        "offerContext": "YouTube",
        "trafficCategories": ["VIDEO"],
        "quotaBytes": "9223372036850"
      }
    ],
    "expireTime": "2019-03-04T00:06:07Z" // req.
}

offers 配列内のデータプランの順序によって、ユーザーにデータプランが表示される順序が決まることがあります。また、UI などの制限により、アプリが x プランのみを表示でき、レスポンスに y > x プランのみが含まれている場合、最初の x プランのみを表示しなければなりません。オファーをクエリするアプリが Google Play 開発者サービスの一部であるモバイル データプラン UI の場合、GTAF は最大 10 個のプランのみを共有します。これは、Google Play 開発者サービスのユーザーに優れたユーザー エクスペリエンスを提供するためです。

offerInfo の文字列は、ユーザーが特典の詳細を確認できるようにするためのもので、アプリ内から特典の受信をオプトアウトする方法も含まれています。これらのフィールドがあるのは、アプリ内購入を許可するためにエンドユーザーの同意を必要とせず、ユーザーがオプトアウトするためのメカニズムを必要とするオペレーターもいるためです。なお、オペレーターは、ユーザーに提供されたすべての特典の購入リクエストを処理するメカニズムを備えていなければなりません。購入の際にユーザーに請求されるメカニズムは、レスポンスの formOfPayment オプションを使用して GTAF に伝えることができます。

リクエストには、人が読める文字列(プランの説明など)の言語を示す Accept-Language ヘッダーを含めなければなりません。

データ購入

購入プラン API は、GTAF が DPA を介してプランを購入する方法を定義します。GTAF は、DPA に 1 つのデータプランを購入するトランザクションを開始します。リクエストには、リクエストをトレースし、トランザクションの重複実行を回避するための一意のトランザクション識別子(transactionId)を含めなければなりません。DPA は成功/失敗のレスポンスを返さなければなりません。

Transaction Request

クライアントからリクエストを受信すると、GTAF は DPA に POST リクエストを発行します。リクエストの URL は次のとおりです。

POST DPA_URL/{userKey}/purchasePlan?key_type={CPID,MSISDN}&client_id=CLIENT_ID

ここで、userKeyCPID または MSISDN です。リクエストの本文は TransactionRequest のインスタンスです。これには次のフィールドが含まれます。

{
  "planId": string,         // Id of plan to be purchased. Copied from
                            // offers.planId field returned from a
                            // Upsell Offer request,
                            // if available. (req.).
  "transactionId": string,  // Unique request identifier (req.)
  "offerContext": string,   // Copied from from the
                            // offers.offerContext, if available.
                            // (opt.)
  "callbackUrl": string     // URL that the DPA can call back with response once
                            // it has handled the request.
}

Transaction Response

DPA は、エラーが発生した場合、一般的なエラーの原因を返さなければなりません。また、次のエラーコードはトランザクションの失敗を表します。

  • DPA は、購入したプラン ID が無効であることを GTAF に示す 400 BAD REQUEST エラーコードを返します。
  • DPA は 402 PAYMENT REQUIRED エラーコードを返し、GTAF にユーザーの残高が購入を完了するのに十分でないことを示します。
  • DPA は 409 CONFLICT エラーコードを返し、購入するプランがユーザーの現在のプロダクト ミックスと互換性がないことを GTAF に示します。たとえば、携帯通信会社のデータプラン ポリシーで後払いプランと前払いプランの組み合わせが禁止されている場合、後払いユーザーが前払いプランを購入しようとすると、409 CONFLICT エラーが発生します。
  • DPA は 403 FORBIDDEN エラーコードを返し、現在の取引が以前に発行された取引の重複であることを GTAF に示します。DPA は、レスポンスで次のエラー原因を返す必要があります。
    • 前のトランザクションが失敗した場合、失敗の理由を示すエラー原因。
    • 前のトランザクションが成功した場合は、DUPLICATE_TRANSACTION。
    • 前のトランザクションがまだキューにある場合は、REQUEST_QUEUED。

DPA は、正常に実行された取引またはキューに登録された取引に対してのみ 200-OK レスポンスを生成しなければなりません。キューに登録されたトランザクションの場合、DPA はトランザクション ステータスのみを入力し、レスポンスの他のフィールドは空のままにします。キューに登録されたトランザクションが処理されたら、DPA はレスポンスとともに GTAF を呼び戻さなければなりません。レスポンスの本文は TransactionResponse のインスタンスで、次の詳細が含まれます。

{
  "transactionStatus": "SUCCESS",

  "purchase": {
    "planId": string,               // copied from request. (req.)
    "transactionId": string,        // copied from request. (req.)
    "transactionMessage": string,   // status message. (opt.)
    "confirmationCode": string,     // DPA-generated confirmation code
                                    // for successful transaction. (opt.)
    "planActivationTime" : string,  // Time when plan will be activated,
                                    // in timestamp format. (opt.)
  },

  // walletInfo is populated with the balance left in the user's account.
  "walletBalance": {
    "currencyCode": string,       // 3-letter currency code defined in ISO 4217.
    "units": string,              // Whole units of the currency amount.
    "nanos": number               // Number of nano units of the amount.
  }
}

planActivationTime がない場合、GTAF はプランが有効になっていると見なします。

GTAF は、ユーザーの同意設定を携帯通信会社に渡すために、次のリクエストを発行しても構いません。

POST DPA_URL/{userKey}/consent?key_type={CPID,MSISDN}&client_id=CLIENT_ID

ここで、userKeyCPID または MSISDN です。リクエストの本文は SetConsentStatusRequest のインスタンスです。

成功すると、レスポンスの本文は空になります。

利用資格

GTAF は、ユーザーがプランを購入できるかどうかを確認するために、次の利用資格リクエストを発行する場合があります。

GET DPA/{userKey}/Eligibility/{planId}?key_type={CPID,MSISDN}

planId は、ユーザーに代わってプランを購入するために使用できるプランの一意の識別子です(データ購入を参照)。planId が指定されていない場合、DPA はそのユーザーが購入可能なすべてのプランを返さなければなりません。

DPA は、エラーが発生した場合、一般的なエラーの原因を返さなければなりません。また、DPA は次のエラーの場合にエラーを返さなければなりません。

  • DPA は、planId が無効であることを GTAF に示す 400 BAD REQUEST エラーコードを返します。
  • DPA は、planId がユーザーのデータプランと互換性がないことを示す 409 CONFLICT エラーコードを返します。

それ以外の場合、DPA は 200-OK レスポンスを返さなければなりません。成功した EligibilityResponse の形式は次のとおりです。

{
  "eligiblePlans":
  [
   {
    "planId": string,   // Plan identifier. Can be used to
                        // refer to the plan during
                        // offers, etc. (req.)
   }
  ]
}

リクエストに planId が含まれている場合、レスポンスにはそのプランのみが含まれます。それ以外の場合、リストにはユーザーが購入できるすべてのプランが含まれます。planId が空で、DPA が対象プランのリストの返却をサポートしていない場合、400 BAD REQUEST エラーを返さなければなりません。

MSISDN 登録エンドポイント

MSISDN にアクセスできるアプリを配信するために、GTAF は DPA に MSISDN を登録します。GTAF は、Google Mobile Data Plan Sharing API によって提供されるアプリケーションがある場合にのみ MSISDN を登録します。この場合、DPA は Google API を使用して GTAF に情報を送信します。MSISDN を登録するために、GTAF は DPA に POST リクエストを行います。

POST DPA_URL/register

リクエストの本文は RegistrationRequest のインスタンスになります。

{
  "msisdn": "<msisdn_string>"
}

MSISDN の登録が成功した場合、DPA は RegistrationResponse を含む 200 OK レスポンスを返さなければなりません。JSON の形式は次のとおりです。

{
  // msisdn that was registered.
  "msisdn": "<msisdn_string>",
  // time after which DPA will not send updates to GTAF.
  "expirationTime": string
}

その後、DPA は expirationTime が経過するまで、ユーザーのデータプランに関する更新を GTAF に送信すべきです。

エラーが発生した場合は、ErrorResponse が返されます。

{
    "error": "<error message>",
    "cause": enum(ErrorCause)
}

さまざまなエラー条件に対する 原因の値と HTTP ステータス コードの完全なリストは、こちらで確認できます。特に、ローミング中のユーザー、または Google とのデータプラン情報の共有をオプトアウトしたユーザーに対して MSISDN 登録リクエストが受信された場合、DPA は HTTP ステータス コード 403 を返さなければなりません。

Monitoring API

ユースケースによっては、GTAF が DPA をモニタリングし、DPA の障害を検出する必要があります。これらのユースケースについては、モニタリング API を定義しています。

API 定義

モニタリング API は、次の URL で HTTP GET リクエストを介して利用できる必要があります。

DPA_URL/dpaStatus

DPA とそのすべてのバックエンドが正しく動作している場合、DPA はこのクエリに対して HTTP ステータス コード 200 と DpaStatus のインスタンスを含むレスポンス本文で応答します。

{
    "status": enum(DpaStatusEnum),
    "message": "<optional human-readable status description>"
}

DPA またはそのバックエンドのいずれかが正しく動作していない場合、HTTP ステータス コード 500 と DpaStatus のインスタンスを含むレスポンス本文で応答する必要があります。

DPA の動作

障害が検出された場合、DPA はすべての dpaStatus クエリに対して「UNAVAILABLE」ステータスを返す必要があります。また、キャッシュ期間が長いデータプラン情報の送信を停止する必要があります。キャッシュ期間が長いレスポンスの送信を停止する方法は 2 つあります。

  1. 短いキャッシュ有効期限の設定を開始します。
  2. データプラン情報の送信を完全に停止します。

GTAF の動作

GTAF は dpaStatus を定期的にポーリングします。DPA の障害を検出すると(「UNAVAILABLE」レスポンスに基づく)、オペレーターのキャッシュをクリアします。

エラーとなるケース

エラーが発生した場合、DPA は次のいずれかに対応する HTTP ステータス コードを返すことが想定されています。

  • ユーザーは現在ローミング中で、このユーザーに対して DPA クエリが無効になっています。DPA が 403 エラーを返します。
  • DPA は、ユーザーキーが無効(存在しないユーザーキー)であることを GTAF に示す 404 NOT_FOUND エラーコードを返します。
  • DPA は 410 GONE エラーコードを返し、key_type = CPID で CPID の有効期限が切れている場合、クライアントは新しいユーザーキーを取得する必要があることを GTAF に示します。
  • DPA は、この呼び出しをサポートしていないことを示す 501 NOT_IMPLEMENTED エラーコードを返します。
  • サービスを一時的に利用できません。DPA は、新しいリクエストを試行できるタイミングを示す Retry-After ヘッダーとともに 503 SERVICE UNAVAILABLE を返します。
  • DPA は、その他の指定されていないエラーに対して 500 INTERNAL SERVER ERROR エラーコードを返します。
  • DPA は、GTAF が DPA に過剰なリクエストを行っていることを示す Retry-After ヘッダーとともに 429 TOO_MANY_REQUESTS エラーを返します。
  • DPA は、DPA の現在の状態との競合によりリクエストを完了できないことを示す 409 CONFLICT エラーを返します。

すべてのエラーケースで、HTTP レスポンスの本文にはエラーに関する詳細情報を含む JSON オブジェクトを含めなければなりません。エラー レスポンスの本文には、ErrorResponse のインスタンスが含まれていなければなりません。

{
  "error": string,
  "cause": enum(ErrorCause)
}

現在定義されている cause 値は、ErrorCause API リファレンスの一部としてリストされています。

それ以外の場合、DPA は 200 OK を返します。これらの cause 値はすべてのレスポンスで使用されます。

国際化

DPA への GTAF リクエストには、人が読める文字列(プランの説明など)の言語を示す Accept-Language ヘッダーが含まれます。また、DPA レスポンス(PlanStatus、PlanOffers)には、値が BCP-47 言語コード(例: "en-US")。

DPA がユーザーのリクエストした言語をサポートしていない場合は、デフォルトの言語を使用し、languageCode フィールドを使用して選択した言語を示すことができます。