API Data Plan Agent

Motivation

Comme indiqué dans la présentation, selon les cas d'utilisation que l'opérateur souhaite prendre en charge, le DPA doit implémenter une combinaison de l'API Google Mobile Data Plan Sharing et de l'API Data Plan Agent. Ce document décrit l'API Data Plan Agent que Google utilisera pour identifier les forfaits de données mobiles de l'utilisateur, récupérer des informations sur ces forfaits et en acheter.

Authentification

Avant que GTAF puisse appeler, le DPA doit authentifier GTAF. Lors de la procédure d'intégration des opérateurs, nous vérifions la validité du certificat SSL DPA. Nous EXIGEONS actuellement l'utilisation d'OAuth2 pour l'authentification mutuelle.

Description de l'API

GTAF utilise une clé utilisateur, qui identifie un abonné à l'opérateur, lorsqu'il interroge le DPA de l'opérateur. Lorsque GTAF interroge le DPA au nom des applications ayant accès au MSISDN, il PEUT utiliser le MSISDN. De manière générale, l'API Data Plan Agent proposée comprend les composants suivants :

  1. Mécanisme permettant d'interroger l'état du forfait de données de l'utilisateur.
  2. Mécanisme permettant d'interroger le DPA pour obtenir des offres de forfaits de données pour l'utilisateur.
  3. Mécanisme permettant de modifier le forfait de données de l'utilisateur (par exemple, en souscrivant un nouveau forfait).
  4. Mécanisme permettant de vérifier si un utilisateur est éligible à l'achat d'un forfait de données spécifique.
  5. Mécanisme permettant à GTAF d'enregistrer les MSISDN auprès de l'APD.
  6. Mécanisme permettant à GTAF de vérifier si le DPA est en bon état.

Le reste de ce document développe chacun de ces composants de l'API. Sauf indication contraire, toutes les communications DOIVENT se faire via HTTPS (avec un certificat SSL DPA valide). Selon les fonctionnalités réellement prises en charge, un opérateur PEUT choisir d'implémenter tout ou partie de ces composants d'API.

Interroger l'état du forfait de données

Interaction entre GTAF et DPA

Interaction entre GTAF et DPA

Figure 4 Flux d'appel pour demander et recevoir des informations sur le forfait de données de l'utilisateur.

La figure 4 illustre le flux d'appels associé à un client qui interroge l'état du forfait de données de l'utilisateur et d'autres informations sur le forfait de données. Ce flux d'appels est partagé pour les appels d'API déclenchés par le client sur l'UE.

  1. Le client demande l'état du forfait de données et/ou d'autres informations en appelant une API Google privée. Le client inclut la clé utilisateur dans la requête envoyée à GTAF.
  2. GTAF utilise la clé utilisateur et un identifiant client pour interroger le DPA de l'opérateur. Les identifiants client acceptés sont mobiledataplan et youtube. Lorsque le DPA reçoit un appel avec l'un de ces identifiants client, il DOIT répondre avec des informations sur le forfait que le client peut utiliser.
  3. GTAF renvoie les informations demandées au client, et les informations sur le forfait sont mises en cache par GTAF jusqu'à l'expiration spécifiée par le DPA.

Les étapes 1 et 3 de la figure 4 sont des API Google privées et ne sont donc pas décrites plus en détail. L'étape 2 est une API publique décrite ci-dessous. Le DPA DOIT respecter l'en-tête HTTP Cache-Control: no-cache lorsqu'il traite ces appels d'API depuis GTAF.

État du plan

GTAF émet la requête HTTP suivante pour obtenir l'état du forfait :

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

Le client au nom duquel GTAF contacte l'APD est identifié à l'aide de CLIENT_ID. En fonction de l'accord entre le client Google et l'opérateur, le DPA peut personnaliser la réponse au GTAF. Le format de la réponse est un objet JSON représentant un 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
      }
    }
  }
}

La requête DOIT inclure un en-tête Accept-Language indiquant la langue dans laquelle les chaînes lisibles (par exemple, les descriptions des forfaits) doivent être affichées.

