Google Play 결제를 통해 Digital Goods API 및 Payment Request API로 결제 받기

앱이 Google Play를 통해 배포되고 디지털 상품을 판매하거나 정기 결제를 제공하려면 Google Play 결제를 사용해야 합니다. Google Play 결제는 카탈로그, 가격, 정기 결제를 관리하는 도구, 유용한 보고서, 사용자가 이미 익숙한 Play 스토어 기반의 결제 절차를 제공합니다.

신뢰할 수 있는 웹 활동을 사용하여 빌드되고 Google Play 스토어를 통해 제공되는 앱의 경우 이제 결제 요청 API디지털 상품 API를 사용하여 Google Play 결제와 통합할 수 있습니다. Android 및 ChromeOS의 Chrome 101 이상에서 사용할 수 있습니다.

이 가이드에서는 PWA에 Google Play 결제 지원을 추가하고 ChromeOS 및 Play 스토어용 Google Play 스토어에 배포할 수 있도록 패키징하는 방법을 알아봅니다.

두 가지 웹 플랫폼 API를 사용하여 PWA에 Play 결제 지원을 추가합니다. Digital Goods API는 SKU 정보를 수집하고 Play 스토어에서 구매 및 사용 권한을 확인하는 데 사용됩니다. Payment Request API는 Google Play 스토어를 결제 수단으로 구성하고 구매 흐름을 완료하는 데 사용됩니다.

Play 스토어에서 애플리케이션으로 수익을 창출하는 방법

애플리케이션이 Play 스토어에서 Google Play 결제를 통해 수익을 창출하는 방법에는 두 가지가 있습니다.

  • 인앱 구매를 사용하면 추가 기능 또는 광고 삭제와 같은 내구재 및 소비성 가상 상품을 모두 판매할 수 있습니다.
  • 정기 결제: 뉴스 구독이나 멤버십과 같이 사용자가 요금을 반복적으로 지불하면 콘텐츠나 서비스에 지속적으로 액세스할 수 있도록 합니다.

요구사항

Google Play 결제를 설정하려면 다음이 필요합니다.

Bubblewrap 프로젝트 업데이트

Bubblewrap이 설치되어 있지 않으면 설치해야 합니다. 시작 방법에 관한 자세한 내용은 빠른 시작 가이드를 참고하세요. Bubblewrap이 이미 있는 경우 버전 1.8.2 이상으로 업데이트해야 합니다.

Bubblewrap에도 플래그 뒤에 있는 기능이 있습니다. 이를 사용 설정하려면 프로젝트 루트에 있는 twa-manifest.json에서 프로젝트 구성을 수정하고 alphaDependenciesplayBilling 기능을 모두 사용 설정해야 합니다.

  ...,
  "enableNotifications": true,
  "features": {
    "playBilling": {
      "enabled": true
    }
  },
  "alphaDependencies": {
    "enabled": true
  },
  ...

구성 파일이 업데이트되면 bubblewrap update를 실행하여 프로젝트에 구성을 적용한 다음 bubblewrap build를 실행하여 새 Android 패키지를 생성하고 이 패키지를 Play 스토어에 업로드합니다.

Digital Goods API 및 Google Play 결제 사용 가능 여부를 감지하는 기능

Digital Goods API는 현재 PWA가 신뢰할 수 있는 웹 활동 내에서 실행 중일 때만 Chrome에서 지원되며 window 객체에서 getDigitalGoodsService를 확인하여 사용 가능 여부를 감지할 수 있습니다.

if ('getDigitalGoodsService' in window) {
 // Digital Goods API is supported!
}

Digital Goods API는 모든 브라우저에서 사용할 수 있으며 다양한 스토어를 지원합니다. 특정 스토어 백엔드가 지원되는지 확인하려면 스토어 ID를 매개변수로 전달하여 getDigitalGoodsService()를 호출해야 합니다. Google Play 스토어는 https://play.google.com/billing 문자열로 식별됩니다.

