Report: State of in-app subscriptions in the US 2023 Get a report

Android 인앱 구매, 5부: 서버 측 구매 검증

Vlad Guriev

Updated: 10월 14, 2023

4 min read

Content

62fdf199166de562699e813d jp android tutorial 1 configuration 4 4

서버측 (server-side)검증은구매 진위를 확인에 도움이 될 수 있습니다.기기는Google서버에요청하여 실제로 구매가 이루어졌는지와 구매가유효한지를 확인합니다.

이가이드에서는 Android앱에대한 서버 측 검증을 구성하는 방법에 대해 설명합니다.

구매를검증하는 이유

서버측 검증은 필수가 아니라는 점에 유의해야 합니다.인앱구매는 검증 없이도 이루어집니다.하지만다음과 같은 몇 가지 중요한 이점이 있습니다.

  1. 고급 결제 분석은 구독에 특히 중요한데, 활성화 후에 발생하는 모든 일을 장치에서 처리하지는 않기 때문입니다. 서버 측 구매 처리가 없으면, 현재 구독 상태를 검색할 수 없고, 사용자가 구독을 갱신 또는 취소했는지, 지불 문제가 있는지 등의 여부를 알 수 없습니다.
  2. 구매의 진위 여부를 확인할 수 있음. 거래가 사기가 아니고 사용자가 실제로 제품에 대한 비용을 지불했음을 확인할 수 있습니다.
  3. 플랫폼 간 구독. 사용자의 구독 상태를 실시간으로 확인할 수 있는 경우, 다른 플랫폼과 동기화할 수 있습니다. 예를 들어 iOS 기기에서 구독을 구매한 사용자는 Android, 웹 및 기타 플랫폼에서 구독을 사용할 수 있습니다.
  4. 서버 측에서 콘텐츠 접근을 제어할 수 있게 되어, 단순히 서버에 대한 요청을 실행하는 것만으로 구독 없이 데이터에 접근하려는 사용자로부터 보호합니다.

경험에따르면,첫번째 이점만으로도 서버 측 구매 처리를 설정하기에충분합니다.

결제검증

다음체계를 사용하여 Android결제검증을 요약할 수 있습니다.

616ecfda9345ee7e2b53d608 vkx4uyzcwdhqdwubf7srxr8us7k37emw9fybjgkduzdvuq6whxgsne4zn9bqt2g052sg2va6lgr0zi5wue22vnkls6wsql1mdozqnmrcrlk rb86shh7dag2fzdho gpavemctll3ds1600 4

GooglePlay 개발자API(API) 요청에대한 인증

GooglePlay 개발자API로작업하려면 먼저 요청에 서명할 키를 생성해야 합니다.먼저GooglePlay Console 계정(앱을관리하는 곳)을GoogleCloud 계정(요청서명을 위한 키를 생성할 곳)에연결해야 합니다.구성이완료되면,사용자에게구매 관리 권한을 부여해야 합니다.이프로세스를 설명하려면 기사 하나를 할애해야 합니다.다행히우리는 이미 Adapty문서의단계별 가이드에서 본 내용을 다뤘습니다.

일반적으로키를 생성한 후 작동을 시작하려면 24시간이상을 기다려야 합니다.기다리지않으려면,인앱상품 또는 구독에 대한 설명을 업데이트하기만 하면즉시 키가 활성화됩니다.

우리는GooglePlay 개발자API로작업하기 위해 공식 google-api-python-client라이브러리를사용할 것입니다.이라이브러리는 대부분의 인기 있는 언어에서 사용할수 있고 필요한 모든 메소드를 지원하기 때문에,사용을권장합니다.

구독거래에 대한 검증

Android에서는iOS서버측 검증과달리,구독및 기타 제품 검증 두 경우 모두 다양한 메소드를사용하여 구현됩니다.따라서거래를 검증할 때 제품을 처리하는 것인지 아니면구독을 처리하는 것인지 알아야 합니다.실제로이것은 모바일 앱에서 이 데이터를 전송해야 하고,토큰재검증이 필요한 경우를 대비하여 데이터베이스에플래그를 유지해야 함을 의미합니다.

