정기 결제 수명 주기

정기 결제 구매는 자동 갱신 동작, 결제 거부 상황, 개발자 관리 작업 등 다양한 요소에 따라 수명 주기 중에 여러 상태를 거칠 수 있습니다.

자동 갱신 정기 결제 수명 주기 처리

사용자의 정기 결제 상태가 변경되면 백엔드 서버는 SubscriptionNotification 메시지를 수신합니다.

그림 1. 자동 갱신 정기 결제 구매의 수명 주기 상태 및 전환 이벤트

백엔드에서 상태를 업데이트하려면 알림에 포함된 구매 토큰을 사용하여 purchases.subscriptionsv2.get API를 호출합니다. 이 엔드포인트는 구매 토큰의 최신 정기 결제 상태를 제공하며 정기 결제 관리를 위한 정보 소스로 간주됩니다.

구매 토큰은 정기 결제 가입부터 만료일 이후 60일까지 유효합니다. 이 날짜 이후에는 구매 토큰으로 더 이상 Google Play Developer API를 호출할 수 없습니다.

새로운 자동 갱신 정기 결제 구매

사용자가 정기 결제를 구매하면 SUBSCRIPTION_PURCHASED 유형의 SubscriptionNotification 메시지가 RTDN 클라이언트로 전송됩니다. 이 알림을 수신했든, 아니면 앱 내에서 PurchasesUpdatedListener를 사용하거나 앱의 onResume() 메서드에서 수동으로 구매를 가져와서 새 구매를 등록했든, 새로운 구매를 보안 백엔드에서 처리해야 합니다. 이를 위해서는 다음 단계를 따르세요.

  1. purchases.subscriptionsv2.get 엔드포인트를 쿼리하여 최신 정기 결제 상태를 포함하는 정기 결제 리소스를 가져옵니다.
  2. subscriptionState 필드의 값이 SUBSCRIPTION_STATE_ACTIVE여야 합니다.
  3. 구매를 인증합니다.
  4. 사용자에게 콘텐츠 액세스 권한을 부여합니다. 구매와 연결된 사용자 계정은 구매 시점에 setObfuscatedAccountIdsetObfuscatedProfileId를 사용하여 식별자가 설정된 경우 정기 결제 리소스의 ExternalAccountIdentifiers 객체로 식별할 수 있습니다.

Play 결제 라이브러리에는 정기 결제를 확인하는 메서드인 acknowledgePurchase()와 확인 상태를 검사하는 메서드인 isAcknowledged()도 있습니다. 단, 보안을 강화하기 위해 구매 처리를 백엔드에서 처리하는 것이 권장됩니다.

새로운 구매의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_PENDING", // need to acknowledge new purchases
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

요금제 갱신

할부되지 않는 자동 갱신 정기 결제의 경우 정기 결제가 갱신될 때 SUBSCRIPTION_RENEWED 알림이 전송됩니다. 할부 정기 결제의 경우 결제일에 정기 결제 요금이 청구될 때마다 SUBSCRIPTION_RENEWED 알림이 전송됩니다. 사용자에게 여전히 정기 결제 콘텐츠 사용 자격이 있는지 확인한 후 Google Play Developer API에서 반환된 정기 결제 리소스의 새 expiryTime로 정기 결제 상태를 업데이트해야 합니다. 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ]
}

정기 결제 갱신을 확인할 필요는 없습니다.

유예 기간

정기 결제 갱신에 결제 문제가 있으면 Google은 사용자에게 이 사실을 알리고 정기 결제가 만료되기 전에 일정 기간 정기 결제 갱신을 주기적으로 시도합니다. 이 복구 기간은 유예 기간과 그 이후의 계정 보류 기간으로 구성될 수 있습니다. 유예 기간 중에도 사용자가 계속해서 정기 결제 사용 권한을 이용할 수 있어야 합니다.

queryPurchasesAsync() 메서드는 유예 기간 상태에 있는 구매를 계속해서 반환합니다. 앱이 queryPurchasesAsync만 사용하여 사용자에게 정기 결제 자격이 있는지 확인한다면 이러한 정기 결제는 Play 결제 라이브러리를 통해 활성 상태로 표시되므로 앱에서 자동으로 유예 기간을 처리해야 합니다.

