부가기능이 포함된 구독

추가 기능이 포함된 정기 결제를 사용하면 함께 구매, 청구, 관리할 수 있는 여러 정기 결제 제품을 번들로 묶을 수 있습니다. 기존 제품 카탈로그 구독은 사전 사양이나 추가 구성 없이 부가기능으로 원활하게 제공될 수 있습니다. 기존 정기 결제 제품이 여러 개인 구매 흐름을 실행하고 이를 부가기능으로 판매할 수 있습니다.

고려사항

부가기능이 포함된 구독 기능을 사용할 때는 다음 사항을 고려하세요.

  • 애드온이 포함된 정기 결제는 자동 갱신 기본 요금제에서만 지원됩니다.

  • 구매의 모든 항목은 동일한 반복 결제 기간을 가져야 합니다. 예를 들어 월별로 청구되는 부가기능이 있는 연간 청구 정기 결제는 사용할 수 없습니다.

  • 부가기능 구매가 포함된 정기 결제에는 최대 50개의 항목이 있을 수 있습니다.

  • 이 기능은 대한민국 (KR) 및 인도 (IN) 지역에서 사용할 수 없습니다.

Play 결제 라이브러리와 통합

이 섹션에서는 부가기능이 포함된 정기 결제 기능을 Play 결제 라이브러리 (PBL)와 통합하는 방법을 설명합니다. 여기서는 앱에 PBL 종속 항목 추가, BillingClient 초기화, Google Play에 연결과 같은 초기 PBL 통합 단계를 잘 알고 있다고 가정합니다. 이 섹션에서는 부가기능이 있는 구독에만 적용되는 PBL 통합 측면을 중점적으로 설명합니다.

구매 흐름 시작

부가기능이 포함된 정기 결제의 구매 흐름을 시작하려면 다음 단계를 따르세요.

  1. BillingClient.queryProductDetailsAsync 메서드를 사용하여 모든 정기 결제 항목을 가져옵니다.

  2. 각 항목의 ProductDetailsParams 객체를 설정합니다.

    ProductDetailsParams 객체로 표시되는 항목은 정기 결제 항목을 나타내는 ProductDetails와 특정 정기 결제 base plan 또는 offer을 선택하는 offerToken을 모두 지정합니다.

  3. BillingFlowParams.Builder.setProductDetailsParamsList 메서드에서 상품 세부정보를 지정합니다. BillingFlowParams 클래스는 구매 흐름의 세부정보를 지정합니다.

    다음 샘플은 여러 항목이 있는 정기 결제 구매의 결제 흐름을 실행하는 방법을 보여줍니다.

    자바

       BillingClient billingClient = ;
    
        // ProductDetails obtained from queryProductDetailsAsync().
        ProductDetailsParams productDetails1 = ...;
        ProductDetailsParams productDetails2 = ...;
        ArrayList productDetailsList = new ArrayList<>();
        productDetailsList.add(productDetails1);
        productDetailsList.add(productDetails2);
    
        BillingFlowParams billingFlowParams =
            BillingFlowParams.newBuilder()
               .setProductDetailsParamsList(productDetailsList)
               .build();
        billingClient.launchBillingFlow(billingFlowParams);

구매에 포함된 상품에 적용되는 규칙

  • 부가기능 갱신일이 기본 항목과 일치하도록 Google Play에서는 무료 체험 또는 할인 가격 단계 후에 일할 계산된 요금을 삽입할 수 있습니다.
  • 혜택 자격 요건은 상품별로 별도로 평가됩니다.

구매 처리

부가기능이 포함된 정기 결제 처리는 앱에 Google Play Billing Library 통합에 설명된 단일 항목 구매 처리와 동일합니다. 유일한 차이점은 사용자가 단일 구매로 여러 권한을 받을 수 있다는 것입니다. 부가기능이 포함된 정기 결제 구매는 여러 항목을 반환하며, 이 항목은 Google Play 결제 라이브러리의 Purchase.getProducts()를 사용한 후 Google Play Developer APIpurchases.subscriptionsv2.get에 있는 lineItems 목록을 사용하여 검색할 수 있습니다.