두번째 중요한 차이점은 Android에서각 거래에는 고유한 토큰이 있는 반면,모든iOS 거래는앱별 공유 암호 (sharedsecret)를사용하여 전체 거래 내역을 저장한다는 것입니다.즉,어느때에든지 사용자의 구매를 복원하려면 임의의 단일토큰을 선택하는 것이 아니라,모든구매 토큰을 저장해야 합니다.

구독을검증하려면 purchases.subscriptions.get메소드를호출해야 합니다. 이것은기본적으로 GET요청호출입니다.

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}

모든매개변수가 필요합니다.

  • packageName: 앱 식별자, (예: com.adapty.sample_app).
  • subscriptionId: 검증 대상 구독의 구독 식별자, (예: com.adapty.sample_app.weekly_sub).
  • token: 고유 거래 토큰. 모바일 앱 측에서 구매가 처리되면 나타납니다.

우선,모두의도한 대로 작동하는지 확인하기 위해 처리해야 하는오류 메시지를 살펴봅시다.

  • 400, Invalid grant: account not found: 이 오류 메시지는 요청 인증 키가 잘못 생성되었음을 의미합니다. 계정이 연결되어 있고, 충분한 권한이 있는 올바른 계정을 사용하고 있으며, 필요한 모든 API가 활성화되어 있는지 확인하십시오. 모든 것을 구성하는 방법에 대한 가이드는 아래 섹션을 참조하세요. 제품 설명 업데이트에 대한 팁을 참고하세요.
  • 400, The purchase token does not match the package name: 이 오류 메시지는 일반적으로 사기 거래에서 나타납니다. 테스트 중 보게 된다면, 다른 앱에 속한 앱 구매 토큰을 사용하고 있지는 않은지 확인하세요.
  • 403, Quota exceeded for quota metric ‘Queries’ and limit ‘Queries per day’ of service ‘androidpublisher.googleapis.com’: 이것은 Google API 요청 일일 할당량이 초과되었음을 의미합니다. 기본적으로, 하루에 최대 200,000 요청을 실행할 수 있습니다. 할당량을 늘릴 수 있지만, 대부분의 앱에는 기본 할당량으로 충분합니다. 이 제한에 도달하면, 앱의 논리를 다시 점검하고 모든 것이 올바른지 확인해야 합니다.
  • 410, The subscription purchase is no longer available for query because it has been expired for too long: 이 오류 메시지는 구독이 60일이나 그 전에 만료된 거래에 나타납니다. 실제 오류 메시지가 아니기 때문에 오류로 처리해서는 안 됩니다.

구독거래

검증에성공하면 응답으로 거래데이터를받게 됩니다.

거래데이터 (구독용):

{     "expiryTimeMillis": "1631116261362",     "paymentState": 1,     "acknowledgementState": 1,     "kind": "androidpublisher#subscriptionPurchase",     "orderId": "GPA.3382-9215-9042-70164",     "startTimeMillis": "1630504367892",     "autoRenewing": true,     "priceCurrencyCode": "USD",     "priceAmountMicros": "1990000",     "countryCode": "US",     "developerPayload": "" }

사용자가앱에서 제공하는 프리미엄 옵션에 접근할 수 있는지,즉활성 구독이 있는지 여부를 이해하려면 다음을 수행해야합니다.

  1. startTimeMillis 그리고 expiryTimeMillis 매개변수를 확인하십시오. 현재 시간은 그 사이에 있어야 합니다.
  2. 그에 더해, paymentState 매개변수에 ‘0’ 값이 없는지 반드시 확인하십시오. 이는 구독 구매가 아직 보류 중임을 의미하므로, 사용자에게 프리미엄 기능 접근 권한을 아직 부여할 필요가 없습니다.
  3. 거래에 autoResumeTimeMillis 속성이 있는 경우, 구독은 일시 중지됩니다. 이는 사용자에게 프리미엄 기능 접근 권한을 지정된 날짜 이전에 부여해서는 안 됨을 의미합니다.