정기 결제 상태를 백엔드와 동기화하면 결제 거부를 더 잘 파악하고 비자발적 이탈을 줄이려고 시도할 때 더 많은 컨텍스트를 확인할 수 있습니다. 사용자가 유예 기간에 진입하면 알림을 받을 수 있도록, 유형이 SUBSCRIPTION_IN_GRACE_PERIODSubscriptionNotification 메시지를 수신 대기하세요. 사용자가 유예 기간 상태에 있는 동안 정기 결제 리소스에는 autoRenewEnabled = true가 포함됩니다. 사용 권한은 사용자가 정기 결제를 취소하거나 유예 기간의 최대 길이에 도달할 때까지 지속되어야 하므로, Google Play는 유예 기간이 만료될 때까지 expiryTime 값을 동적으로 연장합니다. 이 기간 동안 subscriptionState 필드의 값은 SUBSCRIPTION_STATE_IN_GRACE_PERIOD입니다. 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_IN_GRACE_PERIOD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

Play에서는 유예 기간 상태에 있는 사용자에게 결제가 거부되었음을 알리고 Play 스토어에서 결제 수단을 수정하라는 메시지를 표시합니다. 사용자가 유예 기간 상태로 전환된 경우, 이 문제가 비자발적인 문제일 수 있으므로 앱에서도 사용자에게 결제 수단을 수정하라는 메시지를 표시해야 합니다. 이렇게 하는 간단한 방법은 In-App Messaging API를 사용하는 것입니다. 사용자가 앱을 열었을 때 이 API를 호출하면 임시 스낵바에 결제가 거부되었음을 알리는 Play 메시지가 표시됩니다. 이 메시지에는 사용자가 Google Play에서 결제 수단을 수정할 수 있는 딥 링크도 포함됩니다.

사용자가 결제 수단을 수정하는 즉시 정기 결제가 원래 갱신일로 갱신되며 개발자는 갱신에 설명된 대로 갱신을 처리할 수 있습니다.

사용자가 유예 기간 중에 결제 수단을 수정하지 않으면 정기 결제가 계정 보류 상태로 전환되고 사용자가 사용 권한을 잃게 됩니다.

유예 기간 액세스 및 복구

그림 2는 유예 기간 상태로 전환되었다가 사용자가 결제 수단을 수정하면 복구되는 정기 결제의 타임라인입니다. 유예 기간이 종료되면 사용자는 정기 결제 혜택을 잃게 되며 계정 보류 상태로 전환됩니다.

그림 2. 유예 기간 상태로 전환되었다가 유예 기간이 종료되기 전에 복구되는 정기 결제의 타임라인

다음 사항을 기억해야 합니다.

  • 유예 기간 동안 사용자는 정기 결제 혜택을 계속 이용할 수 있어야 합니다.
  • 유예 기간 동안 정기 결제가 복구되는 경우 갱신일은 초기화되지 않습니다.
  • 유예 기간을 7일에서 14일로 늘리면 유예 기간 상태에 있는 사용자는 연장된 정기 결제 혜택을 이용할 수 있습니다.
  • 유예 기간을 줄이면 새 유예 기간을 초과할 정도로 이전 유예 기간에 충분히 도달한 사용자는 정기 결제 혜택이 즉시 취소됩니다. 예를 들어 유예 기간을 14일에서 7일로 줄이면 이전 유예 기간의 8~14일 차에 있는 사용자는 정기 결제 혜택이 즉시 취소됩니다.
  • 정기 결제는 활성 상태로 유지되며 무음 유예 기간이 끝날 때까지 유예 기간 RTDN이 전송되지 않습니다.

자동 유예 기간

유예 기간을 0일로 설정할 수 있지만 Play에서는 결제 재시도를 위한 충분한 시간을 확보하기 위해 최소 1일을 기다립니다. 이 자동 유예 기간은 결제 처리를 위한 안전망을 제공합니다. 이 24시간 동안 정기 결제는 ACTIVE 상태로 유지됩니다.

정기 결제 상태 변경사항과 동기화 상태를 유지하는 가장 좋은 방법은 실시간 개발자 알림(RTDN)을 수신 대기하고 이에 반응하는 것입니다. 만료 시간 대신 RTDN 시간에 purchases.subscriptionsv2.get() 메서드를 호출하여 더 정확한 정기 결제 상태를 가져옵니다.

24시간 자동 유예 기간 후의 정기 결제 상태에 따라 다음 알림 중 하나가 수신됩니다.

  • SUBSCRIPTION_ON_HOLD(사용 설정된 경우)
  • SUBSCRIPTION_CANCELED(취소된 경우)
  • SUBSCRIPTION_EXPIRED(만료된 경우)
  • SUBSCRIPTION_RENEWED(갱신이 완료된 경우)

