動機
如總覽所述,視電信業者想支援的用途而定,DPA 必須實作 Google Mobile Data Plan Sharing API 和 Data Plan Agent API 的組合。本文說明 Google 用來識別使用者行動數據方案、擷取方案資訊及購買數據方案的 Data Plan Agent API。
驗證
GTAF 必須先通過 DPA 驗證,才能呼叫 DPA。在營運商的導入程序中,我們會檢查 DPA SSL 憑證的有效性。我們目前「要求」使用 OAuth2 進行相互驗證。
API 說明
GTAF 查詢電信業者 DPA 時,會使用使用者金鑰來識別電信業者的訂閱者。如果應用程式有權存取 MSISDN,GTAF 代表應用程式查詢 DPA 時「可能」會使用 MSISDN。從高階層面來看,建議的 Data Plan Agent API 包含下列元件:
- 查詢使用者資料方案狀態的機制。
- 查詢 DPA,取得使用者資料方案優惠的機制。
- 變更使用者資料方案的機制 (例如購買新方案)。
- 驗證使用者是否符合購買特定數據方案的資格。
- GTAF 向 DPA 註冊 MSISDN 的機制。
- GTAF 用來驗證 DPA 是否處於健康狀態的機制。
本文件的其他部分會詳細說明這些 API 元件。除非另有明確註記,否則所有通訊都必須透過 HTTPS 進行 (並使用有效的 DPA SSL 憑證)。視實際支援的功能而定,營運商可選擇實作所有或部分 API 元件。
查詢資料方案狀態
GTAF-DPA 互動
圖 4. 要求及接收使用者資料方案資訊的通話流程。
圖 4 說明用戶端查詢使用者資料方案狀態和其他資料方案資訊時的呼叫流程。UE 上用戶端觸發的 API 呼叫會共用這個呼叫流程。
- 用戶端會呼叫私有 Google API,要求取得資料方案狀態和/或其他資訊。用戶端會在傳送至 GTAF 的要求中加入使用者金鑰。
- GTAF 會使用使用者金鑰和用戶端 ID 查詢電信業者的 DPA。支援的用戶端 ID 為 mobiledataplan 和 youtube。 當 DPA 收到含有其中一個用戶端 ID 的呼叫時,必須回覆用戶端可使用的方案資訊。
- 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 代表的客戶會使用 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 代表的客戶會使用 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 服務的一部分,即「行動數據方案使用者介面」,GTAF 只會分享最多 10 個方案。這是為了確保 Google Play 服務使用者享有良好的使用體驗。
offerInfo
中的字串可讓使用者進一步瞭解優惠,並提供在應用程式內選擇不再接收優惠的方式。之所以需要這些欄位,是因為部分電信業者不需要取得使用者同意,即可允許應用程式內購,但需要提供使用者停用機制。請注意,如果向使用者提供任何優惠,營運商就「必須」具備機制來執行購買要求。使用者購買商品時的收費機制,可透過回應中的 formOfPayment 選項傳達給 GTAF。
要求應包含 Accept-Language
標頭,指出清楚易懂的字串 (例如方案說明) 應使用的語言。
購買數據
購買方案 API 定義 GTAF 如何透過 DPA 購買方案。GTAF 會啟動交易,向 DPA 購買一項數據方案。要求「必須」包含專屬交易 ID (transactionId),以追蹤要求並避免重複執行交易。資料保護主管機關「必須」回覆成功/失敗回應。
交易要求
收到用戶端的要求後,GTAF 會向 DPA 發出 POST 要求。要求的網址為:
POST DPA_URL/{userKey}/purchasePlan?key_type={CPID,MSISDN}&client_id=CLIENT_ID
其中 userKey
是 CPID
或 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.
}
交易回應
發生錯誤時,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 才應產生 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
其中 userKey
是 CPID
或 MSISDN
。要求主體是 SetConsentStatusRequest 的執行個體。
如果成功,回應主體應為空白。
資格條件
GTAF 可能會發出下列資格要求,確認使用者是否符合購買方案的資格。
GET DPA/{userKey}/Eligibility/{planId}?key_type={CPID,MSISDN}
請注意,planId
是方案的專屬 ID,可用於代表使用者購買方案 (請參閱「資料購買」)。如未指定 planId
,DPA 必須傳回該使用者可購買的所有方案。
發生錯誤時,DPA 應傳回常見的錯誤原因。 此外,在下列錯誤情況下,DPA 應傳回錯誤:
- DPA 會傳回 400 BAD REQUEST 錯誤代碼,向 GTAF 指出
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 Sharing API 提供應用程式服務時,GTAF 才會註冊 MSISDN,此時 DPA 會使用 Google API 將資訊傳送至 GTAF。如要註冊 MSISDN,GTAF 會向 DPA 發出 POST 要求:
POST DPA_URL/register
要求主體是 RegistrationRequest 的例項。
{
"msisdn": "<msisdn_string>"
}
如果 MSISDN 註冊成功,DPA 必須傳回 200 OK 回應,包括 RegistrationResponse。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 定義
監控 API 應可透過下列網址的 HTTP GET 要求存取:
DPA_URL/dpaStatus
如果 DPA 和所有後端都正常運作,DPA 應會以 HTTP 狀態碼 200 回應這項查詢,並在回應主體中提供 DpaStatus 的例項。
{
"status": enum(DpaStatusEnum),
"message": "<optional human-readable status description>"
}
如果 DPA 或任何後端運作不正常,應傳回 HTTP 狀態碼 500,以及含有 DpaStatus 執行個體的回應主體。
DPA Behavior
偵測到失敗時,DPA 必須針對所有 dpaStatus 查詢傳回「UNAVAILABLE」狀態。此外,如果快取時間較長,也必須停止傳送數據方案資訊。如果快取時間較長,系統可能會停止傳送回應,方法如下:
- 開始設定較短的快取到期時間。
- 完全停止傳送數據方案資訊。
GTAF 行為
GTAF 會定期輪詢 dpaStatus。如果偵測到 DPA 失敗 (根據「UNAVAILABLE」回應),就會清除該運算子的快取。
錯誤案例
如果發生錯誤,DPA 應傳回與下列其中一項對應的 HTTP 狀態碼:
- 使用者目前處於漫遊狀態,且已為該使用者停用 DPA 查詢。DPA 會傳回 403 錯誤。
- DPA 會傳回 404 NOT_FOUND 錯誤代碼,向 GTAF 指出 user key 無效 (即不存在的 user key)。
- 如果 key_type = CPID 且 CPID 已過期,DPA 會傳回 410 GONE 錯誤代碼,向 GTAF 表示用戶端應取得新的使用者金鑰。
- DPA 會傳回 501 NOT_IMPLEMENTED 錯誤代碼,表示不支援這項呼叫。
- 暫時無法使用服務,DPA 會傳回 503 SERVICE UNAVAILABLE,並在 Retry-After 標頭中指出何時可以嘗試新要求。
- 對於所有其他未指定的錯誤,DPA 會傳回 500 INTERNAL SERVER ERROR 錯誤代碼。
- DPA 會傳回 429 TOO_MANY_REQUESTS 錯誤,並附上 Retry-After 標頭, 指出 GTAF 對 DPA 發出過多要求。
- DPA 會傳回 409 CONFLICT 錯誤,表示要求與 DPA 目前的狀態發生衝突,因此無法完成。
在所有錯誤情況下,HTTP 回應的主體都必須包含 JSON 物件,其中含有錯誤的詳細資訊。錯誤回應主體必須包含 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 欄位指出所選語言。