구독거래의 주요 속성을 살펴봅시다.

  • kind: 거래 유형. 구독의 경우, 항상 androidpublisher#subscriptionPurchase 값을 갖습니다. 이 매개변수를 통해, 구독을 처리하는지 또는 제품을 처리하는지 이해하고, 그에 맞는 처리 논리를 선택할 수 있습니다.
  • paymentState: 지불 상태. 만료된 거래에는 이 속성이 없습니다. 가능한 값은 다음과 같습니다.
    0: 이 구매는 아직 처리되지 않았습니다. 일부 국가에서는 사용자가 현장에서 구독료를 지불할 수 있습니다. 즉, 사용자는 자신의 장치에서 구독 구매를 시작하고 가까운 터미널에서 요금을 지불합니다. 전반적으로 매우 드문 경우이지만, 그래도 염두에 두어야 합니다.
    1: 구독을 구매했습니다.
    2: 구독은 평가판 (trial) 기간입니다.
    3: 구독은 다음 기간에 업그레이드 또는 다운그레이드됩니다. 이는 구독 요금제가 변경되는 것을 의미합니다.
  • acknowledgementState: 구매 확정 상태. 사용자가 지불한 것에 대한 접근 권한을 받았는지 여부를 승인하는 중요한 매개변수입니다. 값 ‘0’은 권한을 받지 않았음을, ‘1’은 받았음을 뜻합니다. 개발자는 이 상태를 정의할 책임이 있는데, 모바일 앱과 서버 측 모두에서 수행할 수 있습니다. 구매 시점으로부터 3일 이내에 승인하지 않으면, 자동으로 환불됩니다. 다음 논리를 구현하는 것이 좋습니다. acknowledgementState=0을 포함하는 거래를 받으면, 매개변수가 서버에 의해 변경됩니다. 그 방법은 아래에서 알려드리겠습니다.
  • orderId: 고유한 거래 식별자. 각 구독 구매 또는 갱신에는 고유한 식별자가 있어서, 이 거래가 이미 이전에 처리되었는지 여부를 확인하는 데 사용할 수 있습니다. 각 갱신 식별자에는 반복되는 초반부가 있는데, 여기에 두 개의 점과 (0부터 시작하는) 구독 갱신 횟수가 덧붙여집니다. 활성화될 때 구독에 GPA.3382-9215-9042-70164 식별자가 있는 경우, 첫 번째 갱신은 GPA.3382-9215-9042-70164..0으로 식별되고 두 번째 갱신은 GPA.3382-9215-9042-70164..1로 식별되는 식입니다. 이 방법으로 거래 체인을 구축하고 갱신 횟수를 추적할 수 있습니다.
  • startTimeMillis: 구독 시작 날짜.
  • expiryTimeMillis: 구독 만료 날짜.
  • autoRenewing: 구독을 다음 기간으로 갱신할지 여부를 나타내는 플래그.
  • priceCurrencyCode: 세 글자 형식으로 나타내는 구매 통화, (예: USD).
  • priceAmountMicros: 구매 가격. 정상적인 가격 값을 얻으려면 이 값을 1000000으로 나눕니다. 즉, 1990000은 실제로 1.99를 의미합니다.
  • countryCode: 두 글자 형식으로 나타내는 구매 국가, (예: 미국).
  • purchaseType: 구매 유형. 이 키는 대부분의 경우에 존재하지 않습니다. 샌드박스 (Sandbox) 환경에서 구매했는지 여부를 이해하는 데 도움이 되기 때문에, 여전히 고려하는 것이 중요합니다. 가능한 값은 다음과 같습니다.
    0: 샌드박스 환경에서 구매하였으므로, 분석 데이터에 포함되어서는 안 됩니다.
    1: 프로모션 코드로 구매하였습니다.
  • autoResumeTimeMillis: 구독 갱신 날짜. 이전에 일시 중지된 구독에만 표시됩니다. 이 매개변수가 보이면, 사용자에게 프리미엄 기능 접근 권한을 지정된 날짜 이전에 부여할 필요가 없습니다.
  • cancelReason: 구독이 갱신되지 않는 이유. 가능한 값은 다음과 같습니다.
    0: 사용자가 구독 자동 갱신을 취소했습니다.
    1: 시스템에서 구독을 취소했습니다. 이것은 대부분 결제 문제로 인해 발생합니다.
    2: 사용자가 다른 구독 요금제로 전환했습니다.
    3: 개발자가 구독을 취소했습니다.
  • userCancellationTimeMillis: 구독 갱신 취소 데이터. cancelReason이 0인 경우에만 나타납니다. 구독은 여전히 활성 상태일 수 있습니다. 확인하려면 expiryTimeMillis 매개변수의 값을 참조하세요.
  • cancelSurveyResult: 구독 취소 사유를 저장하는 객체로, 사용자가 이 문제에 대해 피드백을 남겼을 때 표시됨.
  • introductoryPriceInfo: 출시 기념가 데이터를 저장하는 객체. 예를 들어, 이것은 50% 할인된 1개월의 특별가일 수 있습니다.
  • promotionType: 구독 활성화에 사용된 프로모션 코드 유형. 가능한 값은 다음과 같습니다.
    0: 일회성 프로모션 코드.
    1: 여러 고객이 적용할 수 있는 맞춤 프로모션 코드. 이러한 코드는 일반적으로 블로거 파트너십에 사용됩니다.
  • promotionCode: 구독을 활성화에 사용된 맞춤 프로모션 코드. 일회성 프로모션 코드에는 이 매개변수가 없습니다.
  • priceChange: 향후 가격 변경 데이터 및 사용자가 이에 동의했는지 여부를 저장하는 객체.