24시간의 자동 유예 기간이 지난 후 언제든지 subscriptionV2.get() 메서드를 호출하여 정기 결제의 최신 상태를 가져올 수도 있습니다.

계정 보류

정기 결제 갱신에 결제 문제가 있는 경우 유예 기간이 종료되면 계정 보류 기간이 시작됩니다. 정기 결제의 계정 보류 기간이 시작되면 사용자가 정기 결제 사용 권한을 이용할 수 없어야 합니다.

계정 보류 중에는 사용자가 정기 결제를 취소, 복원 또는 재구매할 수 있으므로 필요에 따라 정기 결제의 취소, 복원 또는 재구매를 처리해야 합니다.

사용자의 계정 보류 기간이 시작되면 사용자에게 정기 결제에 대한 액세스가 정지된 이유를 가능한 한 빨리 알릴 수 있도록 RTDN에서 알림이 전송됩니다. 사용자에게 알리는 간단한 방법은 In-App Messaging API를 사용하는 것입니다. 사용자가 앱을 열었을 때 이 API를 호출하면 임시 스낵바에 결제가 거부되었음을 알리는 메시지가 표시됩니다. 이 메시지에는 사용자가 Google Play에서 결제 수단을 수정할 수 있는 딥 링크도 포함됩니다.

사용자가 앱 외부의 정기 결제 콘텐츠에 액세스할 수 있는 경우 여러 표시 경로에서 액세스할 수 없게 된 것을 알게 될 수 있습니다. 사용자에게 푸시 알림이나 이메일을 보내 결제 거부로 인해 정기 결제가 더 이상 활성 상태가 아님을 알릴 수 있습니다.

정기 결제는 계정 보류 중에 queryPurchasesAsync() 메서드에 의해 반환되지 않으므로 앱에서 이 메서드를 사용하여 기존 구매를 표시하는 경우 기본적으로 계정 보류를 지원해야 합니다.

실시간 개발자 알림을 사용하면 정기 결제가 계정 보류 상태가 될 때 SUBSCRIPTION_ON_HOLD 유형의 SubscriptionNotification을 수신합니다. 보안 백엔드 서버에서 purchases.subscriptionsv2.get 메서드를 호출하여 새로운 정기 결제 정보를 받습니다. 계정 보류 중에는 정기 결제 리소스expiryTime 필드가 기한이 지난 타임스탬프로 설정되고 subscriptionState 필드가 SUBSCRIPTION_STATE_ON_HOLD로 설정됩니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ON_HOLD",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

액세스 권한을 복원하려면 사용자가 결제 수단을 수정해야 합니다. Play에서는 계정 보류 상태에 있는 사용자에게 결제 거부 사실을 알립니다. 앱에서도 결제 수단을 수정하라는 메시지를 표시해야 합니다.

사용자가 결제 수단을 수정하면 정기 결제가 활성 상태로 돌아갑니다. 그러고 나서 정기 결제한 콘텐츠에 대한 액세스 권한을 복원해야 합니다. 이 경우 동일한 구매가 복원된 것이므로 구매 토큰은 계정 보류가 시작되기 전과 동일하며, 유형이 SUBSCRIPTION_RECOVERED인 RTDN을 수신하게 됩니다.

할부 정기 결제의 경우 개별 결제 시 결제 거부 및 복구가 발생할 수 있습니다.

복구 후에는 Play 결제 라이브러리에서 다시 queryPurchasesAsync() 메서드를 통해 정기 결제를 반환합니다. 이 메서드를 사용하여 사용자에게 정기 결제 자격이 있는지 확인하는 경우 앱은 계정 보류로부터 복구된 정기 결제를 자동으로 처리해야 합니다.

정기 결제가 복구되어 사용자에게 다시 액세스 권한을 부여해야 하는 경우 알림을 받을 수 있도록 유형이 SUBSCRIPTION_RECOVEREDSubscriptionNotification 메시지를 수신 대기하세요. 이 알림을 받은 후 정기 결제를 쿼리하면 expiryTime 필드가 미래의 타임스탬프로 설정되고 subscriptionState 필드가 다시 SUBSCRIPTION_STATE_ACTIVE로 설정됩니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      ...
    }
  ],
}