부가기능이 포함된 정기 결제 수정

부가기능이 포함된 구독을 변경하면 업그레이드 또는 다운그레이드가 발생합니다. 자세한 내용은 정기 결제 업그레이드 또는 다운그레이드를 참고하세요.

앱에서 부가기능이 있는 기존 정기 결제를 변경하거나 복원하려면 추가 매개변수를 사용하여 launchBillingFlow API를 호출하고 다음 사항을 확인해야 합니다.

  • 항상 현재 정기 결제 구매의 구매 토큰으로 setOldPurchaseToken를 호출합니다.
  • 항목을 업그레이드, 다운그레이드 또는 크로스그레이드하려면 SubscriptionProductReplacementParams.setReplacementMode를 호출하여 이전 구매 항목과 새 구매 항목 간에 요금제 변경을 처리하는 방법을 지정합니다. 그렇지 않으면 이 매개변수를 설정할 필요가 없습니다.
  • 기본 항목이 변경되지 않은 경우에도 SubscriptionProductReplacementParams.setSubscriptionReplacementMode를 호출하여 특정 대체 동작을 적용할 수 있습니다. 이 경우에 적용되는 규칙은 동일한 정기 결제 내에서 재신청 또는 요금제 전환을 참고하세요.
  • 새 부가기능은 다음 갱신일을 정기 결제의 기본 항목과 일치시키기 위해 일할 계산된 요금과 함께 즉시 적용됩니다.
  • 삭제된 부가기능은 현재 결제 기간이 종료되면 만료됩니다.
  • 결제 흐름을 실행할 때는 삭제할 항목을 제외한 부가기능이 포함된 정기 결제의 모든 활성 항목과 새 부가기능을 지정해야 합니다.

다음 샘플은 부가기능이 있는 기존 정기 결제를 변경할 때 launchBillingFlow API를 호출하는 방법을 보여줍니다.

자바

BillingClient billingClient = ;

int replacementMode =;

// ProductDetails obtained from queryProductDetailsAsync().
ProductDetailsParams productDetails1 = ...;
ProductDetailsParams productDetails2 = ...;
ProductDetailsParams productDetails3 = ...;

ArrayList newProductDetailsList = new ArrayList<>();
newProductDetailsList.add(productDetails1);
newProductDetailsList.add(productDetails1);
newProductDetailsList.add(productDetails1);

BillingFlowParams billingFlowParams =
    BillingFlowParams.newBuilder()
        .setSubscriptionUpdateParams(
          SubscriptionUpdateParams.newBuilder()
              .setOldPurchaseToken(purchaseTokenOfExistingSubscription)
              // No need to set if change does not affect the base item.
             .setSubscriptionReplacementMode(replacementMode)
             .build())
        .setProductDetailsParamsList(productDetailsList)
        .build();

billingClient.launchBillingFlow(billingFlowParams);

정기 결제 수정 시나리오

다음 표에는 부가기능이 포함된 정기 결제의 다양한 수정 시나리오와 해당 동작이 나와 있습니다.

SubscriptionProductReplacementParams를 사용하는 경우

기존 항목 수정된 항목 SubscriptionProductReplacementParams에서 교체 모드를 설정해야 하나요? 동작
A (기본 상품), B A (기본 항목) 예 (KEEP_EXISTING 사용)
  • 항목 B는 지연된 삭제가 예정되어 있습니다.
  • 항목 A가 유지됩니다.
  • 사용자는 가입 시 받은 신규 할인 결제의 잔액을 포함하여 상품 A의 현재 가격을 유지합니다.
A A (기본 상품), B 예 (A에 KEEP_EXISTING 사용)
  • 상품 B가 일할 계산된 요금과 함께 즉시 추가됩니다.
  • 항목 A가 유지됩니다.
  • 사용자는 가입 시 받은 신규 할인 결제의 잔액을 포함하여 상품 A의 현재 가격을 유지합니다.
