데이터 요금제 에이전트 API

동기

개요에 언급된 바와 같이, 지원하려는 사용 사례에 따라 DPA는 Google 모바일 데이터 요금제 공유 API와 데이터 요금제 에이전트 API를 조합하여 구현해야 합니다. 이 문서에서는 Google이 사용자의 모바일 데이터 요금제를 식별하고, 이러한 요금제에 관한 정보를 검색하고, 데이터 요금제를 구매하는 데 사용하는 데이터 요금제 에이전트 API를 설명합니다.

인증

GTAF가 호출되기 전에 DPA가 GTAF를 인증해야 합니다. 운영자 온보딩 절차의 일환으로 DPA SSL 인증서의 유효성을 확인합니다. 현재 상호 인증에는 OAuth2를 사용해야 합니다.

API 설명

GTAF는 운영자의 DPA를 쿼리할 때 운영자의 구독자를 식별하는 사용자 키를 사용합니다. GTAF가 MSISDN에 액세스할 수 있는 애플리케이션을 대신하여 DPA를 쿼리하는 경우 GTAF는 MSISDN을 사용할 수 있습니다(MAY). 대략적으로 제안된 데이터 요금제 에이전트 API는 다음 구성요소로 구성됩니다.

  1. 사용자 데이터 요금제 상태를 쿼리하는 메커니즘
  2. 사용자의 데이터 요금제 혜택을 DPA에 쿼리하는 메커니즘
  3. 사용자의 데이터 요금제를 변경하는 메커니즘 (예: 새 요금제 구매)
  4. 사용자가 특정 데이터 요금제를 구매할 수 있는지 확인하는 메커니즘입니다.
  5. GTAF가 DPA에 MSISDN을 등록하는 메커니즘
  6. GTAF가 DPA가 정상 상태인지 확인할 수 있는 메커니즘

이 문서의 나머지 부분에서는 이러한 각 API 구성요소를 자세히 설명합니다. 명시적으로 언급되지 않는 한 모든 통신은 HTTPS(유효한 DPA SSL 인증서 사용)를 통해 이루어져야 합니다(MUST). 지원되는 실제 기능에 따라 운영자는 이러한 API 구성요소의 전부 또는 일부를 구현할 수 있습니다(MAY).

데이터 요금제 상태 쿼리

GTAF-DPA 상호작용

GTAF-DPA 상호작용

그림 4. 사용자 데이터 요금제 정보를 요청하고 수신하는 호출 흐름

그림 4는 사용자의 데이터 요금제 상태 및 기타 데이터 요금제 정보를 쿼리하는 클라이언트와 관련된 호출 흐름을 보여줍니다. 이 호출 흐름은 UE에서 클라이언트에 의해 트리거된 API 호출에 공유됩니다.

  1. 클라이언트는 비공개 Google API를 호출하여 데이터 요금제 상태 또는 기타 정보를 요청합니다. 클라이언트는 GTAF에 대한 요청에 사용자 키를 포함합니다.
  2. GTAF는 사용자 키와 클라이언트 식별자를 사용하여 운영자의 DPA를 쿼리합니다. 지원되는 클라이언트 식별자는 mobiledataplanyoutube입니다. DPA는 이러한 클라이언트 식별자 중 하나를 사용하여 전화를 수신할 때 클라이언트가 사용할 수 있는 계획 정보로 응답해야 합니다(MUST).
  3. GTAF는 요청된 정보를 클라이언트에 반환하고 계획 정보는 DPA에서 지정한 만료 시간까지 GTAF에 의해 캐시됩니다.

그림 4의 1단계와 3단계는 비공개 Google API이므로 더 이상 설명하지 않습니다. 2단계는 아래에 설명된 공개 API입니다. DPA는 GTAF에서 이러한 API 호출을 제공할 때 Cache-Control: no-cache HTTP 헤더를 준수해야 합니다(MUST).

계획 상태