계정 보류 기간이 종료되기 전에 사용자가 결제 수단을 수정하지 않으면 대신 유형이 SUBSCRIPTION_CANCELED인 RTDN을 수신하게 됩니다. 취소 처리에 관한 안내는 취소를 참고하세요. 이 방식으로 취소된 정기 결제를 쿼리하면 반환된 expiryTime 필드가 기한이 지난 타임스탬프로 설정됩니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_past,
      ...
    }
  ],
}

사용자가 유료 사용 권한을 가지고 있지 않으며 정기 결제가 취소로 인해 제거되었으므로 계정 보류 중에 취소 알림을 받는 즉시 SUBSCRIPTION_EXPIRED 유형의 RTDN도 수신하게 됩니다. 평소와 같이 이 만료를 처리할 수 있습니다.

사용자는 원래 구매의 계정 보류 기간 중에 동일한 정기 결제 요금제나 앱을 통해 제공되는 다른 요금제를 재구매하여 액세스 권한을 다시 얻을 수 있습니다. 이 경우 새 구매 토큰이 발행되고 이 새 인스턴스를 나타내는 SUBSCRIPTION_PURCHASED 이벤트의 일부로 새 값이 반환됩니다.

계정 보류 액세스 및 복구

그림 3은 계정 보류 상태로 전환되었다가 사용자가 결제 수단을 수정하여 다시 복구되는 정기 결제의 타임라인입니다.

그림 3. 계정 보류 상태로 전환된 후 계정 보류가 종료되기 전에 복구되는 정기 결제의 타임라인

이전 예와 마찬가지로, 그림 4는 계정 보류 상태로 전환되기 전에 먼저 유예 기간 상태로 전환되고 계정 보류 중에 복구되는 정기 결제의 타임라인입니다.

그림 4. 유예 기간이 시작된 후 계정 보류 상태로 전환되고 계정 보류가 종료되기 전에 복구되는 정기 결제의 타임라인

다음 사항을 기억해야 합니다.

  • 정기 결제를 계정 보류 상태로 전환하기 전에 Google Play는 최대 24시간 동안 결제 수단에 요금을 청구하려고 추가로 시도합니다. 이 기간 동안 사용자는 정기 결제 혜택을 그대로 유지합니다. 재시도 기간이 지나면 정기 결제가 계정 보류 상태로 전환되고 사용자는 정기 결제의 혜택을 누릴 수 없게 됩니다.
  • 정기 결제가 결제 수단 실패로 인한 일시중지 상태에서 재개되면 정기 결제가 곧바로 계정 보류 상태로 전환됩니다.
  • 계정 보류 상태에서 정기 결제가 복구되면 갱신일이 초기화됩니다.

만료

정기 결제가 만료되면 사용자는 정기 결제에 액세스할 수 없게 됩니다. 이 경우 유형이 SUBSCRIPTION_EXPIREDSubscriptionNotification 메시지가 전송됩니다. 이 알림을 받으면 Google Play Developer API를 쿼리하여 최신 정기 결제 리소스를 가져오세요. subscriptionStateSUBSCRIPTION_STATE_EXPIRED임을 확인한 후에는 사용 권한을 삭제하고 백엔드에서 구매 상태를 무효한 것으로 등록합니다. 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time_in_past,
      ...
    }
  ],
}

취소

사용자는 Play 정기결제 센터에서 정기 결제를 자발적으로 취소하거나 계정 보류 상태에서 복구하지 않음으로써 정기 결제가 자동으로 취소되도록 할 수도 있습니다. 개발자는 purchases.subscriptions.cancel을 사용하여 취소를 트리거할 수도 있습니다. 정기 결제가 취소되더라도 사용자는 현재 결제 주기가 끝날 때까지 콘텐츠에 액세스할 수 있습니다. 결제 주기가 끝나면 액세스가 취소되어야 합니다.

할부되지 않는 자동 갱신 정기 결제를 취소하면 SUBSCRIPTION_CANCELED 알림이 트리거됩니다. 이 알림을 받으면 Google Play Developer API에서 반환된 정기 결제 리소스SUBSCRIPTION_STATE_CANCELED로 설정된 subscriptionState 필드가 포함되며 expiryTime 필드에는 사용자가 정기 결제에 액세스할 수 없게 되는 날짜가 포함됩니다. 이 날짜가 과거인 경우 사용자는 즉시 사용 권한을 잃게 됩니다. 이러한 상황은 예를 들어 결제 거부로 인해 계정 보류 상태에서 사용자가 정기 결제를 취소하는 경우 발생할 수 있습니다.

