iOS 인 앱 구매 (In App Purchase) 구현 가이드라인

이전에 사내 공유 목적으로 작성한 In App Purchase 가이드라인을 정리하여 보았습니다.

공식 가이드라인(Apple): https://developer.apple.com/kr/app-store/review/guidelines/#business

요약

  1. 인앱결제 수수료(Fee) 30%, 구독상품의 경우 1년이상 구독시 해당유저 15%로 인하
  2. 모든 상품에 현지통화 가격 표시해야 함
  3. 인앱결제 이외의 결제수단은 허용되지 않음. (단, 가상의 서비스가 아닌 실물 상품 등을 제공하는 경우에는 가능), 가상 서비스 재화 등의 경우 쿠폰 코드 입력 화면도 사용할 수 없음.
  4. 인앱 구독상품이 타사 서비스에 영향을 주면 안됨
  5. TestFlight에서의 인앱 구매는 실제 결제가 되지 않기 때문에, 서버에서 별도 처리가 필요

용어 설명

  소모성 제품 (Consumable) 비소모성 제품 (Non-Consumable) 자동 갱신 구독 (Auto-renewable Subscription) 비갱신형 구독 (Non-renewable Subscription)
구매 가능 여부 여러 번 한 번만 여러 번 여러 번
영수증 표시 여부 한 번만 항상 항상 항상
기기간 동기화 여부 X 시스템에 따라 다름 시스템에 따라 다름 앱에 따라 다름
구매 복원 X 시스템에 따라 다름 시스템에 따라 다름 앱에 따라 다름

소모성 제품 (Consumable)

여러번 구입 가능한 제품. 앱 내 결제 복원 시에는 복원되지 않는 항목이며 아이템은 앱이나 서버에서 관리해야 합니다. (Apple에서 관리하지 않습니다)

구현 예시: 앱 내 유료 재화 (예: 보석) 등

앱 내에서만 데이터가 관리되는 경우, 앱 삭제 시 구매한 재화를 돌릴 수 있는 방법이 없으므로 외부 서버 등에서 관리되어야 하며 단순한 기능 잠금 해제 등의 경우 비소모성 제품 (Non-Consumable)을 이용해 구현해야 합니다. 비소모성 제품을 이용해 구현하면 구매 여부를 Apple에서 관리하므로, 별도의 서버 구현이 필요하지 않습니다.

비소모성 제품 (Non-Consumable)

Apple 계정당 한 번만 구입 가능한 제품. 앱 내 결제 복원 시에는 추가 구매없이 (재화 소모나 결제 없이) 복원되어야 하며 구매 항목은 Apple에서 관리합니다.

구현 예시: 광고 제거, 유료 게임 스테이지 잠금 해제 등

인 앱 상품을 구현할 때 구매 항목을 복원할 수 있는 버튼이나 메뉴가 앱에 존재해야 하며, 이 때 어떠한 추가 구매 절차 등이 들어가서는 안 됩니다. 또한, 구매 복원 시 구매한 항목은 바로 복원되어야 합니다.

자동 갱신 구독 (Auto-renewable Subscription)

특정 주기별로 자동 결제되는 제품. 앱 내 결제 복원 시에는 추가 결제 절차없이 복원되어야 하며 구매한 항목은 Apple에서 관리합니다. 사용자가 언제든지 앱을 통하지 않고서도 구독을  해지할 수 있습니다.  (Apple 계정 -> 구독 관리에서 해지 가능)

구현 예시: 일반판에서 전문가판으로 업그레이드 (매 주기마다 결제)

특정 주기별로 여러 개의 구독 상품을 만들 수 있으며 무료 체험 기간 또한 지정할 수 있습니다. 구독 상품을 구매했을 때의 혜택으로 앱의 유료 재화를 구독 기간동안 추가 제공하는 등의 상품도 만들 수 있습니다. 단, 구독 시 이용할 수 있는 컨텐츠의 범위가 확실하게 늘어나야 하며 구독 후 이용할 수 없는 상황이 와서는 안 됩니다.

구독 수수료는 기본적으로 타 항목과 동일한 30%이지만, 유저가 1년 이상 구독 한 경우 수수료는 해당 건에 한해 15%로 인하됩니다.

구독을 통해 제공하는 항목의 가격이 비정상적으로 비쌀 경우 Apple App Review 단계에서 Reject (거절) 될 수 있습니다.

비갱신형 구독 (Non-renewable Subscription)