Pour les forfaits postpayés, expirationTime DOIT correspondre à la date de récurrence du forfait (c'est-à-dire la date à laquelle le solde de données est actualisé/rechargé).

Chaque module de forfait peut contenir plusieurs catégories de trafic de module de forfait (PMTCs)) pour modéliser le cas où un module de forfait est partagé entre plusieurs applications (par exemple, 500 Mo pour les jeux et la musique). Les PMTC suivants sont prédéfinis : GENERIC, VIDEO, VIDEO_BROWSING, VIDEO_OFFLINE, MUSIC, GAMING, SOCIAL and MESSAGING.. Les opérateurs doivent contacter les équipes Google concernées pour définir l'ensemble des catégories de trafic et leur sémantique qui sont pertinentes pour les différentes applications Google.

Interroger les offres de forfait

GTAF envoie la requête HTTP suivante pour obtenir les offres de forfaits de l'opérateur :

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

Le client au nom duquel GTAF contacte l'APD est identifié à l'aide de CLIENT_ID. En fonction de l'accord entre le client Google et l'opérateur, le DPA peut personnaliser la réponse au GTAF. Le paramètre de contexte facultatif fournit le contexte d'application dans lequel la requête est effectuée. Il s'agit généralement d'une chaîne que l'application transmet à l'opérateur via GTAF.

Le corps de la réponse contient une instance 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.
}

L'ordre des forfaits de données dans le tableau offers PEUT déterminer l'ordre dans lequel les forfaits de données sont présentés aux utilisateurs. De plus, si l'application ne peut présenter que x forfaits en raison de limitations de l'UI ou d'autres limitations, et que la réponse contient y > x forfaits, seuls les x premiers forfaits DOIVENT être présentés. GTAF ne partage que 10 forfaits maximum si l'application qui interroge les offres est l'UI du forfait de données mobiles, qui fait partie des services Google Play. Cela permet de garantir une bonne expérience utilisateur aux utilisateurs des services Google Play.

Les chaînes de offerInfo sont destinées à permettre à l'utilisateur d'en savoir plus sur l'offre. Elles incluent également un moyen de refuser de recevoir d'autres offres dans les applications. La raison d'être de ces champs est que certains opérateurs n'ont pas besoin du consentement de l'utilisateur final pour autoriser les achats via l'application, mais nécessitent plutôt un mécanisme permettant aux utilisateurs de se désinscrire. Notez que l'opérateur DOIT disposer d'un mécanisme permettant de répondre à une demande d'achat pour toute offre proposée à l'utilisateur. Le mécanisme par lequel l'utilisateur sera facturé pour tout achat peut être communiqué à GTAF à l'aide de l'option formOfPayment dans la réponse.

La requête DOIT inclure un en-tête Accept-Language indiquant la langue dans laquelle les chaînes lisibles (par exemple, les descriptions des forfaits) doivent être affichées.

Achat de données

L'API Purchase Plan définit la manière dont GTAF peut acheter des forfaits via le DPA. Le GTAF initie la transaction pour acheter un forfait de données auprès du DPA. La requête DOIT inclure un identifiant de transaction unique (transactionId) pour suivre les requêtes et éviter l'exécution de transactions en double. La DPA DOIT répondre avec une réponse de réussite/échec.

Demande de transaction

Une fois qu'il reçoit une demande d'un client, GTAF émet une requête POST au DPA. L'URL de la requête est la suivante :

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

userKey est un CPID ou un MSISDN. Le corps de la requête est une instance de TransactionRequest qui inclut les champs suivants :

{
  "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.
}

Réponse de la transaction