취소된 구매의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_CANCELED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ],
}

할부 정기 결제의 경우 약정 기간 동안 결제가 남아 있는 경우 사용자가 시작한 취소 시 SUBSCRIPTION_CANCELLATION_SCHEDULED 알림이 전송됩니다. 취소는 대기 중이며 현재 약정 기간이 종료될 때 적용됩니다. 이 알림을 받으면 Google Play Developer API에서 반환된 정기 결제 리소스의 subscriptionState 필드는 SUBSCRIPTION_STATE_ACTIVE로 설정됩니다. 할부 정기 결제는 약정 기간이 끝날 때까지 활성 상태로 유지되기 때문입니다. 하지만 빈 pendingCancellation 객체가 있습니다. SUBSCRIPTION_CANCELED 알림이 전송된 후 약정 기간이 종료되면 SUBSCRIPTION_EXPIRED 알림이 전송됩니다.

취소 대기 중인 할부 정기 결제 구매의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_plan01",
      "expiryTime": expiration_time,
      "autoRenewingPlan": {
        "autoRenewEnabled": true,
        "recurringPrice": {
          "currencyCode": "USD",
          "units": "1",
          "nanos": 990000000
        },
        "installmentDetails": {
          "initialCommittedPaymentsCount": 6,
          "remainingCommittedPaymentsCount": 5,
          "pendingCancellation": {}
      ...
        }
      }
    }
  ],
}

정기 결제 리소스의 canceledStateContext 필드에서 정기 결제가 취소된 이유를 확인할 수 있습니다(예: 정기 결제가 사용자, 시스템 또는 개발자 중 누구에 의해 취소되었는지). 사용자가 정기 결제를 취소했다면 userInitiatedCancellation 필드를 통해 사용자가 정기 결제를 취소한 이유를 확인할 수 있습니다. 이는 커뮤니케이션 전략에 도움이 됩니다.

정기 결제가 취소되었지만 아직 만료되지 않은 경우에도 queryPurchasesAsync()에서 반환됩니다. 사용자에게 정기 결제가 취소된 사실과 만료일을 알리는 메시지를 앱에 표시하는 것이 좋습니다.

해지

백엔드에서 purchases.subscriptionsv2.revoke를 사용하여 정기 결제를 해지하거나 구매 지불을 거절하는 등 정기 결제는 다양한 이유로 해지될 수 있습니다. 이 경우 즉시 사용자의 사용 권한을 취소합니다. 그러면 유형이 SUBSCRIPTION_REVOKEDSubscriptionNotification 메시지가 전송됩니다. 이 알림을 받으면 Google Play Developer API에서 반환되는 정기 결제 리소스subscriptionState 필드가 SUBSCRIPTION_STATE_EXPIRED로 설정됩니다.

해지된 구매의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_EXPIRED",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": expiration_time,
      ...
    }
  ]
}

지연된 정기 결제

여러 가지 이유로 사용자의 사용 권한을 연장해야 할 수 있습니다. 예를 들어, 영화 구매 시 1주일 무료 이용권 제공, 호의의 표시로 고객에게 무료 이용 혜택 제공과 같은 특별 프로모션으로서 무료 액세스 권한을 제공할 수 있습니다. Play Developer API의 purchases.subscriptions.defer 메서드를 사용하여 자동 갱신 정기 결제의 다음 결제일을 미룰 수 있습니다. 이렇게 하면 유형이 SUBSCRIPTION_DEFERREDSubscriptionNotification 메시지가 전송됩니다. 연기 기간 동안 사용자는 전체 액세스 권한으로 정기 결제 콘텐츠에 액세스할 수 있지만 요금이 청구되지 않습니다. 정기 결제 갱신일은 새로운 날짜를 반영하여 업데이트됩니다.

선불 요금제의 경우 결제 연기 API를 사용하여 만료 시간을 연기할 수 있습니다.

지연된 정기 결제의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": timestamp_in_future,
      ...
    }
  ],
}

일시중지된 정기 결제

사용자에게 정기 결제 일시중지 기능을 제공하여 자발적 앱 제거를 줄일 수 있습니다. 일시중지 기능을 사용하도록 설정하면 사용자가 반복 주기에 따라 일주일에서 최대 3개월까지 정기 결제를 일시중지하도록 선택할 수 있게 됩니다.