A (기본 상품), B A (기본 항목), C 예 (A에 KEEP_EXISTING 사용)
  • B는 지연된 삭제가 예정되어 있습니다.
  • C가 일할 계산된 요금과 함께 즉시 추가됩니다.
  • 항목 A가 유지됩니다.
  • 사용자는 가입 시 받은 신규 할인 결제의 잔액을 포함하여 상품 A의 현재 가격을 유지합니다.
A (기본 상품), B B (기본 상품) 아니요 A가 지연된 삭제가 예정되어 있습니다.
A (기본 상품), B C (기본 항목)
  • A -> C의 대체는 SubscriptionProductReplacementParams replacementMode에 따라 달라집니다.
  • B는 지연된 삭제가 예정되어 있습니다.
A (기본 상품), B C (기본 항목), B
  • A -> C의 대체는 SubscriptionProductReplacementParams replacementMode에 따라 달라집니다.
  • 항목 B를 변경하지 않으려면 교체 모드를 KEEP_EXISTING로 설정합니다. 그렇지 않으면 기본적으로 대체 모드는 IMMEDIATE_WITHOUT_PRORATION입니다.
A (기본 상품), B C (기본 항목), D
  • A -> C의 대체는 SubscriptionProductReplacementParams replacementMode에 따라 달라집니다.
  • B는 지연된 삭제가 예정되어 있습니다.
  • D가 일할 계산된 요금과 함께 즉시 추가됩니다.
A (기본 상품), B A (기본 항목), C
  • A -> A 및 B -> C의 대체는 각 ProductDetailsParamsSubscriptionProductReplacementParams replacementMode에 제공된 대체 모드에 따라 다릅니다.
  • 상품 A를 변경하지 않으려면 교체 모드를 KEEP_EXISTING로 설정합니다.
A (기본 항목), B, C D (기본 상품), B, C
  • A->D 및 B->B, C->C의 대체는 각 ProductDetailsParamsSubscriptionProductReplacementParams replacementMode에 제공된 대체 모드에 따라 다릅니다.
  • 항목 B와 C를 변경하지 않으려면 대체 모드를 KEEP_EXISTING로 설정합니다.

SubscriptionUpdateParams를 사용하는 경우

기존 항목 수정된 항목 교체 정보를 설정해야 하나요? 동작
A (기본 상품), B A (기본 항목) 아니요
  • 항목 B는 지연된 삭제가 예정되어 있습니다.
  • 상품 A의 동작은 기본 요금제의 기본 요금제 및 혜택 변경 설정에 따라 달라집니다.
  • 상품 A의 가격이 최신 가격으로 업데이트되며, 혜택 자격 기준에 따라 가입 시 받은 신규 할인 결제가 취소될 수 있습니다.
A A (기본 상품), B 아니요
  • 상품 B가 일할 계산된 요금과 함께 즉시 추가됩니다.
  • 상품 A의 동작은 기본 요금제의 기본 요금제 및 혜택 변경 설정에 따라 달라집니다.
  • 상품 A의 가격이 최신 가격으로 업데이트되며, 혜택 자격 기준에 따라 가입 시 받은 신규 할인 결제가 취소될 수 있습니다.
A (기본 상품), B A (기본 항목), C 아니요
  • B는 지연된 삭제가 예정되어 있습니다.
  • C가 일할 계산된 요금과 함께 즉시 추가됩니다.
  • 상품 A의 동작은 기본 요금제의 기본 요금제 및 혜택 변경 설정에 따라 달라집니다.
A (기본 상품), B B (기본 상품) 아니요 A가 지연된 삭제가 예정되어 있습니다.
A (기본 상품), B C (기본 항목)
  • A -> C 대체는 setSubscriptionReplacementMode (PBL 8.1에서 지원 중단됨)에 따라 다릅니다.
  • B는 지연된 삭제가 예정되어 있습니다.