한정 기간동안만 상품을 이용할 수 있도록 한 번만 결제하는 제품이지만 만료되면 다시 결제해야하는 제품. 결제 복원 여부는 앱이 결정하며, 구매 항목은 Apple에서 관리합니다. 다시 구독하려면 사용자가 다시 수동으로 결제해야 합니다. (자동으로 갱신되지 않음)

구현 예시: 프리미엄 스트리밍 컨텐츠 구독권

비갱신형 구독 상품의 경우, 앱 로그인을 필수로 요하는 경우 App Reject (거절) 사례가 종종 있다고 합니다.

참조 URL: https://stackoverflow.com/questions/17609347/restore-transactions-for-non-renewing-subscriptions-without-registration

구독 (Subscription)에 대하여

공식 소개 웹사이트: https://developer.apple.com/kr/app-store/subscriptions/

구독이란 금액을 지불하여 일정 기간동안 컨텐츠를 이용할 수 있도록 하는 일종의 서비스 제공 형태입니다. 각 플랫폼 (App Store 혹은 Google Play)에서 제공하는 구독 시스템을 사용하여 구현할 경우 각 플랫폼에서 구독에 대한 관리, 자동 결제 등을 도맡아 해줍니다.

수수료 (Fee)에 대하여

2020년 기준 기본적인 Apple의 인 앱 결제 수수료는 30%

  • 특정 유저가 자동 갱신 구독 (Auto-Renewable Subscription) 상품을 1년 이상 지속적으로 결제하는 경우, 해당 구독 건에 한해 그 이후의 결제분부터 수수료가 15%로 인하됨(단, 중간에 해당 유저가 정기 구독 결제를 취소한 후 60일이 지나면 결제 기간 누적이 취소됨)
  • 실제로 개발자가 받는 (추정) 수익금은 매출 – 수수료 – (세금)
  • 고객의 DCC (이중 환전 수수료)는 개발자가 지불하는 수수료와 아무 연관이 없음

가이드라인 공통사항

아래 내용은 인 앱 결제 구현 시 반드시 지켜야 하며 위반할 경우 앱이 거절 (Reject) 되거나 App Store에서 삭제될 수 있습니다.

  • 앱 내 구입 항목은 각 소속 앱 스토어 국가에 따른 화폐 단위 및 가격구매 버튼 혹은 아이템 설명에 표시되어야 합니다.