정기 결제 재신청 매주 매월 3개월 6개월 연간
사용 가능한 일시중지 길이* 1주
2주
3주
4주
1개월
2개월
3개월
1개월
2개월
3개월
1개월
2개월
3개월
해당 사항 없음
*언제든지 변경될 수 있습니다.

정기 결제 일시중지는 현재 결제 기간이 종료되어야만 적용됩니다. 정기 결제가 일시중지된 동안에는 사용자가 정기 결제 콘텐츠에 액세스할 수 없고 갱신 요금을 지불하지 않습니다. 일시중지 기간이 끝나면 정기 결제가 재개되고 Google에서 정기 결제 갱신을 시도합니다. 재개가 완료되면 정기 결제가 다시 활성화됩니다. 결제 문제로 인해 정기 결제가 재개되지 않으면 사용자는 그림 5와 6 같이 계정 보류 상태로 전환됩니다.

그림 5. 사용자가 정기 결제를 일시중지한 후 재개합니다.
그림 6. 사용자가 정기 결제를 일시중지한 후 계정 보류 상태로 전환됩니다.

또한 사용자는 그림 6과 같이 일시중지 기간에 언제든지 수동으로 정기 결제를 재개하도록 선택할 수 있습니다. 사용자가 정기 결제를 수동으로 재개하면 결제일이 수동 재개 날짜로 변경됩니다.

사용자의 정기 결제가 일시중지되면 Play 결제 라이브러리는 queryPurchasesAsync() 메서드를 통해 정기 결제를 반환하지 않습니다. 정기 결제가 재개되면 queryPurchasesAsync() 메서드가 다시 정기 결제를 반환합니다.

사용자가 정기 결제를 일시중지하는 경우를 알 수 있도록 RTDN을 수신 대기하세요. 이러한 알림을 통해 앱의 사용자에게 정기 결제가 일시중지되었으며 정기 결제 콘텐츠에 대한 액세스 권한이 없음을 알릴 수 있습니다. 또한 Google Play로 연결되는 딥 링크를 사용하여 언제든지 정기 결제를 수동으로 재개하는 방법을 사용자에게 제공해야 합니다.

사용자가 정기 결제 일시중지를 시작하면 유형이 SUBSCRIPTION_PAUSE_SCHEDULE_CHANGEDSubscriptionNotification 메시지가 전송됩니다. 이 시점에서 사용자는 다음 갱신일까지 정기 결제 액세스 권한을 유지해야 하며, 정기 결제 리소스autoRenewEnabled = true를 포함합니다. 이 시점에서 subscriptionState 필드의 값은 SUBSCRIPTION_STATE_ACTIVE입니다.

일시중지가 적용되면 유형이 SUBSCRIPTION_PAUSEDSubscriptionNotification 메시지가 전송됩니다. 이 경우 사용자는 정기 결제에 대한 액세스 권한을 잃어야 하며, 정기 결제 리소스는 autoRenewEnabled = true를 포함하고 subscriptionState 필드는 SUBSCRIPTION_STATE_PAUSED로 설정됩니다. PausedStateContext 객체에서 정기 결제가 다시 갱신될 것으로 예상되는 시점을 확인할 수 있습니다.

일시중지 기간이 끝날 때 정기 결제가 자동으로 재개되거나 사용자가 수동으로 정기 결제를 재개하면 유형이 SUBSCRIPTION_RENEWEDSubscriptionNotification 메시지가 전송됩니다. 이 경우 갱신에 설명된 대로 처리해야 합니다.

일시중지 후 정기 결제 재개를 시도하는 동안 결제 실패가 발생하면 유형이 SUBSCRIPTION_ON_HOLDSubscriptionNotification 메시지가 전송됩니다. 이 경우 계정 보류에 설명된 대로 처리해야 합니다.

정기 결제 재신청

자동 갱신 정기 결제 기본 요금제의 경우 Google Play 스토어에 정기 결제 재신청 버튼이 표시될 수 있습니다. 이 버튼을 통해 사용자가 정기 결제에 다시 액세스할 수 있습니다. 정기 결제가 오래 전에 만료된 경우 등 여러 가지 이유로 버튼이 표시되지 않을 수도 있습니다.

그림 7. Google Play 스토어 앱의 계정 > 정기 결제 섹션에 취소된 정기 결제와 정기 결제 재신청 버튼이 표시되어 있습니다.

버튼에는 항상 정기 결제 재신청이라고 라벨이 표시되지만 기능은 정기 결제 상태에 따라 달라집니다.