A (기본 상품), B C (기본 항목), B A -> C 대체는 setSubscriptionReplacementMode (PBL 8.1에서 지원 중단됨)에 따라 다릅니다.
A (기본 상품), B C (기본 항목), D
  • A -> C 대체는 setSubscriptionReplacementMode (PBL 8.1에서 지원 중단됨)에 따라 다릅니다.
  • B는 지연된 삭제가 예정되어 있습니다.
  • D가 일할 계산된 요금과 함께 즉시 추가됩니다.

실시간 개발자 알림

여러 항목 권한이 포함된 부가기능이 있는 정기 결제 구매의 경우 RTDNsubscriptionId 필드가 제공되지 않습니다. 대신 Play Developer API를 사용하여 구매를 가져오고 연결된 항목 권한을 확인할 수 있습니다.

기존 정기 결제 사용자의 가격 변경

부가기능 구매가 있는 정기 결제의 기존 정기 결제 사용자의 정기 결제 가격을 변경하는 것은 정기 결제 가격 변경에 설명된 대로 단일 항목 정기 결제의 정기 결제 가격을 변경하는 것과 유사합니다. 하지만 이 섹션에 설명된 대로 몇 가지 제한사항과 기능 차이점이 있습니다.

기존 가격 사용자 집단 종료

기존 사용자 집단을 종료하면 부가기능 구매가 포함된 정기 결제에도 영향을 미칩니다. 다음 규칙이 적용됩니다.

  • 모든 미해결 동의형 요금 인상의 갱신 시간이 새 요금과 동일해야 합니다. 부가기능 구매가 포함된 정기 결제의 상품에 사용자가 아직 확인하지 않은 동의형 요금 인상이 있는 경우, 구매의 다른 상품에 대한 새로운 동의형 요금 인상은 OUTSTANDING 상태의 기존 요금 인상과 새 가격 적용 갱신 시간이 동일하지 않는 한 무시됩니다. 사용자가 가격 인상을 확인하면 최신 가격 변경사항이 등록됩니다. 또한 사용자는 확인되지 않은 모든 가격 인상 동의 옵션을 한 번에만 수락할 수 있습니다.

    예:

    • 부가기능 (상품 A 및 B)이 포함된 정기 결제가 매월 7일에 갱신된다고 가정해 보겠습니다.
    • 상품 A의 가격이 7달러에서 10달러로 이전되고 있으며 7월 7일에 가격 인상이 적용될 예정입니다.
    • 6월 2일에 항목 B의 가격이 5달러에서 6달러로 변경됩니다. 동의형 요금 인상은 이전 후 37일 후에 시작되므로 상품 B의 가장 빠른 요금 인상은 8월 7일입니다.

    이 시나리오에서 사용자가 상품 A의 가격 변경을 수락할 때까지 (CONFIRMED 상태가 될 때까지) 이 정기 결제 구매에 상품 B의 가격 변경이 등록되지 않으며 SubscriptionPurchaseV2에서 상품 B의 가격 변경 세부정보를 반환하지 않습니다. 사용자가 상품 A의 가격 변경을 확인하면 상품 B의 가격 변경이 시작됩니다. 사용자는 상품 A의 동의형 인상을 수락한 후에만 상품 B의 동의형 인상을 수신합니다.

  • Google Play 이메일에는 동일한 날짜에 가격이 인상되거나 인하되는 모든 항목의 목록이 포함되어 있습니다.

부가기능이 포함된 구독 취소

사용자는 Play 정기 결제 센터에서 부가기능이 포함된 정기 결제의 전체 구매를 취소할 수 있으며, 개발자는 Google Play Developer API를 사용해서만 부가기능이 포함된 정기 결제의 전체 구매를 취소할 수 있습니다.

취소되었지만 취소되지 않은 정기 결제 구매의 경우 구매에 포함된 항목이 자동 갱신되지 않지만 사용자는 해당 결제 기간이 끝날 때까지 자격이 부여된 항목에 계속 액세스할 수 있습니다.

부가기능이 포함된 정기 결제 취소 및 환불