if ('getDigitalGoodsService' in window) {
  // Digital Goods API is supported!
  try {
    const service =
        await window.getDigitalGoodsService('https://play.google.com/billing');
    // Google Play Billing is supported!

  } catch (error) {
    // Google Play Billing is not available. Use another payment flow.
    return;
  }
}

SKU 세부정보 검색

Digital Goods API는 결제 백엔드에서 제품명, 설명, 가장 중요한 가격과 같은 정보를 검색할 수 있는 getDetails()를 제공합니다.

그런 다음 이 정보를 사용자 인터페이스에서 사용하고 사용자에게 더 많은 세부정보를 제공할 수 있습니다.

const skuDetails = await service.getDetails(['shiny_sword', 'gem']);
for (item of skuDetails) {
  // Format the price according to the user locale.
  const localizedPrice = new Intl.NumberFormat(
      navigator.language,
      {style: 'currency', currency: item.price.currency}
    ).format(item.price.value);

  // Render the price to the UI.
  renderProductDetails(
        item.itemId, item.title, localizedPrice, item.description);
}

구매 흐름 빌드

PaymentRequest의 생성자는 결제 수단 목록과 결제 세부정보 목록이라는 두 가지 매개변수를 사용합니다.

신뢰할 수 있는 웹 활동 내에서는 https://play.google.com/billing를 식별자로 설정하고 제품 SKU를 데이터 멤버로 추가하여 Google Play 결제 결제 수단을 사용해야 합니다.

async function makePurchase(service, sku) {
   // Define the preferred payment method and item ID
   const paymentMethods = [{
       supportedMethods: "https://play.google.com/billing",
       data: {
           sku: sku,
       }
   }];

   ...
}

결제 세부정보는 필수사항이지만 Play 결제는 이러한 값을 무시하고 Play Console에서 SKU를 만들 때 설정된 값을 사용하므로 가짜 값으로 채울 수 있습니다.

const paymentDetails = {
    total: {
        label: `Total`,
        amount: {currency: `USD`, value: `0`}
    }
};

const request = new PaymentRequest(paymentMethods, paymentDetails);

결제 요청 객체에서 show()를 호출하여 결제 흐름을 시작합니다. Promise가 성공하면 결제가 완료되었을 수 있습니다. 실패하면 사용자가 결제를 중단했을 가능성이 높습니다.

약속이 성공하면 구매를 확인하고 확인해야 합니다. 사기를 방지하려면 이 단계를 백엔드를 사용하여 구현해야 합니다. Play 결제 문서에서 백엔드에 인증을 구현하는 방법을 알아보세요. 구매를 확인하지 않으면 3일 후 사용자에게 환불되고 Google Play에서 구매가 취소됩니다.

...
const request = new PaymentRequest(paymentMethods, paymentDetails);
try {
    const paymentResponse = await request.show();
    const {purchaseToken} = paymentResponse.details;

    // Call backend to validate and acknowledge the purchase.
    if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
        // Optional: tell the PaymentRequest API the validation was
        // successful. The user-agent may show a "payment successful"
        // message to the user.
        const paymentComplete = await paymentResponse.complete('success');
    } else {
        // Optional: tell the PaymentRequest API the validation failed. The
        // user agent may show a message to the user.
        const paymentComplete = await paymentResponse.complete('fail');
    }
} catch(e) {
    // The purchase failed, and we can handle the failure here. AbortError
    // usually means a user cancellation
}
...

원하는 경우 purchaseToken에서 consume()를 호출하여 구매를 사용한 것으로 표시하고 다시 구매할 수 있도록 허용할 수 있습니다.

모든 것을 종합하면 구매 방법은 다음과 같습니다.