GTAF는 요금제 상태를 가져오기 위해 다음 HTTP 요청을 실행합니다.

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

GTAF가 DPA에 연락하는 클라이언트는 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 헤더가 포함되어야 합니다(SHALL).

후불 요금제의 경우 expirationTime는 요금제 반복 날짜(즉, 데이터 잔액이 새로고침/다시 로드되는 시점)여야 합니다(MUST).

각 계획 모듈에는 여러 계획 모듈 트래픽 카테고리가 포함될 수 있습니다(예를 들어 계획 모듈이 여러 앱 간에 공유되는 사례를 모델링하기 위해 PMTCs)). 게임 및 음악의 경우 500MB). 다음 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 배열의 데이터 요금제 순서에 따라 사용자에게 데이터 요금제가 표시되는 순서가 결정될 수 있습니다(MAY). 또한 UI 또는 기타 제한사항으로 인해 애플리케이션에서 x 요금제만 표시할 수 있고 응답에 y > x 요금제만 포함된 경우 처음 x 요금제만 표시해야 합니다(SHALL). GTAF는 혜택을 쿼리하는 애플리케이션이 Google Play 서비스의 일부인 모바일 데이터 요금제 UI인 경우 최대 10개의 요금제만 공유합니다. 이는 Google Play 서비스 사용자에게 우수한 사용자 환경을 제공하기 위한 것입니다.

offerInfo의 문자열은 사용자가 혜택에 대해 자세히 알아볼 수 있도록 하기 위한 것이며, 애플리케이션 내에서 더 많은 혜택을 수신하지 않도록 선택할 수 있는 방법도 포함합니다. 이러한 필드가 있는 이유는 일부 운영자는 인앱 구매를 허용하기 위해 최종 사용자 동의가 필요하지 않지만 사용자가 선택 해제할 수 있는 메커니즘이 필요하기 때문입니다. 운영자는 사용자에게 제공되는 모든 혜택의 구매 요청을 처리하는 메커니즘이 있어야 합니다(MUST). 사용자에게 구매 비용이 청구되는 메커니즘은 응답의 formOfPayment 옵션을 사용하여 GTAF에 전달할 수 있습니다.

요청에는 사람이 읽을 수 있는 문자열(예: 요금제 설명)이 표시되어야 하는 언어를 나타내는 Accept-Language 헤더가 포함되어야 합니다(SHALL).

데이터 구매

구매 계획 API는 GTAF가 DPA를 통해 계획을 구매하는 방법을 정의합니다. GTAF는 DPA에서 하나의 데이터 요금제를 구매하는 트랜잭션을 시작합니다. 요청에는 요청을 추적하고 중복 거래 실행을 방지하기 위한 고유 거래 식별자(transactionId)가 포함되어야 합니다(SHALL). DPA는 성공/실패 응답으로 응답해야 합니다(MUST).

거래 요청

클라이언트로부터 요청을 수신하면 GTAF는 DPA에 POST 요청을 발행합니다. 요청의 URL은 다음과 같습니다.

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

여기서 userKeyCPID 또는 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는 오류가 발생한 경우 일반적인 오류 원인을 반환해야 합니다(SHALL). 또한 다음 오류 코드는 거래 실패 결과를 나타냅니다.

  • DPA는 구매한 요금제 ID가 잘못되었음을 GTAF에 나타내는 400 잘못된 요청 오류 코드를 반환합니다.
  • DPA는 사용자에게 구매를 완료할 잔액이 충분하지 않음을 GTAF에 나타내는 402 PAYMENT REQUIRED 오류 코드를 반환합니다.
  • DPA는 구매할 요금제가 사용자의 현재 제품 조합과 호환되지 않음을 GTAF에 나타내는 409 CONFLICT 오류 코드를 반환합니다. 예를 들어 이동통신사 데이터 요금제 정책에서 후불 요금제와 선불 요금제를 혼합하는 것을 허용하지 않는 경우 후불 사용자가 선불 요금제를 구매하려고 하면 409 CONFLICT 오류가 발생합니다.
  • DPA는 GTAF에 현재 거래가 이전에 발급된 거래의 중복임을 나타내는 403 FORBIDDEN 오류 코드를 반환합니다. DPA는 응답에서 다음 오류 원인을 반환해야 합니다(SHOULD).
    • 이전 트랜잭션이 실패한 경우 실패 이유를 나타내는 오류 원인입니다.
    • 이전 거래가 성공한 경우 DUPLICATE_TRANSACTION
    • 이전 트랜잭션이 아직 대기열에 있는 경우 REQUEST_QUEUED입니다.