En cas d'erreur, le DPA DOIT renvoyer les causes d'erreur courantes. De plus, les codes d'erreur suivants représentent des résultats de transactions ayant échoué :

  • Le DPA renvoie un code d'erreur 400 BAD REQUEST indiquant à GTAF que l'ID du forfait acheté n'est pas valide.
  • Le DPA renvoie un code d'erreur 402 PAYMENT REQUIRED (Paiement requis) indiquant à GTAF que l'utilisateur ne dispose pas d'un solde suffisant pour effectuer l'achat.
  • Le DPA renvoie un code d'erreur 409 CONFLICT indiquant à GTAF que le forfait à acheter n'est pas compatible avec la combinaison de produits actuelle de l'utilisateur. Par exemple, si la règle relative au forfait de données de l'opérateur n'autorise pas le mélange de forfaits postpayés et prépayés, toute tentative d'achat d'un forfait prépayé pour un utilisateur postpayé entraînera une erreur 409 CONFLICT.
  • Le DPA renvoie un code d'erreur 403 FORBIDDEN indiquant à GTAF que la transaction actuelle est un doublon d'une transaction émise précédemment. Le DPA DOIT renvoyer les causes d'erreur suivantes en réponse :
    • Si la transaction précédente a échoué, la cause de l'erreur indique la raison de l'échec.
    • Si la transaction précédente a réussi, DUPLICATE_TRANSACTION.
    • Si la transaction précédente est toujours dans la file d'attente, REQUEST_QUEUED.

Le DPA DOIT générer une réponse 200-OK uniquement pour une transaction exécutée ou mise en file d'attente. En cas de transaction en file d'attente, le DPA ne doit renseigner que l'état de la transaction et laisser les autres champs de la réponse vides. Le DPA DOIT rappeler GTAF avec une réponse une fois qu'une transaction en file d'attente a été traitée. Le corps de la réponse est une instance de TransactionResponse qui inclut les informations suivantes :

{
  "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.
  }
}

Si le planActivationTime est manquant, GTAF DOIT supposer que le forfait a été activé.

GTAF PEUT émettre la demande suivante pour transmettre la préférence de consentement de l'utilisateur à l'opérateur.

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

userKey est un CPID ou un MSISDN. Le corps de la requête est une instance de SetConsentStatusRequest.

Si la requête aboutit, le corps de la réponse doit être vide.

Éligibilité

GTAF MAY peut émettre la demande d'éligibilité suivante pour vérifier si un utilisateur peut souscrire un forfait.

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

Notez que planId est l'identifiant unique du forfait qui peut être utilisé pour l'acheter au nom de l'utilisateur (voir Achat de données). Si planId n'est pas spécifié, le DPA DOIT renvoyer tous les forfaits que l'utilisateur peut acheter.

En cas d'erreur, le DPA DOIT renvoyer les causes d'erreur courantes. En outre, le DPA DOIT renvoyer une erreur dans les cas suivants :

  • Le DPA renvoie un code d'erreur 400 BAD REQUEST indiquant à GTAF que planId n'est pas valide.
  • Le DPA renvoie un code d'erreur 409 CONFLICT indiquant que planId est incompatible avec le forfait de données de l'utilisateur.

Sinon, le DPA DOIT renvoyer une réponse 200-OK. Le format d'une EligibilityResponse réussie est le suivant :

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

Lorsque la requête inclut un planId, la réponse n'inclut que ce forfait. Sinon, la liste inclut tous les forfaits que l'utilisateur peut acheter. Si planId est vide et que le DPA ne permet pas de renvoyer la liste des forfaits éligibles, il DOIT renvoyer une erreur 400 BAD REQUEST.

Point de terminaison d'enregistrement du MSISDN

Pour diffuser des applications ayant accès au MSISDN, GTAF enregistre le MSISDN auprès de la DPA. Le GTAF n'enregistre le MSISDN que lorsqu'il existe des applications fournies par l'API Google Mobile Data Plan Sharing, dans lesquelles le DPA envoie des informations au GTAF à l'aide des API Google. Pour enregistrer un MSISDN, GTAF envoie une requête POST au DPA :

POST DPA_URL/register

Le corps de la requête sera une instance de RegistrationRequest.

{
  "msisdn": "<msisdn_string>"
}

Si l'enregistrement du MSISDN réussit, le DPA DOIT renvoyer une réponse 200 OK incluant RegistrationResponse. Le format du fichier JSON est le suivant :

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

Le DPA DOIT ensuite envoyer des informations sur le forfait de données de l'utilisateur à GTAF jusqu'à ce que expirationTime soit écoulé.

En cas d'erreur, une ErrorResponse doit être renvoyée :

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