async function makePurchase(service, sku) {
    // Define the preferred payment method and item ID
    const paymentMethods = [{
        supportedMethods: "https://play.google.com/billing",
        data: {
            sku: sku,
        }
    }];

    // The "total" member of the paymentDetails is required by the Payment
    // Request API, but is not used when using Google Play Billing. We can
    // set it up with bogus details.
    const paymentDetails = {
        total: {
            label: `Total`,
            amount: {currency: `USD`, value: `0`}
        }
    };

    const request = new PaymentRequest(paymentMethods, paymentDetails);
    try {
        const paymentResponse = await request.show();
        const {purchaseToken} = paymentResponse.details;

        // Call backend to validate and acknowledge the purchase.
        if (await acknowledgePurchaseOnBackend(purchaseToken, sku)) {
            // Optional: consume the purchase, allowing the user to purchase
            // the same item again.
            service.consume(purchaseToken);

            // Optional: tell the PaymentRequest API the validation was
            // successful. The user-agent may show a "payment successful"
            // message to the user.
            const paymentComplete =
                    await paymentResponse.complete('success');
        } else {
            // Optional: tell the PaymentRequest API the validation failed.
            // The user agent may show a message to the user.
            const paymentComplete = await paymentResponse.complete('fail');
        }
    } catch(e) {
        // The purchase failed, and we can handle the failure here.
        // AbortError usually means a user cancellation
    }
}

기존 구매 상태 확인하기

Digital Goods API를 사용하면 사용자가 다른 기기에서, 이전 설치에서, 프로모션 코드에서 사용했거나, 앱을 마지막으로 연 시점에 이미 구매한 기존 사용 권한 (아직 사용하지 않은 인앱 구매 또는 진행 중인 정기 결제)이 있는지 확인할 수 있습니다.


const service =
     await window.getDigitalGoodsService('https://play.google.com/billing');
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

이전에 구매했으나 확인되지 않은 구매 내역이 있는지 확인할 때도 이 페이지가 유용합니다. 사용자의 사용 권한이 앱에 올바르게 반영되도록 하려면 최대한 빨리 구매를 확인하는 것이 좋습니다.

const service =
     await window.getDigitalGoodsService("https://play.google.com/billing");
...
const existingPurchases = await service.listPurchases();
for (const p of existingPurchases) {
    await verifyOrAcknowledgePurchaseOnBackend(p.purchaseToken, p.itemId);

    // Update the UI with items the user is already entitled to.
    console.log(`Users has entitlement for ${p.itemId}`);
}

통합 테스트

개발용 Android 기기에서

테스트를 위해 개발 Android 기기에서 Digital Goods API를 사용 설정할 수 있습니다.

  • 개발자 모드가 사용 설정된 Android 9 이상을 사용하고 있는지 확인합니다.
  • Chrome 101 이상을 설치합니다.
  • Chrome에서 chrome://flags로 이동하여 이름으로 플래그를 검색하여 다음 플래그를 사용 설정합니다.
    • #enable-debug-for-store-billing
  • 사이트가 https 프로토콜을 사용하여 호스팅되고 있는지 확인합니다. http를 사용하면 API가 undefined

ChromeOS 기기에서

Digital Goods API는 버전 89부터 ChromeOS 안정화 버전에서 사용할 수 있습니다. 그동안 Digital Goods API를 테스트할 수 있습니다.

  • Play 스토어에서 기기에 앱을 설치합니다.
  • 사이트가 https 프로토콜을 사용하여 호스팅되고 있는지 확인합니다. http를 사용하면 API가 undefined

테스트 사용자 및 QA팀

Play 스토어는 사용자 테스트 계정 및 테스트 SKU를 비롯한 테스트 기능을 제공합니다. 자세한 내용은 Google Play 결제 테스트 문서를 참고하세요.

다음 단계는 무엇일까요?

이 문서에서 설명한 대로 Play 결제 API에는 Digital Goods API에서 관리하는 클라이언트 측 구성요소와 서버 측 구성요소가 있습니다.