DPA는 성공적으로 실행된 트랜잭션 또는 대기열에 추가된 트랜잭션에 대해서만 200-OK 응답을 생성해야 합니다(SHALL). 대기열에 추가된 거래의 경우 DPA는 거래 상태만 입력하고 응답의 다른 필드는 비워 두어야 합니다. 대기열에 추가된 트랜잭션이 처리되면 DPA는 응답과 함께 GTAF를 다시 호출해야 합니다(MUST). 응답 본문은 다음 세부정보가 포함된 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는 사용자 동의 환경설정을 이동통신사에 전달하기 위해 다음 요청을 발행할 수 있습니다(MAY).

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

여기서 userKeyCPID 또는 MSISDN입니다. 요청 본문은 SetConsentStatusRequest의 인스턴스입니다.

성공한 경우 응답 본문은 비어 있어야 합니다.

자격요건

GTAF는 사용자가 요금제를 구매할 수 있는지 확인하기 위해 다음 자격 요건 요청을 발행할 수 있습니다.

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

planId는 사용자를 대신하여 요금제를 구매하는 데 사용할 수 있는 요금제의 고유 식별자입니다 (데이터 구매 참고). planId가 지정되지 않은 경우 DPA는 해당 사용자가 구매할 수 있는 모든 요금제를 반환해야 합니다(MUST).

DPA는 오류가 발생한 경우 일반적인 오류 원인을 반환해야 합니다(SHALL). 또한 DPA는 다음 오류 사례에서 오류를 반환해야 합니다(SHALL).

  • DPA는 GTAF에 planId이 유효하지 않음을 나타내는 400 BAD REQUEST 오류 코드를 반환합니다.
  • DPA는 planId이 사용자의 데이터 요금제와 호환되지 않음을 나타내는 409 CONFLICT 오류 코드를 반환합니다.

그렇지 않으면 DPA는 200-OK 응답을 반환해야 합니다(SHALL). 성공적인 EligibilityResponse의 형식은 다음과 같습니다.

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

요청에 planId가 포함된 경우 응답에는 해당 요금제만 포함됩니다. 그렇지 않으면 목록에 사용자가 구매할 수 있는 모든 요금제가 포함됩니다. planId가 비어 있고 DPA가 자격 요건을 충족하는 요금제 목록 반환을 지원하지 않는 경우 400 BAD REQUEST 오류를 반환해야 합니다(MUST).

MSISDN 등록 엔드포인트

MSISDN에 액세스할 수 있는 애플리케이션을 제공하기 위해 GTAF는 DPA에 MSISDN을 등록합니다. GTAF는 Google 모바일 데이터 요금제 공유 API에서 제공하는 애플리케이션이 있는 경우에만 MSISDN을 등록합니다. 이 경우 DPA는 Google API를 사용하여 GTAF에 정보를 전송합니다. MSISDN을 등록하기 위해 GTAF는 DPA에 POST 요청을 합니다.

POST DPA_URL/register

요청 본문은 RegistrationRequest의 인스턴스입니다.

{
  "msisdn": "<msisdn_string>"
}

MSISDN 등록이 성공하면 DPA는 RegistrationResponse를 포함하는 200 OK 응답을 반환해야 합니다(MUST). JSON 형식은 다음과 같습니다.

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

