Data Plan Agent API

動機

總覽中所述,視運算子想要支援的用途而定,DPA 必須實作 Google Mobile Data Plan Shared API 與 Data Plan Agent API 的組合。本文件說明 Google 將用於識別使用者的行動數據方案、Data Plan Agent API,以及購買方案的相關資訊。

驗證

DPA 必須先驗證 GTAF,才能呼叫 GTAF。在運算子新手上路流程中,我們會檢查 DPA SSL 憑證的有效性。目前「必須」使用 OAuth2 進行共同驗證。

API 說明

GTAF 使用使用者金鑰來識別運算子和訂閱者的 DPA。當 GTAF 代表可存取 MSISDN 的應用程式查詢 DPA 時,GTAF MAY 可能會使用 MSISDN。大致上,提議的 Data Plan Agent API 包含下列元件:

  1. 查詢使用者資料方案狀態的機制。
  2. 向使用者查詢數據方案優惠的 DPA 機制。
  3. 變更使用者數據方案的機制 (例如購買新方案)。
  4. 確認使用者是否符合購買特定數據方案的機制。
  5. GTAF 註冊機制,向 DPA 註冊 MSISDN。
  6. GTAF 的機制,以驗證 DPA 是否處於良好的狀態。

本文件的其餘部分會逐一介紹這些 API 元件。除非另有說明,否則所有通訊都「必須」透過 HTTPS (使用有效的 DPA SSL 憑證) 進行。視實際支援的功能而定,運算子可能會選擇實作所有或部分 API 元件。

查詢數據方案狀態

GTAF-DPA 互動

GTAF-DPA 互動

圖 4. 用於要求及接收使用者資料方案資訊的呼叫流程。

圖 4 說明與查詢使用者數據狀態和其他數據方案資訊的用戶端相關的呼叫流程。這個呼叫流程由用戶端在 UE 上觸發的 API 呼叫共用。

  1. 用戶端會呼叫私人 Google API,要求數據方案狀態和/或其他資訊。用戶端會在向 GTAF 發出的要求中納入使用者金鑰
  2. GTAF 會使用使用者金鑰和用戶端 ID 查詢運算子的 DPA。支援的用戶端 ID 為 mobiledataplanyoutube。當 DPA 收到包含其中一個用戶端 ID 的呼叫時,「必須」回應用戶端可使用的方案資訊。
  3. GTAF 將要求的資訊傳回用戶端,而 GTAF 會擷取方案資訊,直到 DPA 指定的到期時間為止。

圖 4 中的步驟 1 和 3 是私人 Google API,因此不會詳細說明。步驟 2 是下文所述的公用 API。從 GTAF 提供這些 API 呼叫時,DPA 「必須」遵循 Cache-Control: no-cache HTTP 標頭。

企劃書狀態

GTAF 會發出下列 HTTP 要求來取得方案狀態:

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

使用 CLIENT_ID 來識別 GTAF 代表與 DPA 聯絡的用戶端。視 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
      }
    }
  }
}

要求 SHALL 應包含 Accept-Language 標頭,指出使用者可讀取的字串 (例如方案說明) 應使用的語言。

如果是後付方案,expirationTime 必須是方案的重複日期 (也就是在資料重新整理/重新載入時)。

每個方案模組都包含多個企劃書模組流量類別 (PMTCs) 用於建立在多個應用程式之間共用方案模組的案例,例如遊戲和音樂的大小上限為 500 MB)。以下 PMTC 預先定義:GENERIC, VIDEO, VIDEO_BROWSING, VIDEO_OFFLINE, MUSIC, GAMING, SOCIAL and MESSAGING.

查詢計畫優惠

GTAF 會發出下列 HTTP 要求,取得業者提供的方案優惠:

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

使用 CLIENT_ID 來識別 GTAF 代表與 DPA 聯絡的用戶端。視 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 選項,向使用者收取任何購買交易的機制。

要求 SHALL 應包含 Accept-Language 標頭,指出使用者可讀取的字串 (例如方案說明) 應使用的語言。

資料購買

購買方案 API 定義 GTAF 如何透過 DPA 購買方案。GTAF 會啟動交易,向 DPA 購買一項數據方案。要求應內含專屬交易 ID (transactionId),用於追蹤要求並避免重複執行交易。DPA 「必須」傳回成功/失敗回應。

交易要求

收到客戶提出的要求後,GTAF 會向 DPA 發出 POST 要求。 要求的網址如下:

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

其中 userKeyCPIDMSISDN。要求主體是 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.
}

交易回應

如果發生錯誤,DPA 應傳回常見的錯誤原因。此外,下列錯誤代碼代表失敗的交易結果:

  • DPA 會傳回 400 BAD REQUEST 錯誤代碼,告知 GTAF 所購買方案的 ID 無效。
  • DPA 會傳回 402 PAYMENT REQUIRED 錯誤代碼,指出 GTAF 的使用者沒有足夠餘額完成購買交易。
  • DPA 傳回 409 CONFLICT 錯誤代碼,向 GTAF 指出要購買的方案與使用者目前的產品組合不相容。舉例來說,如果電信業者數據方案政策禁止混合使用後付方案和預付方案,嘗試為後付使用者購買預付方案會導致 409 CONFLICT 錯誤。
  • DPA 會傳回 403 FORBIDDEN 錯誤代碼,表示 GTAF 目前的交易與先前核發的交易重複。DPA 應在回應中傳回下列錯誤原因:
    • 如果先前的交易失敗,系統會指示錯誤原因。
    • 如果先前的交易成功,DUPLICATE_TRANSACTION
    • 如果先前的交易仍在佇列中,REQUEST_QUEUED,