정기 결제가 취소되었지만 아직 만료되지 않은 동안에는 사용자가 계속 정기 결제 상태에 있으며 정기 결제 혜택을 받습니다. 사용자가 정기 결제 재신청을 탭하면 취소가 사실상 실행취소되고 정기 결제가 계속 갱신됩니다. 이 작업을 Play 개발자 문서 및 API에서는 복원이라고 합니다.

자동 갱신 정기 결제가 만료된 후에는 사용자가 동일한 정기 결제 기본 요금제를 구매하도록 허용할 수 있습니다. 이러한 작업을 Play 개발자 문서 및 API에서는 정기 결제 재신청이라고 합니다. Play Console에서 또는 API를 사용하여 각 기본 요금제의 이 옵션을 구성할 수 있습니다.

만료 전에 복원

앱이 queryPurchasesAsync()만 사용하여 사용자에게 정기 결제 자격이 있는지 확인한다면 queryPurchasesAsync() 메서드가 만료일 전에 취소된 구매를 계속 반환하므로 앱은 복원을 자동으로 처리해야 합니다. 복원된 정기 결제는 취소되지 않았던 것처럼 계속 갱신됩니다.

앱에서 정기 결제 상태가 백엔드와 동기화되는 경우, 유형이 SUBSCRIPTION_RESTARTEDSubscriptionNotification 메시지를 수신 대기해야 합니다. 이 RTDN을 수신하면 앱은 알림에 응답하고, 정기 결제가 이제 갱신되도록 설정되었음을 기록하며, 앱에 복원 메시지 표시를 중지할 수 있습니다. 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date
      ...
    }
  ],
}

만료 후 정기 결제 재신청

정기 결제 재신청을 허용하도록 Google Play Console 또는 API를 사용하여 자동 갱신 기본 요금제를 구성한 경우 사용자는 Google Play 스토어에서 만료된 정기 결제를 다시 구매할 수 있습니다.

이는 신규 구매입니다. Google Play에서는 새로운 구매 토큰을 발급하고 개발자의 백엔드는 SUBSCRIPTION_PURCHASED 유형의 RTDN을 수신합니다. 이러한 앱 외부 구매 유형의 구매 상태에는 원래 정기 결제가 완전히 만료되었으므로 원래 구매와 관련된 linkedPurchaseToken이 포함되지 않습니다. 이는 백엔드에서 다른 구매와 마찬가지로 처리하고 확인해야 하는 신규 구매입니다.

업그레이드, 다운그레이드, 정기 결제 재신청

사용자가 정기 결제가 만료되기 전에 앱에서 취소한 후 업그레이드, 다운그레이드 또는 가입하면 이전 정기 결제는 무효화되고 새로운 정기 결제가 새로운 구매 토큰을 사용하여 생성됩니다

Google Play Developer API에서 반환되는 정기 결제 리소스는 사용자가 업그레이드, 다운그레이드 또는 정기 결제를 재신청한 이전 구매를 나타내는 linkedPurchaseToken 필드를 포함합니다. 이 필드의 구매 토큰을 사용하여 이전 정기 결제를 조회하고 기존 사용자 계정을 식별하여 새로운 구매를 동일한 계정에 연결할 수 있습니다.

앱에서 업그레이드, 다운그레이드, 정기 결제 재신청 옵션을 제공하기 전에 기존의 정기 결제를 확인해야 합니다. 기존 정기 결제가 아직 확인 대기 중인 경우 요금제 변경 또는 정기 결제 재신청이 차단됩니다.

사용자가 업그레이드, 다운그레이드 또는 정기 결제 재신청을 성공적으로 구매하면 이는 개발자가 확인해야 하는 신규 구매입니다. 이를 위해서는 Google Play Developer API를 사용하는 것이 좋습니다. 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  ...
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "linkedPurchaseToken": old_purchase_token,
  ...
  "lineItems": [
    {
      "productId": "sub_variant_plan01",
      "expiryTime": next_renewal_date,
      "autoRenewingPlan": {
        "autoRenewEnabled": true
      }
    }
  ],
}

가격 변경사항

자동 갱신 정기 결제 가격을 변경하고 적절한 경우 사용자에게 알리는 방법을 알아보려면 가격 변경 권장사항 가이드를 참고하세요.