구독승인

위에서이미 언급했듯이,구매후 3일이내 구독이 승인되지 않으면 자동으로 취소 및환불됩니다..솔직히말해서,왜이렇게 해야 하는지 이해하기가 어려운데,iOS를포함한 다른 결제 처리 시스템에서는 이런 것을 본적이 없습니다.하지만acknowledgementState=0을포함하는 거래를 수신하는 경우,귀하는구독을 승인해야 합니다.

이렇게하려면 purchases.subscriptions.acknowledge메소드를호출해야 합니다.이메소드는 POST요청을실행합니다

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscriptionId}/tokens/{token}:acknowledge

매개변수는요청 검증과 동일합니다.요청이성공적으로 실행되면 구독이 승인되므로,돈을붙잡을 수 있습니다.

구독이아직 완전히 구매되지 않은 경우 승인할 필요가 없습니다.

구독갱신 취소 (Subscriptionrenewal cancellation), 철회(revocation),환불(refund)및연기 (deferral)

구독인증 및 승인 외의 다른 구독 작업에도 GooglePlay 개발자API를사용할 수 있습니다.이는매우 드물며,갱신을제외하고는 GooglePlay Console에서지원한다는 점에 유의해야 합니다.하지만API 솔루션범위에 대한 일반적인 이해를 돕기 위해 나열하겠습니다.이러한모든 요청은 앞에서 언급한 메소드 즉,패키지packageName,subscriptionId,그리고token과동일한 매개변수를 필요로 합니다.

  • 갱신 취소 (Renewal cancellation). purchases.subscriptions.cancel 메소드. 선택한 구독에 대한 자동 갱신을 취소합니다. 그러나 구독은 현재 결제 기간 동안 계속 사용할 수 있습니다.
  • 구독 환불 (Subscription refund). purchases.subscriptions.refund 메소드. 구독을 환불합니다. 그러나 사용자는 구독 접근 권한을 계속 유지하고, 다음 기간에 자동으로 갱신됩니다. 대부분의 경우, 환불 처리 시 구독도 취소해야 합니다.
  • 구독 철회 (Subscription revocation). purchases.subscriptions.revoke 메소드. 즉시 구독을 취소하므로, 사용자는 프리미엄 기능에 접근할 수 없습니다. 구독은 갱신되지 않습니다. 이 메소드는 일반적으로 환불 처리와 함께 호출됩니다.
  • 구독 구매 연기 (Subscription purchase deferral). purchases.subscriptions.defer 메소드. 지정된 날짜까지 구독을 연장합니다. 요청에서 구독 만료 날짜와 대체할 날짜를 지정합니다. 후자는 전자보다 구독 기간이 길어야 합니다.