다음은 정기 결제 취소 및 환불에 관한 몇 가지 가이드라인입니다.

  • Play Console을 사용하여 정기 결제 액세스 권한을 취소하지 않고 특정 주문에 대해 금액 기반 환불을 처리합니다.

  • orders.refund을 호출하여 정기 결제에 대한 액세스 권한을 취소하지 않고 사용자가 결제한 특정 정기 결제 금액을 전액 환불합니다.

  • purchases.subscriptionsv2.revoke을 호출하여 모든 정기 결제 항목에 대한 액세스 권한을 즉시 취소합니다. 이 API를 사용하면 다음 작업을 할 수 있습니다.

    • 모든 항목에 대한 액세스 권한을 취소하고 일할 계산된 환불을 제공합니다.

    • 일할 계산된 환불을 사용하여 부가기능이 포함된 정기 결제를 취소하면 다음 갱신까지 남은 시간을 기준으로 일할 계산된 금액으로 각 항목의 최신 주문에 대해 환불이 발행됩니다.

    • 모든 항목의 액세스 권한을 취소하고 FullRefund를 제공합니다.

    • 개별 항목의 액세스 권한을 취소하고 항목에 대해 전액 환불을 받습니다.

부가기능이 포함된 정기 결제에서 개별 항목 취소

전체 구매를 취소하지 않고 부가기능이 있는 정기 결제에서 개별 정기 결제 항목을 취소하려면 RevocationContext에서 설정된 ItemBasedRefund 필드를 사용하여 purchases.subscriptionsv2.revoke를 호출합니다. 취소 및 환불해야 하는 상품의 productIdItemBasedRefund 필드에서 설정할 수 있습니다.

ItemBasedRefund 필드는 하나 이상의 자동 갱신 정기 결제 항목이 있는 구매에 설정할 수 있습니다.

  • ItemBasedRefund에 지정된 상품을 취소한 후에도 정기 결제 구매에 활성 상태의 상품이 남아 있는 경우 해당 상품만 취소되고 정기 결제 상태가 중단되지 않은 상태로 전액 환불됩니다.
  • ItemBasedRefund에 지정된 항목을 취소한 후 정기 결제 구매에 활성 항목이 남아 있지 않으면 항목이 취소되고 전액 환불되며 정기 결제가 취소됩니다.

고려사항

  • ItemBasedRefund를 사용하는 경우 한 번에 하나의 항목만 취소할 수 있습니다. 다른 항목을 취소해야 하는 경우 요청을 여러 번 호출할 수 있습니다.
  • 정기 결제 구매가 결제 거부 상태에 있거나 ItemBasedRefund에 지정된 상품을 소유하지 않거나 만료된 경우 상품 거부가 차단됩니다.
  • 선불 구독에서는 상품 거부가 지원되지 않습니다.

결제 거부 시 상품 만료

부가기능이 있는 정기 결제의 경우 일부 갱신은 만료일이 미래인 항목에 영향을 주지 않고 항목 혜택의 하위 집합만 연장하면 됩니다.

갱신에 어떤 항목이 포함되는지와 관계없이 갱신 결제가 거부되면 전체 정기 결제 구매가 다음 문서에 설명된 대로 유예 기간 및 계정 보류 상태로 전환됩니다.

복구 기간 선택

유예 기간 자체는 여전히 사용자에게 사용 권한을 부여하므로 부가기능이 포함된 정기 결제를 구매한 후 갱신 결제가 거부되면 모든 활성 항목 중 유예 기간이 가장 짧은 항목이 선택되고 해당 항목의 유예 기간과 계정 보류 기간이 이 갱신의 복구 기간으로 적용됩니다.

활성 항목에는 갱신 시도 직전에 부가기능이 포함된 구독 구매 시 활성 상태였던 항목이 포함되며, 새로 추가된 항목(복구 후까지 권한이 부여되지 않음)과 삭제 또는 거부로 인해 더 이상 활성 상태가 아닌 항목은 제외됩니다.

