Motivação
Como mencionado na visão geral, dependendo dos casos de uso que o operador quer oferecer suporte, o DPA precisa implementar uma combinação da API Google Mobile Data Plan Sharing e da API Data Plan Agent. Este documento descreve a API Data Plan Agent, que o Google usa para identificar os planos de dados móveis do usuário, recuperar informações sobre eles e comprar planos de dados.
Autenticação
Antes que o GTAF possa fazer chamadas, o DPA precisa autenticar o GTAF. Como parte do processo de integração do operador, vamos verificar a validade do certificado SSL da DPA. Atualmente, EXIGIMOS o uso do OAuth2 para autenticação mútua.
Descrição da API
O GTAF usa a chave do usuário, que identifica um assinante do operador, ao consultar a DPA do operador. Quando o GTAF consulta a DPA em nome de aplicativos que têm acesso ao MSISDN, o GTAF PODE usar o MSISDN. Em um nível alto, a API Data Plan Agent proposta inclui os seguintes componentes:
- Mecanismo para consultar o status do plano de dados do usuário.
- Mecanismo para consultar a DPA sobre ofertas de plano de dados para o usuário.
- Mecanismo para fazer mudanças no plano de dados do usuário (por exemplo, comprar um novo plano).
- Mecanismo para verificar se um usuário está qualificado para comprar um determinado plano de dados.
- Mecanismo para o GTAF registrar MSISDNs com a DPA.
- Mecanismo para o GTAF verificar se o DPA está em um estado íntegro.
O restante deste documento detalha cada um desses componentes da API. A menos que seja explicitamente indicado, todas as comunicações precisam acontecer por HTTPS (com um certificado SSL de DPA válido). Dependendo dos recursos reais compatíveis, um operador PODE implementar todos ou um subconjunto desses componentes de API.
Como consultar o status do plano de dados
Interação entre GTAF e DPA
Figura 4. Fluxo de chamadas para solicitar e receber informações do plano de dados do usuário.
A Figura 4 ilustra o fluxo de chamadas associado a um cliente que consulta o status do plano de dados do usuário e outras informações relacionadas. Esse fluxo de chamadas é compartilhado para chamadas de API acionadas pelo cliente no UE.
- O cliente solicita o status do plano de dados e/ou outras informações chamando uma API privada do Google. O cliente inclui a chave de usuário na solicitação para o GTAF.
- O GTAF usa a chave do usuário e um identificador do cliente para consultar a DPA do operador. Os identificadores de cliente aceitos são mobiledataplan e youtube. Quando o DPA recebe uma chamada com um desses identificadores de cliente, ele PRECISA responder com informações do plano que podem ser usadas pelo cliente.
- O GTAF retorna as informações solicitadas ao cliente, e as informações do plano são armazenadas em cache pelo GTAF até o horário de expiração especificado pela DPA.
As etapas 1 e 3 na Figura 4 são APIs privadas do Google e, portanto, não são descritas com mais detalhes. A etapa 2 é uma API pública descrita abaixo. O DPA PRECISA respeitar o cabeçalho HTTP Cache-Control: no-cache
ao veicular essas chamadas de API do GTAF.
Status do plano
O GTAF emite a seguinte solicitação HTTP para receber o status do plano:
GET DPA_URL/{userKey}/planStatus?key_type={CPID,MSISDN}&client_id=CLIENT_ID
O cliente em nome de quem a GTAF está entrando em contato com a DPA é identificado usando CLIENT_ID. Dependendo do contrato entre o cliente do Google e a operadora, a DPA pode personalizar a resposta à GTAF. O formato da resposta é um objeto JSON que representa um 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
}
}
}
}
A solicitação DEVE incluir um cabeçalho Accept-Language
indicando o idioma
em que as strings legíveis (por exemplo, descrições de planos) devem estar.
Para planos pós-pagos, expirationTime
PRECISA ser a data de recorrência do plano (ou seja, quando o saldo de dados é atualizado/recarregado).
Cada módulo de plano pode conter várias categorias de tráfego de módulo de plano (PMTCs)
) para modelar o caso em que um módulo de plano é compartilhado entre vários apps (por exemplo, 500 MB para jogos e músicas. Os seguintes PMTCs são predefinidos: GENERIC, VIDEO,
VIDEO_BROWSING, VIDEO_OFFLINE, MUSIC, GAMING, SOCIAL and MESSAGING.
. Espera-se que os operadores entrem em contato com equipes individuais do Google para concordar com o conjunto de categorias de tráfego e suas semânticas relevantes para diferentes aplicativos do Google.
Consultar ofertas de planos
O GTAF emite a seguinte solicitação HTTP para receber ofertas de planos da operadora:
GET DPA_URL/{userKey}/planOffer?key_type={CPID,MSISDN}&client_id=CLIENT_ID&context={purchaseContext}
O cliente em nome de quem a GTAF está entrando em contato com a DPA é identificado usando CLIENT_ID. Dependendo do contrato entre o cliente do Google e a operadora, a DPA pode personalizar a resposta à GTAF. O parâmetro de contexto opcional fornece o contexto do aplicativo em que a solicitação é feita. Normalmente, essa é uma string que o aplicativo transmite ao operador pelo GTAF.
O corpo da resposta contém uma instância de 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.
}
A ordem dos planos de dados na matriz offers
PODE determinar a ordem em que os planos de dados são apresentados aos usuários. Além disso, se o aplicativo puder apresentar apenas x planos devido a limitações de interface ou outras, e a resposta contiver y > x planos, apenas os primeiros x planos SERÃO apresentados. O GTAF compartilha apenas até 10 planos se o aplicativo que consulta ofertas for a interface do plano de dados móvel, que faz parte dos Serviços do Google Play. Isso garante uma boa experiência para os usuários
do Google Play Services.
As strings em offerInfo
permitem que o usuário leia mais sobre a oferta e incluem uma maneira de recusar o recebimento de mais ofertas nos aplicativos. O motivo de ter esses campos é que algumas operadoras não precisam do consentimento do usuário final para permitir compras no app, mas exigem um mecanismo para que os usuários desativem essa opção. O operador PRECISA ter um mecanismo para atender a um pedido de compra de qualquer oferta feita ao usuário. O mecanismo pelo qual
o usuário vai pagar por qualquer compra pode ser comunicado com o GTAF usando a opção
formOfPayment
na resposta.
A solicitação DEVE incluir um cabeçalho Accept-Language
indicando o idioma
em que as strings legíveis (por exemplo, descrições de planos) devem estar.
Compra de dados
A API de plano de compra define como o GTAF pode comprar planos pela DPA. O GTAF inicia a transação para comprar um plano de dados para o DPA. A solicitação DEVE incluir um identificador de transação exclusivo (transactionId) para rastrear solicitações e evitar a execução de transações duplicadas. O DPA PRECISA responder com uma resposta de sucesso/falha.
Solicitação de transação
Quando recebe uma solicitação de um cliente, o GTAF emite uma solicitação POST para a DPA. O URL da solicitação é:
POST DPA_URL/{userKey}/purchasePlan?key_type={CPID,MSISDN}&client_id=CLIENT_ID
em que userKey
é um CPID
ou MSISDN
. O corpo da solicitação é uma instância de TransactionRequest, que inclui os seguintes campos:
{
"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.
}
Resposta da transação
O DPA vai retornar as causas de erro comuns em caso de erro. Além disso, os seguintes códigos de erro representam resultados de transações com falha:
- A DPA retorna um código de erro 400 BAD REQUEST indicando ao GTAF que o ID do plano comprado é inválido.
- A DPA retorna um código de erro 402 PAYMENT REQUIRED, indicando à GTAF que o usuário não tem saldo suficiente para concluir a compra.
- A DPA retorna um código de erro 409 CONFLICT, indicando ao GTAF que o plano a ser comprado é incompatível com o mix de produtos atual do usuário. Por exemplo, se a política de plano de dados da operadora não permitir a combinação de planos pós-pago e pré-pago, tentar comprar um plano pré-pago para um usuário pós-pago vai gerar um erro 409 CONFLICT.
- A DPA retorna um código de erro 403 FORBIDDEN indicando ao GTAF que a
transação atual é uma duplicata de uma transação emitida anteriormente. O
DPA DEVE retornar as seguintes causas de erro na resposta:
- Se a transação anterior falhou, a causa do erro indica o motivo da falha.
- Se a transação anterior foi concluída, DUPLICATE_TRANSACTION.
- Se a transação anterior ainda estiver na fila, REQUEST_QUEUED.
O DPA GERA uma resposta 200-OK apenas para uma transação executada ou enfileirada com sucesso. No caso de uma transação em fila, o DPA só vai preencher o status da transação e deixar outros campos na resposta em branco. O DPA PRECISA retornar uma resposta à GTAF depois que uma transação enfileirada for processada. O corpo da resposta é uma instância de TransactionResponse, que inclui os seguintes detalhes:
{
"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.
}
}
Se o planActivationTime
estiver ausente, o GTAF vai presumir que o plano foi ativado.
Consentimento
O GTAF PODE emitir a seguinte solicitação para transmitir a preferência de consentimento do usuário à operadora.
POST DPA_URL/{userKey}/consent?key_type={CPID,MSISDN}&client_id=CLIENT_ID
em que userKey
é um CPID
ou MSISDN
. O corpo da solicitação é uma
instância de
SetConsentStatusRequest.
Se a solicitação for bem-sucedida, o corpo da resposta estará vazio.
Qualificação
O GTAF PODE emitir a seguinte solicitação de qualificação para verificar se um usuário está qualificado para comprar um plano.
GET DPA/{userKey}/Eligibility/{planId}?key_type={CPID,MSISDN}
planId
é o identificador exclusivo do plano que pode ser usado para
comprar o plano em nome do usuário (consulte Compra de dados).
Se planId
não for especificado, o DPA vai retornar todos os planos que podem ser comprados por esse
usuário.
O DPA vai retornar as causas de erro comuns em caso de erro. Além disso, a DPA VAI retornar um erro nos seguintes casos:
- A DPA retorna um código de erro 400 BAD REQUEST indicando ao GTAF que
planId
é inválido. - A DPA retorna um código de erro 409 CONFLICT indicando que
planId
é incompatível com o plano de dados do usuário.
Caso contrário, o DPA vai retornar uma resposta 200-OK. O formato de uma EligibilityResponse bem-sucedida é:
{
"eligiblePlans":
[
{
"planId": string, // Plan identifier. Can be used to
// refer to the plan during
// offers, etc. (req.)
}
]
}
Quando a solicitação inclui um planId
, a resposta inclui apenas esse plano. Caso contrário, a lista inclui todos os planos que o usuário pode
comprar. Se planId
estiver vazio e a DPA não oferecer suporte ao retorno da lista de planos qualificados, ela precisará retornar um erro 400 BAD REQUEST.
Endpoint de registro de MSISDN
Para veicular aplicativos que têm acesso ao MSISDN, o GTAF vai registrar o MSISDN com a DPA. O GTAF registra o MSISDN apenas quando há aplicativos veiculados pela API Google Mobile Data Plan Sharing, em que o DPA envia informações ao GTAF usando APIs do Google. Para registrar o MSISDN, o GTAF fará uma solicitação POST para o DPA:
POST DPA_URL/register
O corpo da solicitação será uma instância de RegistrationRequest.
{
"msisdn": "<msisdn_string>"
}
Se o registro do MSISDN for bem-sucedido, o DPA precisará retornar uma resposta 200 OK, incluindo RegistrationResponse. O formato do JSON é:
{
// msisdn that was registered.
"msisdn": "<msisdn_string>",
// time after which DPA will not send updates to GTAF.
"expirationTime": string
}
O DPA DEVE enviar atualizações sobre o plano de dados do usuário para o GTAF até que o expirationTime tenha passado.
Se ocorrer um erro, uma ErrorResponse deverá ser retornada:
{
"error": "<error message>",
"cause": enum(ErrorCause)
}
A lista completa de possíveis valores de causa e códigos de status HTTP para diferentes condições de erro está disponível aqui. Em particular, se uma solicitação de registro de MSISDN for recebida para um usuário em roaming ou que não tenha permitido o compartilhamento de informações do plano de dados com o Google, o DPA DEVE retornar o código de status HTTP 403.
API Monitoring
Alguns casos de uso exigem que o GTAF monitore o DPA e detecte falhas. Para esses casos de uso, definimos uma API de monitoramento.
Definição de API
A API de monitoramento precisa estar disponível por uma solicitação HTTP GET no seguinte URL:
DPA_URL/dpaStatus
Se o DPA e todos os back-ends estiverem funcionando corretamente, o DPA vai responder a essa consulta com o código de status HTTP 200 e um corpo de resposta que tem uma instância de DpaStatus.
{
"status": enum(DpaStatusEnum),
"message": "<optional human-readable status description>"
}
Se o DPA ou qualquer um dos back-ends dele não estiver funcionando corretamente, ele vai responder com o código de status HTTP 500 e um corpo de resposta que tenha uma instância de DpaStatus.
Comportamento da DPA
Quando uma falha é detectada, a DPA precisa retornar o status "UNAVAILABLE" para todas as consultas dpaStatus. Além disso, ele precisa parar de enviar informações do plano de dados com períodos longos de cache. Ele pode parar de enviar respostas com longos períodos de cache de uma das duas maneiras:
- Comece a definir prazos de validade curtos para o cache.
- Parar de enviar informações do plano de dados completamente.
Comportamento da GTAF
O GTAF vai pesquisar o dpaStatus periodicamente. Quando ele detecta uma falha de DPA (com base na resposta "UNAVAILABLE"), o cache do operador é limpo.
Casos de erro
Em caso de erro, espera-se que o DPA retorne um código de status HTTP correspondente a um dos seguintes:
- O usuário está em roaming, e a consulta de DPA está desativada para ele. A DPA retorna um erro 403.
- A DPA retorna um código de erro 404 NOT_FOUND, indicando ao GTAF que a chave de usuário é inválida (ou seja, uma chave de usuário inexistente).
- A DPA retorna um código de erro 410 GONE indicando ao GTAF que o cliente precisa receber uma nova chave de usuário se key_type = CPID e o CPID expirou.
- A DPA retorna um código de erro 501 NOT_IMPLEMENTED indicando que não há suporte para essa chamada.
- Serviço temporariamente indisponível. A DPA retorna um 503 SERVICE UNAVAILABLE com o cabeçalho "Retry-After" indicando quando uma nova solicitação pode ser feita.
- A DPA retorna um código de erro 500 INTERNAL SERVER ERROR para todos os outros erros não especificados.
- A DPA retorna um erro 429 TOO_MANY_REQUESTS com o cabeçalho "Retry-After" indicando que o GTAF está fazendo muitas solicitações à DPA.
- A DPA retorna um erro 409 CONFLICT indicando que a solicitação não pode ser concluída devido a um conflito com o estado atual da DPA.
Em todos os casos de erro, o corpo da resposta HTTP PRECISA incluir um objeto JSON com mais informações sobre o erro. O corpo da resposta de erro PRECISA conter uma instância de ErrorResponse.
{
"error": string,
"cause": enum(ErrorCause)
}
Os valores cause
definidos no momento estão listados como parte da
referência da API ErrorCause.
Caso contrário, a DPA vai retornar um 200 OK. Esses valores cause
são usados em todas as respostas.
Internacionalização
As solicitações da GTAF à DPA incluem um cabeçalho "Accept-Language" que indica o idioma em que as strings legíveis (por exemplo, descrições de planos) devem estar. Além disso, as respostas da DPA (PlanStatus, PlanOffers) incluem um campo obrigatório languageCode cujo valor é o código de idioma BCP-47 (por exemplo, "en-US") da resposta.
Se a DPA não for compatível com o idioma solicitado pelo usuário, ela poderá usar um idioma padrão e o campo "languageCode" para indicar a escolha.