제품(구독아님)검증

제품검증은 구독 검증과 유사합니다.GET 요청을실행하기 위해 purchases.products.get메소드를호출해야 합니다.

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}

위에서설명한 예를 보면,이러한모든 매개변수에 이미 익숙할 것입니다.

거래데이터 (제품용):

{   "purchaseTimeMillis": "1630529397125",   "purchaseState": 0,   "consumptionState": 0,   "developerPayload": "",   "orderId": "GPA.3374-2691-3583-90384",   "acknowledgementState": 1,   "kind": "androidpublisher#productPurchase",   "regionCode": "RU" }

제품거래는구독 거래보다 훨씬 적은 수의 속성을 포함합니다.몇가지 중요한 속성을 살펴봅시다.

  • kind: 거래 유형. 제품에서는 항상 androidpublisher#productPurchase 값을 가집니다. 이 매개변수를 통해, 구독을 처리하는지 또는 제품을 처리하는지 이해하고, 그에 맞는 처리 논리를 선택할 수 있습니다.
  • purchaseState: 지불 상태. 여기의 키 값은 구독에 대한 paymentState  매개변수와 다르다는 것에 주의하시기 바랍니다. 가능한 값은 다음과 같습니다.
    0: 구매가 완료되었습니다.
    1: 구매가 취소되었습니다. 이는 구매가 보류 중이었으나, 사용자가 지불하지 않았음을 의미합니다.
    2: 구매가 보류 중입니다. 일부 국가에서는 사용자가 현장에서 구독료를 지불할 수 있습니다. 즉, 사용자는 자신의 장치에서 구독 구매를 시작하고 가까운 터미널에서 요금을 지불합니다. 전반적으로 매우 드문 경우이지만, 그래도 염두에 두어야 합니다
  • acknowledgementState: 구매 확정 상태. 사용자가 지불한 것에 대한 접근 권한을 받았는지 여부를 승인하는 중요한 매개변수입니다. 값 ‘0’은 권한을 받지 않았음을, ‘1’은 받았음을 뜻합니다. 개발자는 이 상태를 정의할 책임이 있는데, 모바일 앱과 서버 측 모두에서 수행할 수 있습니다. 구매 시점으로부터 3일 이내에 승인하지 않으면, 자동으로 환불됩니다. 다음 논리를 구현하는 것이 좋습니다. acknowledgementState=0을 포함하는 거래를 받으면, 매개변수가 서버에 의해 변경됩니다. 그 방법은 아래에서 알려드리겠습니다.
  • consumptionState: 제품 소비 상태. 이것이 iOS에서 ‘소모품’이라고 부르는 것입니다. 모바일 앱 측에서 정의됩니다. 값이 ‘0’이면 제품이 소비되지 않았음을 의미합니다. 만약 ‘1’이면 소비된 것입니다. 앱 또는 일부 특정 프리미엄 기능에 대한 평생 (lifetime) 접근 권한을 판매하는 경우, 이러한 제품은 소비되어서는 안 됩니다. 즉, 상태가 0이어야 합니다. 사용자가 몇 번이고 다시 살 수 있는 코인을 판매하는 경우, 해당 제품은 소비되어야 합니다. 즉, 상태가 1이어야 합니다. consumptionState=0은 제품을 한 번만 구입할 수 있음을 의미하지만, consumptionState=1은 여러 번 구매할 수 있음을 의미합니다.
  • orderId: 고유한 거래 식별자. 각 구독 구매 또는 갱신에는 고유한 식별자가 있어서, 이 거래가 이미 이전에 처리되었는지 여부를 확인하는 데 사용할 수 있습니다.
  • purchaseTimeMillis: 구입 일자.
  • regionCode: 두 글자 형식으로 나타내는 구매 국가, (예: 미국). 이 매개변수의 이름은 구독에서는 countryCode라고 이름이 붙여져 있습니다.
  • purchaseType: 구매 유형. 이 키는 대부분의 경우에 존재하지 않습니다. 샌드박스 (Sandbox) 환경에서 구매했는지 여부를 이해하는 데 도움이 되기 때문에, 여전히 고려하는 것이 중요합니다. 가능한 값은 다음과 같습니다.
    0: 샌드박스 환경에서 구매하였으므로 분석 데이터에 포함되어서는 안됩니다.
    1: 프로모션 코드로 구매하였습니다.
    ‍2: 타겟 액션으로 구매하는 것이 승인되었는데, 예를 들면, 결제 대신 인앱 광고를 보는 것 등입니다.

