API агента плана данных, API агента плана данных

Мотивация

Как упоминалось в обзоре , в зависимости от вариантов использования, которые оператор хочет поддерживать, DPA должен реализовать комбинацию API совместного использования планов мобильных данных Google и API агента плана данных. В этом документе описывается API-интерфейс Data Plan Agent, который Google будет использовать для идентификации мобильных тарифных планов пользователя, получения информации об этих тарифных планах и приобретения тарифных планов.

Аутентификация

Прежде чем GTAF сможет позвонить, DPA должен аутентифицировать GTAF. В рамках процесса адаптации оператора мы проверим действительность SSL-сертификата DPA. В настоящее время мы ТРЕБУЕМ использовать OAuth2 для взаимной аутентификации.

Описание API

GTAF использует ключ пользователя , который идентифицирует абонента оператора, при запросе DPA оператора. Когда GTAF запрашивает DPA от имени приложений, имеющих доступ к MSISDN, GTAF МОЖЕТ использовать MSISDN. На высоком уровне предлагаемый API агента плана данных включает следующие компоненты:

  1. Механизм запроса статуса пользовательского тарифного плана.
  2. Механизм запроса к DPA предложений тарифного плана для пользователя.
  3. Механизм внесения изменений в тарифный план пользователя (например, покупка нового плана).
  4. Механизм для проверки того, имеет ли пользователь право приобрести определенный тарифный план.
  5. Механизм GTAF для регистрации MSISDN в DPA.
  6. Механизм GTAF для проверки работоспособности DPA.

Остальная часть этого документа подробно описывает каждый из этих компонентов API. Если явно не указано иное, все коммуникации ДОЛЖНЫ осуществляться по протоколу HTTPS (с действительным сертификатом SSL DPA). В зависимости от фактических поддерживаемых функций оператор МОЖЕТ реализовать все или часть этих компонентов API.

Запрос статуса плана данных

Взаимодействие GTAF-DPA

GTAF-DPA Interaction

Рис. 4. Поток вызовов для запроса и получения информации о тарифном плане пользователя.

На рис. 4 показан поток вызовов, связанный с запросом клиента о статусе плана данных пользователя и другой информации о плане данных. Этот поток вызовов используется совместно для вызовов API, инициированных клиентом в UE.

  1. Клиент запрашивает статус тарифного плана и/или другую информацию, вызывая частный API Google. Клиент включает ключ пользователя в запрос к GTAF.
  2. GTAF использует ключ пользователя и идентификатор клиента для запроса DPA оператора. Поддерживаемые идентификаторы клиентов: mobiledataplan и youtube . Когда DPA получает вызов с одним из этих идентификаторов клиента, он ДОЛЖЕН ответить информацией о плане, которую может использовать клиент.
  3. GTAF возвращает запрошенную информацию клиенту, а информация о плане кэшируется GTAF до истечения срока действия, указанного DPA.

Шаги 1 и 3 на рис. 4 являются частными API Google и поэтому далее не описываются. Шаг 2 — общедоступный API, описанный ниже. DPA ДОЛЖЕН учитывать HTTP-заголовок Cache-Control: no-cache при обслуживании этих вызовов API из GTAF.

Статус плана

GTAF отправляет следующий HTTP-запрос, чтобы получить статус плана:

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

Клиент, от имени которого GTAF связывается с DPA, идентифицируется с помощью CLIENT_ID . В зависимости от соглашения между клиентом Google и оператором DPA может настроить ответ на GTAF. Формат ответа — объект JSON, представляющий PlanStatus .

