데이터 요금제 에이전트 API

동기

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

인증

GTAF가 전화를 걸려면 먼저 DPA가 GTAF를 인증해야 합니다. 연산자 온보딩 프로세스의 일부로 DPA SSL 인증서의 유효성이 확인됩니다. 현재 상호 인증에 OAuth2를 사용해야 합니다.

API 설명

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

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

이 문서의 나머지 부분에서는 각 API 구성요소를 자세히 설명합니다. 명시적으로 언급되지 않는 한, 모든 통신은 HTTPS를 통해 이루어져야 합니다 (유효한 DPA SSL 인증서 사용). 지원되는 실제 기능에 따라, 연산자는 이러한 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 헤더가 포함되어야 합니다.

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

각 계획 모듈에는 여러 계획 모듈 트래픽 카테고리 (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 요금제만 표시됩니다. GTAF는 혜택을 쿼리하는 애플리케이션이 Google Play 서비스의 일부인 모바일 데이터 요금제 UI인 경우에만 최대 10개의 요금제만 공유합니다. 이는 Google Play 서비스 사용자에게 만족스러운 환경을 제공하기 위해서입니다.

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

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

데이터 구매

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

거래 요청

클라이언트에서 요청을 받으면 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는 GTAF에 구매한 요금제 ID가 유효하지 않음을 나타내는 400 BAD REQUEST 오류 코드를 반환합니다.
  • DPA는 사용자에게 구매를 완료하기에 충분한 잔액이 없음을 GTAF에 알리는 402 결제 필요 오류 코드를 반환합니다.
  • DPA는 구매하려는 요금제가 사용자의 현재 제품 조합과 호환되지 않음을 알려주는 409 CONFLICT 오류 코드를 GTAF에 반환합니다. 예를 들어 이동통신사 데이터 요금제 정책에서 후불 요금제와 선불 요금제를 혼합할 수 없는 경우 후불 사용자의 선불 요금제를 구매하려고 하면 409 CONFLICT 오류가 발생합니다.
  • DPA는 현재 거래가 이전에 발행된 거래와 중복된다는 것을 나타내는 403 FORBIDDEN 오류 코드를 반환합니다. DPA는 이에 대한 응답으로 다음 오류 원인을 반환해야 합니다(SHOULD).
    • 이전 트랜잭션이 실패였으면 오류 이유가 실패 원인입니다.
    • 이전 트랜잭션이 성공했다면 DUPLICATE_TRANSACTION합니다.
    • 이전 트랜잭션이 아직 큐에 있는 경우 REQUEST_QUEUED입니다.

DPA SHALL은 성공적으로 실행된 트랜잭션이나 큐에 추가된 트랜잭션에 대해서만 200-OK 응답을 생성합니다. 큐에 추가된 트랜잭션의 경우 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는 요금제가 활성화되었다고 가정합니다.

GTAF는 사용자 동의 환경설정을 이동통신사에 전달하기 위해 다음 요청을 실행할 수 있습니다(MAY).

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

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

요청이 성공하면 응답 본문이 비어 있어야 합니다.

자격요건

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

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

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

오류가 발생하면 DPA SHALL은 일반적인 오류 원인을 반환합니다. 또한 DPA SHALL은 다음과 같은 경우 오류를 반환합니다.

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

그렇지 않으면 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 오류를 반환해야 합니다(MUST).

MSISDN 등록 엔드포인트

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

POST DPA_URL/등록

요청 본문은 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 정의

Monitoring 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를 폴링합니다. DPA 장애가 감지되면(‘UNAVAILABLE’ 응답에 기반) 연산자의 캐시를 지웁니다.

오류 사례

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

  • 사용자가 로밍 중이며 이 사용자에 대한 DPA 쿼리가 사용 중지되었습니다. DPA는 403 오류를 반환합니다.
  • DPA는 사용자 키가 유효하지 않음 (예: 존재하지 않는 사용자 키)을 나타내는 404 NOT_FOUND 오류 코드를 GTAF에 반환합니다.
  • DPA는 key_type = CPID 및 CPID가 만료된 경우 클라이언트가 새 사용자 키를 얻어야 함을 나타내는 410 GONE 오류 코드를 반환합니다.
  • DPA는 이 호출을 지원하지 않음을 나타내는 501 NOT_IMPLEMENTED 오류 코드를 반환합니다.
  • 서비스가 일시 중지되었습니다. DPA는 새로운 요청을 시도할 수 있음을 나타내는 Retry-After 헤더와 함께 503 서비스를 사용할 수 없도록 반환합니다.
  • DPA는 지정되지 않은 다른 모든 오류에 대해 500 INTERNAL SERVER ERROR 오류 코드를 반환합니다.
  • DPA는 GTAF가 DPA에 너무 많은 요청을 하고 있음을 알리는 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 언어 코드인 필수 languageCode 필드가 있습니다 (예: '-미국').

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