보시다시피,제품검증은 구독 검증과 매우 유사합니다.하지만다음과 같은 몇 가지 사항에 유의해야 합니다.

  • 분석에는 매우 유용하겠지만, 가격은 반환되지 않습니다.
  • purchaseState 매개변수 값은 구독에서 나타나는 paymentState 매개변수 값과 매우 다릅니다. 보고하지 않으면 버그가 발생합니다.
  • 구독에 대해 countryCode로 이름이 붙여진 경우에도 regionCode는 반환됩니다.

구독구매와 마찬가지로,제품구매도 승인해야 합니다.이렇게하려면 POST요청을실행할 purchases.products.acknowledge메소드를호출하십시오

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/products/{productId}/tokens/{token}:acknowledge

구매가아직 완료되지 않은 경우,승인할필요가 없습니다.

구독및 제품에 대한 환불 추적

환불을보고하지 않고서는 고품질 분석이 불가능합니다.안타깝게도iOS에서와는달리,환불데이터가 거래에 존재하지 않고 별도의 이벤트로메시지가 표시되지도 않습니다.환불된거래 목록을 받으려면 정기적으로,예를들자면 하루에 한 번 purchases.voidedpurchases.list를호출해야 합니다.이메소드는 GET요청을실행합니다:

https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/voidedpurchases

요청에대한 응답으로 모든 환불된 거래목록을 받게 됩니다.데이터베이스에서purchaseToken매개변수와는상반되게,orderId매개변수로거래를 검색하는 것을 추천합니다.첫째,시간이덜 걸립니다.둘째,모든구독 갱신은 동일한 토큰을 공유하며,가장최근의 토큰만 가져오면 되기 때문입니다.

Subscribe to Adapty newsletter

Get fresh paywall ideas, subscription insights, and mobile app news every month!

거래에대한 서버 알림 (Servernotifications)

서버알림(실시간개발자 알림)은Google 측과귀하의 서버 상에서 발생한 이벤트에 대해 거의 실시간으로알 수 있게 해줍니다.구성이완료되면 새로운 구매,갱신,결제문제 등에 대한 알림을 받게 됩니다.이를통해 더 나은 분석을 수집하고 구독자 상태를 훨씬쉽게 관리할 수 있습니다.

서버알림 수신을 시작하려면,Google Cloud Pub/Sub 주제를생성하여 원하는 주소로 알림을 보내게 해야 합니다.그러면이 주제가 GooglePlay Console의수익 창출 설정 섹션에 표시되어야 합니다.스크린샷이포함된 자세한 가이드는 Adapty문서를참조하세요.

서버알림:

{   "message": {     "data": "eyJ2ZXJzaW9uIjoiMS4wIiwicGFja2FnZU5hbWUiOiJjb20uYWRhcHR5LnNhbXBsZV9hcHAiLCJldmVudFRpbWVNaWxsaXMiOiIxNjMwNTI5Mzk3MTI1Iiwic3Vic2NyaXB0aW9uTm90aWZpY2F0aW9uIjp7InZlcnNpb24iOiIxLjAiLCJub3RpZmljYXRpb25UeXBlIjo2LCJwdXJjaGFzZVRva2VuIjoiY2o3anAuQU8tSjFPelIxMjMiLCJzdWJzY3JpcHRpb25JZCI6ImNvbS5hZGFwdHkuc2FtcGxlX2FwcC53ZWVrbHlfc3ViIn19",     "messageId": "2829603729517390",     "message_id": "2829603729517390",     "publishTime": "2021-09-01T20:49:59.124Z",     "publish_time": "2021-08-04T20:49:59.124Z"   },   "subscription": "projects/935083/subscriptions/adapty-rtdn" }

우리는주로 base64로인코딩된 거래 데이터를 포함하는 data키를봐야 합니다.messageId키는메시지 중복 제거에 사용할 수 있으므로,중복메시지를 처리할 필요가 없습니다.

다음은서버 알림의 거래입니다.

{   "version": "1.0",   "packageName": "com.adapty.sample_app",   "eventTimeMillis": "1630529397125",   "subscriptionNotification": {     "version": "1.0",     "notificationType": 6,     "purchaseToken": "cj7jp.AO-J1OzR123",     "subscriptionId": "com.adapty.sample_app.weekly_sub"   } }

packageName키는해당 이벤트가 속한 앱이 무엇인지 알 수 있게 해줍니다.subscriptionId키는관련된 구독을 알려주고,purchaseToken은특정 거래를 찾는 데 도움이 됩니다.구독의경우에는 항상 갱신 체인의 마지막 거래를 찾게 되는데,해당이벤트가 속할 거래이기 때문입니다.notificationType키는이벤트유형을포함합니다.구독에는다음에 나오는 내용이 가장 편리하다고 생각합니다.

  • (2) SUBSCRIPTION_RENEWED: 구독이 성공적으로 갱신되었습니다.
  • (3) SUBSCRIPTION_CANCELED: 사용자가 구독 자동 갱신을 비활성화했습니다. 자동 갱신이 비활성화된 경우, 사용자를 활성 구독자로 되돌려야 합니다.
  • (5) SUBSCRIPTION_ON_HOLD, (6) SUBSCRIPTION_IN_GRACE_PERIOD: 결제 문제로 인해 구독을 갱신할 수 없습니다. 구독이 자동으로 취소되지 않도록 사용자에게 알려야 합니다.
  • (12) SUBSCRIPTION_REVOKED: 구독이 취소되었습니다. 이는 사용자가 이전에 구독에서 부여된 프리미엄 기능에 대한 접근 권한을 상실해야 함을 의미합니다.

제품(구독아님)에서subscriptionNotification키대신 oneTimeProductNotification을받게 됩니다.또한여기에는 subscriptionId키대신 sku키가포함됩니다.게다가,제품에대한 오직 2개의이벤트유형만을받게 될 것입니다

  • (1) ONE_TIME_PRODUCT_PURCHASED: 성공적인 제품 구매.
  • (2) ONE_TIME_PRODUCT_CANCELED: 사용자가 비용을 지불하지 않았기 때문에 제품 구매가 취소되었습니다.

결론

서버측 검증은 앱에 대해 수집할 수 있는 분석을 더욱강화합니다.사기꾼이프리미엄 콘텐츠에 접근하는 것을 더 어렵게 만들고,플랫폼간 구독 구현에 사용할 수 있습니다.그러나,특히높은 데이터 정확도가 필수인 경우,서버측 검증 구현에는 상당한 시간이 걸릴 수 있습니다.고품질데이터를 제공하려면,구독업그레이드,구독크로스그레이드,평가판기간,프로모션및 출시 할인가,유예기간,환불등과 같은 다양한 부수적인 경우를 고려해야 합니다.또한Google이1년이상 갱신되는 구독에 대해 (30%가아니라)15%의수수료만 청구하는 것과 같은 모든 정책 세부사항을알고 고려해야 합니다.