La liste complète des valeurs cause et des codes d'état HTTP possibles pour les différentes conditions d'erreur est disponible ici. En particulier, si une demande d'enregistrement de MSISDN est reçue pour un utilisateur en itinérance ou qui n'a pas choisi de partager les informations de son forfait de données avec Google, le DPA DOIT renvoyer le code d'état HTTP 403.

Cloud Monitoring

Certains cas d'utilisation nécessitent que GTAF surveille le DPA et détecte les échecs de DPA. Pour ces cas d'utilisation, nous avons défini une API de surveillance.

Définition de l'API

L'API Monitoring doit être disponible via une requête HTTP GET à l'URL suivante :

DPA_URL/dpaStatus

Si le DPA et tous ses backends fonctionnent correctement, le DPA doit répondre à cette requête avec le code d'état HTTP 200 et un corps de réponse contenant une instance de DpaStatus.

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

Si le DPA ou l'un de ses backends ne fonctionnent pas correctement, il doit répondre avec le code d'état HTTP 500 et un corps de réponse contenant une instance de DpaStatus.

Comportement des DPA

Lorsqu'un échec est détecté, le DPA doit renvoyer l'état "UNAVAILABLE" pour toutes les requêtes dpaStatus. De plus, il doit cesser d'envoyer des informations sur le forfait de données avec de longues périodes de mise en cache. Il peut cesser d'envoyer des réponses avec de longues périodes de cache de deux manières :

  1. Commencez par définir des délais d'expiration du cache courts.
  2. Cessez complètement d'envoyer des informations sur le forfait de données.

Comportement GTAF

GTAF interroge régulièrement dpaStatus. Lorsqu'il détecte un échec de DPA (en fonction de la réponse "UNAVAILABLE"), il efface son cache pour l'opérateur.

Cas d'erreur

En cas d'erreur, le DPA doit renvoyer un code d'état HTTP correspondant à l'un des suivants :

  • L'utilisateur est actuellement en itinérance et la requête DPA est désactivée pour cet utilisateur. Le DPA renvoie une erreur 403.
  • Le DPA renvoie un code d'erreur 404 NOT_FOUND indiquant à GTAF que la clé utilisateur n'est pas valide (c'est-à-dire qu'elle n'existe pas).
  • Le DPA renvoie un code d'erreur 410 GONE indiquant à GTAF que le client doit obtenir une nouvelle clé utilisateur si key_type = CPID et que le CPID a expiré.
  • Le DPA renvoie un code d'erreur 501 NOT_IMPLEMENTED indiquant qu'il ne prend pas en charge cet appel.
  • Service momentanément indisponible. Le DPA renvoie un code 503 SERVICE UNAVAILABLE avec l'en-tête Retry-After indiquant quand une nouvelle requête peut être tentée.
  • Le DPA renvoie un code d'erreur 500 INTERNAL SERVER ERROR pour toutes les autres erreurs non spécifiées.
  • Le DPA renvoie une erreur 429 TOO_MANY_REQUESTS avec l'en-tête Retry-After indiquant que GTAF envoie trop de requêtes au DPA.
  • Le DPA renvoie une erreur 409 CONFLICT indiquant que la requête ne peut pas être traitée en raison d'un conflit avec l'état actuel du DPA.

Dans tous les cas d'erreur, le corps de la réponse HTTP DOIT inclure un objet JSON contenant plus d'informations sur l'erreur. Le corps de la réponse d'erreur DOIT contenir une instance de ErrorResponse.

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

Les valeurs cause actuellement définies sont listées dans la référence de l'API ErrorCause.

Sinon, le DPA renvoie un code 200 OK. Notez que ces valeurs cause sont utilisées pour toutes les réponses.

Internationalisation

Les requêtes GTAF envoyées au DPA incluent un en-tête Accept-Language indiquant la langue dans laquelle les chaînes lisibles (par exemple, les descriptions des forfaits) doivent être affichées. De plus, les réponses DPA (PlanStatus, PlanOffers) incluent un champ languageCode obligatoire dont la valeur est le code de langue BCP-47 (par exemple, "en-US") de la réponse.

Si le DPA n'est pas compatible avec la langue demandée par l'utilisateur, il peut utiliser une langue par défaut et indiquer son choix à l'aide du champ "languageCode".