화폐 단위와 가격 표시는 하드 코드할 필요가 없으며, StoreKit API에 각 사용자별 App Store 지역에 따라 화폐 단위와 가격을 표시할 수 있도록 하는 기능이 내장되어 있습니다.

  • 앱에서 쿠폰 코드, 외부 결제 시스템 사용 등을 이용한 아이템 잠금을 구현해서는 안 됩니다.
    • 가이드라인에서는 In App purchase를 사용하여 잠금 해제하도록 강제하고 있습니다.
    • 다른 방법으로 결제하는 것을 유도해서도 안 됩니다. (계좌번호, 연락처 등을 표시하거나 다른 방법을 안내하는 문구 등)
    • 일부 게임, 앱 등에서는 쿠폰 코드 입력 화면을 고객센터 안쪽 링크로 감추거나, 심사 시에만 메뉴를 감추는 방법으로 우회 구현하고 있습니다. 
    • 이 사항으로 앱이 거절될 경우, 앱 심사 담당자에 따라 고객센터 전화번호나 메일 등이 들어가도 거절이 될 수 있습니다. (Apple 앱 심사는 일반적으로 앱 거절 시엔 담당자가 변경되지 않습니다.)
    • 쿠폰 코드를 사용하고 싶은 경우, App Store에서 제공하는 프로모션 코드를 통해 쿠폰 코드의 대체제로 사용할 수 있습니다. (https://help.apple.com/app-store-connect/?lang=ko#/dev50869de4a)

일부 게임에서는 소비 재화를 iOS 플랫폼에서만 수수료를 포함한 30% 인상된 가격에 판매하고 있습니다. (다른 결제 방법을 사용할 수 없기 때문에)

  • 상품이 앱 외부에서 사용하는 상품인 경우에는 앱 내 구입 방법 이외의 방법을 사용해야 합니다. 예를 들면:
    • Apple Pay
    • 신용 카드, 앱 결제
    • 기타 앱 내 구입 이외의 결제 방법

예: G마켓, 옥션, 쿠팡 등의 앱이 상품(물건) 구매를 위해 인 앱 결제를 사용하지 않음

  • 소비자가 구매한 항목은 연락처 업로드, 게시글 업로드, 특정 횟수만큼 앱 로그인 등의 어떠한 조건 없이 바로 사용이 가능해야 합니다.

예: 구매 후 미션을 클리어해야 구매한 항목을 사용할 수 있게 되는 등의 제약

소모성, 비소모성 제품 (Consumable, Non-Consumable)

  • 앱 내 크레딧(소모성 재화) 등은 사용 만료 기한이 없어야 하며 소모성 아이템 이외의 결제 항목모두 결제 복원이 가능해야 합니다. (구매 항목 복원 버튼의 구현 필요)

구매 항목 복원은 StoreKit API를 통해 구현할 수 있습니다. 

  •  인앱 결제 아이템은 다른 유저에게 선물로 보내는 목적으로도 개발할 수 있습니다.
  • 가챠(랜덤성 뽑기 / 랜덤박스) 아이템은 각 보상의 확률을 무조건 공개해야 합니다.
  • 비소모품 제품의 경우 ~일 체험 아이템을 만들 수 있으며 잠금 해제 후의 기능 명시가 확실하게 되어 있어야 하고, 체험 기간이 끝나면 얼마를 지불해야 하는지 명확히 표시해야 합니다.

구독형 제품 (Subscription)

  • 최소 구독 기간은 7일이여야 합니다.
  • 구독한 아이템의 내용이 타 서비스의 이용권/구독권으로써 이용될 수 없습니다.
  • 구독을 통해 소모성 크레딧 등을 제공할 수 있으며 소모성 크레딧 구매 등의 할인권으로써도 판매가 가능합니다.
  • 자동 갱신 구독은 무료 체험 기간을 제공할 수 있습니다.

가격 책정 (Pricing)

모든 상품의 가격은 정해진 등급과 대체 등급의 가격 중에서 선택해야 합니다. (약 200개 정도 있습니다.)

참고 문서: https://help.apple.com/app-store-connect/?lang=ko#/dev2acb77fcc

Apple에서 In App Purchase 상품을 심사할 때, 상품이 적절한 가치를 가지고 있는지도 평가합니다. 만약 가격이 너무 비싸다고 판단할 경우 App Reject이 될 수 있습니다.

영수증 검증 (Validate Receipt)

탈옥 (Jailbreak), 중간자 공격(man-in-the-middle attack) 등의 이유로 실제로 구매하지 않았으나 구매 처리가 되는 경우를 방지하기 위해 구입한 항목에 대해서 영수증 검증 처리가 있어야 합니다.

관련 문서:

API 문서: https://developer.apple.com/documentation/appstorereceipts/verifyreceipt

다계정 처리 (Multiple Apple Accounts)

한 사용자는 다수의 Apple 계정을 가질 수 있습니다. 영수증 데이터에 포함되지 않는 소모성 제품을 제외한 나머지 제품은 다수 계정에 대해 주기적으로 영수증 확인 및 결제 상태에 대한 상태 업데이트를 해 주어야 하며 이는 Receipt 데이터를 주기적으로 서버에 보내어 검증하는 것으로 해결할 수 있습니다.

관련 문서:

환불 처리 (Refund)

이전까지는 결제 항목에 대한 환불 여부를 알 수 없었고, 구독 취소에 대해서만 확인할 수 있었지만 2020년 WWDC부터 모든 유형의 결제 항목에서 환불 알림을 받을 수 있게 되었습니다.

관련 문서: https://developer.apple.com/documentation/storekit/in-app_purchase/handling_refund_notifications

결제 테스트 (Testing In-App Purchase)

결제 테스트는 App Store Connect에서 세금 및 지불 정보 관리가 모두 되어 있어야 결제 테스트가 가능하며 되어있지 않다면 테스트가 불가능 합니다. (결제시 오류 발생)

샌드박스 유저 및 TestFlight에서의 인앱 구매

샌드박스 유저로 인 앱 구매를 시도하거나, TestFlight를 통해 받은 앱에서는 인앱 구매 시 어떠한 대금도 청구되지 않습니다. 영수증 검증 시 TestFlight의 영수증을 서버에 첨부하면 테스트 구매라는 오류 코드가 발생하고, 테스트 서버에 첨부하면 정상 처리가 됩니다. 구매한 상품을 서버에서 관리하기 때문에 테스트 구매 또한 서버에서 별도 처리가 진행되어야 합니다.

구독 테스트 기간 (Sandbox subscription duration)

샌드박스 계정으로 결제하거나, TestFlight를 통한 테스트 결제 시 적용됩니다.

실제 구독 기간 테스트 시 기간
1주 3분
1개월 5분
2개월 10분
3개월 15분
6개월 30분
1년 1시간