{
  "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 МБ для игр и музыки). Предварительно определены следующие 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 МОЖЕТ определять порядок, в котором планы данных представляются пользователям. Кроме того, если приложение может представить только x планов из-за пользовательского интерфейса или других ограничений, а ответ содержит y > x планов, ДОЛЖНЫ быть представлены только первые x планов. GTAF использует только до 10 планов, если приложение, запрашивающее предложения, представляет собой пользовательский интерфейс Mobile Data Plan, который является частью сервисов Google Play. Это необходимо для обеспечения удобного взаимодействия с пользователями Сервисов Google Play.

Строки в offerInfo предназначены для того, чтобы позволить пользователю узнать больше о предложении, а также включить способ отказаться от получения дополнительных предложений от внутренних приложений. Причина наличия этих полей заключается в том, что некоторым операторам не требуется согласие конечного пользователя, чтобы разрешить покупки в приложении, а скорее требуется механизм отказа пользователей. Обратите внимание, что оператор ДОЛЖЕН иметь механизм для выполнения запроса на покупку для любого предложения, предоставленного пользователю. Механизм, с помощью которого с пользователя будет взиматься плата за любую покупку, можно сообщить GTAF с помощью параметра formOfPayment в ответе.

Запрос ДОЛЖЕН включать заголовок Accept-Language , указывающий язык, на котором должны быть читаемые человеком строки (например, описания плана).

Покупка данных

API плана покупки определяет, как GTAF может приобретать планы через DPA. GTAF инициирует транзакцию для покупки одного тарифного плана для DPA. Запрос ДОЛЖЕН включать уникальный идентификатор транзакции (transactionId) для отслеживания запросов и предотвращения дублирования выполнения транзакции. DPA ДОЛЖЕН ответить ответом об успехе/неуспехе.

Запрос транзакции

Получив запрос от клиента, GTAF отправляет запрос POST в DPA. URL-адрес запроса:

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, что идентификатор приобретенного плана недействителен.
  • 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 — это уникальный идентификатор плана, который можно использовать для приобретения плана от имени пользователя (см. раздел « Покупка данных »). Если 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 зарегистрирует MSISDN в DPA. GTAF регистрирует MSISDN только при наличии приложений, обслуживаемых Google Mobile Data Plan Sharing API, при этом DPA отправляет информацию в GTAF с использованием API Google. Чтобы зарегистрировать MSISDN, GTAF отправит запрос POST к DPA:

POST DPA_URL/регистрация

Тело запроса будет экземпляром 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 до истечения срока действия .

При возникновении ошибки должен быть возвращен ErrorResponse :

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

Полный список возможных значений причины и кодов состояния HTTP для различных состояний ошибки доступен здесь . В частности, если запрос на регистрацию MSISDN получен для пользователя, который находится в роуминге или не решил делиться информацией о тарифном плане с Google, DPA ДОЛЖЕН вернуть код состояния HTTP 403.

API мониторинга

В некоторых случаях использования GTAF требует мониторинга DPA и обнаружения сбоев DPA. Для этих случаев использования мы определили API мониторинга.

Определение API

API мониторинга должен быть доступен через HTTP-запрос GET по следующему URL-адресу:

DPA_URL/dpaStatus

Если DPA и все его серверные части работают правильно, DPA должен ответить на этот запрос с кодом состояния HTTP 200 и телом ответа, которое имеет экземпляр DpaStatus .

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

Если DPA или какой-либо из его бэкендов не работает правильно, он должен ответить кодом состояния HTTP 500 и телом ответа, которое имеет экземпляр DpaStatus .

Поведение DPA

При обнаружении сбоя DPA должен вернуть статус «НЕДОСТУПЕН» для всех запросов dpaStatus. Кроме того, он должен прекратить отправку информации о плане данных с длительными периодами кэширования. Он может прекратить отправку ответов с длительным периодом кэширования одним из двух способов:

  1. Начните устанавливать короткие сроки действия кеша.
  2. Полностью прекратить отправку информации о тарифных планах.

Поведение GTAF

GTAF будет периодически опрашивать dpaStatus. Когда он обнаруживает сбой DPA (на основе ответа «НЕДОСТУПЕН»), он очищает свой кэш для оператора.

Случаи ошибок

Ожидается, что в случае ошибки DPA вернет код состояния HTTP, соответствующий одному из следующих:

  • Пользователь в настоящее время находится в роуминге, и запрос DPA отключен для этого пользователя. DPA возвращает ошибку 403.
  • DPA возвращает код ошибки 404 NOT_FOUND, указывающий GTAF, что пользовательский ключ недействителен (т. е. пользовательский ключ не существует).
  • DPA возвращает код ошибки 410 GONE, указывающий GTAF, что клиент должен получить новый ключ пользователя , если key_type = CPID и срок действия CPID истек.
  • 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 перечислены как часть справочника по API ErrorCause .

В противном случае DPA возвращает 200 OK. Отметим, что эти значения cause используются для всех ответов.

Интернационализация

Запросы GTAF к DPA включают заголовок Accept-Language, указывающий язык, на котором должны быть читаемые человеком строки (например, описания планов). Кроме того, ответы DPA (PlanStatus, PlanOffers) включают обязательное поле languageCode, значением которого является BCP-47. код языка (например, "en-US") ответа.

Если DPA не поддерживает запрошенный пользователем язык, он может использовать язык по умолчанию и использовать поле languageCode, чтобы указать свой выбор.