그런 다음 DPA는 expirationTime이 지날 때까지 사용자 데이터 요금제에 관한 업데이트를 GTAF에 전송해야 합니다(SHOULD).

오류가 발생하면 ErrorResponse가 반환되어야 합니다.

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

다양한 오류 조건에 대한 가능한 원인 값과 HTTP 상태 코드의 전체 목록은 여기에서 확인할 수 있습니다. 특히 로밍 중이거나 Google과 데이터 요금제 정보를 공유하지 않기로 선택한 사용자의 MSISDN 등록 요청이 수신되면 DPA는 HTTP 상태 코드 403을 반환해야 합니다(MUST).

Monitoring API

일부 사용 사례에서는 GTAF가 DPA를 모니터링하고 DPA 실패를 감지해야 합니다. 이러한 사용 사례를 위해 모니터링 API가 정의되어 있습니다.

API 정의

모니터링 API는 다음 URL에서 HTTP GET 요청을 통해 사용할 수 있어야 합니다.

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를 주기적으로 폴링합니다. 'UNAVAILABLE' 응답을 기반으로 DPA 실패를 감지하면 운영자의 캐시를 지웁니다.

오류 케이스

오류가 발생한 경우 DPA는 다음 중 하나에 해당하는 HTTP 상태 코드를 반환해야 합니다.

  • 사용자가 현재 로밍 중이며 이 사용자에 대해 DPA 쿼리가 사용 중지되어 있습니다. DPA에서 403 오류를 반환합니다.
  • DPA는 GTAF에 사용자 키가 유효하지 않음 (즉, 존재하지 않는 사용자 키)을 나타내는 404 NOT_FOUND 오류 코드를 반환합니다.
  • DPA는 key_type = CPID이고 CPID가 만료된 경우 클라이언트가 새 사용자 키를 가져와야 함을 GTAF에 나타내는 410 GONE 오류 코드를 반환합니다.
  • DPA는 이 호출을 지원하지 않음을 나타내는 501 NOT_IMPLEMENTED 오류 코드를 반환합니다.
  • 서비스가 일시 중지되었습니다. DPA는 새 요청을 시도할 수 있는 시점을 나타내는 Retry-After 헤더와 함께 503 SERVICE UNAVAILABLE을 반환합니다.
  • DPA는 기타 지정되지 않은 오류에 대해 500 INTERNAL SERVER ERROR 오류 코드를 반환합니다.
  • DPA는 GTAF가 DPA에 너무 많은 요청을 보내고 있음을 나타내는 Retry-After 헤더와 함께 429 TOO_MANY_REQUESTS 오류를 반환합니다.
  • DPA는 DPA의 현재 상태와 충돌하므로 요청을 완료할 수 없음을 나타내는 409 CONFLICT 오류를 반환합니다.

모든 오류 사례에서 HTTP 응답 본문에는 오류에 관한 자세한 정보가 포함된 JSON 객체가 포함되어야 합니다(MUST). 오류 응답 본문에는 ErrorResponse 인스턴스가 포함되어야 합니다(MUST).

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

현재 정의된 cause 값은 ErrorCause API 참조의 일부로 나열됩니다.

그렇지 않으면 DPA는 200 OK를 반환합니다. 이러한 cause 값은 모든 대답에 사용됩니다.

다국어 지원

DPA에 대한 GTAF 요청에는 사람이 읽을 수 있는 문자열 (예: 요금제 설명)이 표시되어야 하는 언어를 나타내는 Accept-Language 헤더가 포함됩니다. 또한 DPA 응답 (PlanStatus, PlanOffers)에는 값이 BCP-47 언어 코드 (예: 'en-US')입니다.

DPA가 사용자가 요청한 언어를 지원하지 않는 경우 기본 언어를 사용하고 languageCode 필드를 사용하여 선택사항을 나타낼 수 있습니다.