DPA SHALL 只會為成功執行的交易或排入佇列的交易產生 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 SHALL 會假設方案已啟用。

GTAF 可以提出下列要求,將使用者的同意聲明偏好設定傳遞至電信業者。

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

其中 userKeyCPIDMSISDN。要求的主體是 SetConsentStatusRequest 的執行個體。

如果成功,回應主體必須為空白。

資格條件

GTAF 可以發出下列資格要求,藉此確認使用者是否符合購買方案的資格。

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

請注意,planId 是方案的專屬 ID,可用於代表使用者購買方案 (請參閱資料購買)。如未指定 planId,DPA 「必須」傳回使用者可購買的所有方案。

如果發生錯誤,DPA 應傳回常見的錯誤原因。此外,DPA 應在發生下列錯誤時傳回錯誤:

  • DPA 向 GTAF 傳回 400 BAD REQUEST 錯誤代碼,指出 planId 無效。
  • DPA 傳回 409 CONFLICT 錯誤代碼,指出 planId 與使用者的數據方案不相容。

否則,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。只有在應用程式由 Google Mobile Data Plan Shared API 提供時,GTAF 才會註冊 MSISDN,其中 DPA 會使用 Google API 將資訊傳送至 GTAF。如要註冊 MSISDN,GTAF 將向 DPA 發出 POST 要求:

POST DPA_URL/註冊

要求的主體會是 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 應將使用者的使用者資料方案更新傳送至 GTAF,直到 expirationTime 過期為止。

如果發生錯誤,應傳回 ErrorResponse

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

如需不同錯誤條件的可能原因值和 HTTP 狀態碼完整清單,請參閱這篇文章。請特別注意,如果使用者收到漫遊服務,或是尚未與 Google 分享數據方案資訊,而已接收 MSISDN 註冊要求,DPA 「必須」傳回 HTTP 狀態碼 403。

Monitoring API

某些用途會需要 GTAF 來監控 DPA 並偵測 DPA 失敗。針對這些用途,我們已定義一個監控 API。

API 定義

您應透過下列網址,透過 HTTP GET 要求存取 Monitoring API:

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」的狀態。另外,它必須停止透過較長的快取時間傳送數據方案資訊。您可能會無法透過下列其中一種方式停止傳送長時間快取回應:

  1. 開始設定較短的快取到期時間。
  2. 停止全部傳送數據方案資訊。

GTAF 行為

GTAF 會定期輪詢 dpaStatus,當系統偵測到 DPA 失敗 (根據「UNAVAILABLE」」回應) 時,就會清除運算子的快取。

錯誤案例

如果發生錯誤,DPA 應會傳回與下列任一項目對應的 HTTP 狀態碼:

  • 使用者目前正在漫遊,且已停用這位使用者的 DPA 查詢。DPA 會傳回 403 錯誤。
  • DPA 會傳回 404 NOT_FOUND 錯誤代碼,向 GTAF 指出使用者金鑰無效 (即不存在的 user key)。
  • 如果 key_type = CPID 且 CPID 已過期,DPA 會傳回 410 GONE 錯誤代碼,向 GTAF 指出用戶端應取得新的使用者金鑰
  • DPA 傳回 501 NOT_IMPLEMENTED 錯誤代碼,表示不支援這個呼叫。
  • 暫時無法使用服務,DPA 會傳回 503 SERVICE UNAVAILABLE ,以及「Try-after」標頭,指出何時可以嘗試新要求。
  • DPA 會針對所有其他未指定的錯誤,傳回 500 內部錯誤錯誤錯誤代碼。
  • DPA 傳回 429 TOO_ %}_REQUESTS 錯誤,使用 Try-after 標頭,指出 GTAF 向 DPA 發出太多要求。
  • DPA 傳回 409 CONFLICT 錯誤,表示要求與 DPA 目前的狀態發生衝突而無法完成。

在所有錯誤情況中,HTTP 回應的主體「必須」包含關於錯誤的詳細資訊。錯誤回應主體「必須」包含 ErrorResponse 的執行個體。

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

目前定義的 cause 值會列在 ErrorCause API 參考資料中。

否則,DPA 會傳回 200 OK。但請注意,所有 cause 值都用於所有回應。

國際化

向 DPA 提出的 GTAF 要求包含 Accept-Language 標頭,指出人類可讀字串 (例如方案說明) 應使用的語言。此外,DPA 回應 (PlanStatus、PlanOffers) 含有必要的 languageCode 欄位,其值是 BCP-47 語言代碼 (例如「en-US」)。

如果 DPA 不支援使用者要求的語言,則可以使用預設語言,並使用 languageCode 欄位表示選擇語言。