가격 변경사항이 기존 정기 결제 사용자에게 동의 옵션으로 적용되는 경우 사용자가 새 가격을 확인하거나 거부하는 조치를 취하면 RTDN을 수신하게 됩니다.

가격 변경 동의 옵션의 사용자 확인 처리

사용자가 정기 결제 가격 인상을 수락하면 유형이 SUBSCRIPTION_PRICE_CHANGED_CONFIRMEDSubscriptionNotification 메시지를 수신합니다. 거부로 인한 가격 인하의 경우나 정기 결제 가격 인상이 갱신되면 유형이 SUBSCRIPTION_RENEWEDSubscriptionNotification 메시지를 수신합니다. 이 알림은 여느 갱신과 동일하게 취급해야 합니다.

가격 인상 동의가 거부된 경우 처리

사용자가 더 높은 가격으로 갱신해야 하기 전에 가격 인상을 수락하지 않은 경우 자동으로 정기 결제가 취소되며 개발자는 유형이 SUBSCRIPTION_CANCELEDSubscriptionNotification 메시지를 수신합니다. 이 이벤트는 취소에 설명된 대로 처리합니다.

사용자는 동일한 메커니즘에 따라 가격 인상을 거부하기 위해 정기 결제를 취소할 수도 있습니다.

선불 요금제의 수명 주기 처리

자동 갱신 정기 결제와 마찬가지로, 새로운 구매가 이루어질 때마다 선불 요금제를 확인해야 합니다. 선불 요금제의 경우 사용자가 매번 구매 흐름을 거쳐야 하므로 최초 구매와 충전을 완전히 처리해야 합니다.

선불 요금제의 기간이 짧을 수 있으므로 가능한 한 빨리 구매를 확인하는 것이 중요합니다. 기간이 1주 이상인 선불 요금제는 3일 이내에 확인해야 합니다. 기간이 1주일 미만인 선불 요금제는 요금제 기간의 절반 이내에 확인해야 합니다. 예를 들어 개발자는 1.5일 이내에 3일 선불 요금제의 구매를 확인해야 합니다.

그림 8. 정기 결제 구매의 수명 주기 상태 및 전환 이벤트

모든 충전을 포함하여 선불 요금제 정기 결제의 구매가 이루어질 때마다 유형이 SUBSCRIPTION_PURCHASEDSubscriptionNotification 메시지가 RTDN 클라이언트로 전송됩니다. 최신 선불 요금제 정기 결제 상태를 확인하려면 purchases.subscriptionsv2.get 메서드를 호출하세요.

충전 구매에는 새 구매 토큰이 발행되며, 새로운 정기 결제 구매 상태의 일부로 linkedPurchaseToken 필드에 이전 구매 토큰이 수신됩니다. 구매 토큰은 정기 결제 가입부터 만료일 이후 60일까지 유효합니다. 이 날짜 이후에는 구매 토큰으로 더 이상 Google Play Developer API를 호출할 수 없습니다.

선불 요금제 구매의 정기 결제 리소스는 다음 예시와 유사합니다.

{
  "kind": "androidpublisher#subscriptionPurchaseV2",
  "startTime": "2022-04-22T18:39:58.270Z",
  "regionCode": "US",
  "subscriptionState": "SUBSCRIPTION_STATE_ACTIVE",
  "latestOrderId": "GPA.3333-4137-0319-36762",
  "acknowledgementState": "ACKNOWLEDGEMENT_STATE_ACKNOWLEDGED",
  "lineItems": [
    {
      "productId": "prepaid_plan01",
      "expiryTime": expiry_date,
      "prepaidPlan": {
        "allowExtendAfterTime": timestamp_after_which_topups_are_allowed
      }
    }
  ]
}

expiryTime 필드에서 사용 권한이 종료되는 시점을 확인할 수 있습니다. 충전 구매는 사용 권한 시간을 누적하여 늘립니다. 즉, 사용자가 원래 사용 권한이 종료되는 시점 전에 충전하면 이전 만료일에 새로운 시간이 추가됩니다.

사용자에게 선불 정기 결제를 잔액 충전으로 연장할 수 있음을 알리는 메시지를 앱에 표시하는 것이 좋습니다. 사용자가 충전이 가능한 시점을 확인하려면 정기 결제 리소스의 allowExtendAfterTime 필드를 확인합니다.

선불 요금제는 자동 갱신되지 않으므로 취소할 수 없습니다. 사용자가 선불 요금제를 취소하려는 경우 만료일까지 기다리면 됩니다.