선택된 최소 유예 기간이 있는 항목의 계정 보류 설정이 적용됩니다. 최소 유예 기간은 동일하지만 계정 보류 기간이 다른 항목이 두 개 이상인 경우 가장 긴 계정 보류 기간이 적용됩니다.

유예 기간

정기 결제 갱신 결제가 거부되면 정기 결제 구매가 유예 기간 상태로 전환됩니다. 유예 기간 동안 사용자는 이전 갱신 기간의 모든 활성 항목에 계속 액세스할 수 있습니다. 유예 기간이 지난 후에도 결제 수단이 수정되지 않으면 전체 정기 결제 구매가 계정 보류 상태가 됩니다. 유예 기간 동안 다른 항목의 갱신일이 도래하는 경우, 정기 결제가 결제 거부에서 복구되면 해당 항목에 대한 새로운 청구 시도가 시작됩니다.

계정 보류

정기 결제 구매가 계정 보류 상태인 동안에는 결제가 복구될 때까지 모든 정기 결제 항목에 대한 액세스가 일시중지됩니다.

계정 보류 상태의 정기 결제가 복구되면 정기 결제 구매가 그대로 계속됩니다. 정기 결제가 복구되지 않으면 결제 거부된 항목이 만료되고 다른 항목에 대한 액세스는 남은 결제 기간 동안 재개됩니다.

예:

  • 사용자가 매월 1일에 갱신되는 내 기본 요금제를 구독하고 있습니다. 8월 15일에 7일 무료 체험이 포함된 월 $10 부가기능 요금제를 추가합니다. 두 항목 모두 유예 기간이 설정되어 있지 않으며 계정 보류 기간은 30일입니다.

  • 8월 22일에 사용자는 8월 31일까지의 일할 계산된 금액인 2.90달러 (10*9/31)가 청구되지만 그 전에 사용자의 결제 수단이 만료되고 8월 22일에 정기 결제가 결제 거부 상태가 됩니다.

결제 거부로 인해 정기 결제가 계정 보류 상태가 되면 사용자는 부가기능이 있는 정기 결제의 항목에 액세스할 수 없습니다. 결제가 복구되었거나 취소되어 정기 결제가 계정 보류에서 해제되면 갱신되지 않는 항목의 남은 기간이 사용자에게 반환됩니다.

이전 예에서 정기 결제는 8월 22일에 계정 보류 상태로 전환됩니다.

  • 9월 1일의 광범위한 갱신일 이전에 8월 25일에 계정이 복구되면 사용자는 당일 내 기본 요금제부가기능 요금제에 대한 액세스 권한을 모두 되찾게 됩니다. 다음 결제일이 9월 4일로 변경됩니다.

  • 30일이 지나도 계정을 복구하지 않으면 9월 21일에 정기 결제가 취소되고 사용자는 부가기능 요금제에 액세스할 수 없게 되며 9월 30일까지 내 기본 요금제에 대한 액세스를 재개할 수 있습니다.

이 예에서는 일부 항목이 유예 기간 및 계정 보류 후 권한을 재개할 수 있으므로 부가기능이 있는 정기 결제의 모든 항목에 대해 업데이트된 expiryTime를 가져와야 합니다.

재무 보고 및 조정

수익 보고서를 사용하여 활성 정기 결제와 Play의 거래를 조정합니다. 각 거래 광고 항목에는 주문 ID가 있습니다. 여러 상품을 나타내는 구매의 경우 수익 및 예상 판매 보고서에는 관련 상품별로 청구, 수수료, 세금, 환불과 같은 거래에 대한 별도의 행이 포함됩니다.

Play Console의 대시보드:

  • 콘솔의 재무 보고 섹션에 표시되는 수익 통계는 항목별로 분류됩니다.

  • 주문 관리에는 부가기능이 포함된 정기 결제 구매가 반영되고 구매한 항목의 목록이 표시됩니다. 주문 관리에서 사용자의 구매를 취소하거나, 취소하거나, 전액 환불할 수 있습니다.