SDK 디버그 메시지
0:05:00SDK 디버그 메시지를 이해하는 일은 문제 해결에 아주 중요합니다. 이 단계에서는 로깅을 활성화하는 방법과 자주 나타나는 로그 메시지를 해석하는 방법을 설명합니다.
디버그 로깅 활성화하기
SDK가 무엇을 하고 있는지 확인하려면 개발 중에는 항상 상세 로깅을 활성화하세요.
iOS (Swift)
swift
import RevenueCat
// configure 전에 활성화
Purchases.logLevel = .debug // 가장 상세한 수준
// Purchases.logLevel = .verbose // 대안
Purchases.configure(withAPIKey: "appl_xxx")Android (Kotlin)
kotlin
import com.revenuecat.purchases.LogLevel
// configure 전에 활성화
Purchases.logLevel = LogLevel.DEBUG // 가장 상세한 수준
// Purchases.logLevel = LogLevel.VERBOSE // 대안
val builder = PurchasesConfiguration.Builder(this, "goog_xxx")
Purchases.configure(builder.build())Log Level
- DEBUG: 가장 상세한 수준으로, 모든 내용을 보여 줍니다(개발 중에 사용).
- VERBOSE: 동작에 관한 자세한 정보를 보여 줍니다.
- INFO: 일반적인 정보성 메시지입니다.
- WARN: 잠재적 문제에 대한 경고입니다.
- ERROR: 오류 메시지만 보여 줍니다.
프로덕션: 프로덕션에서는 성능 오버헤드와 로그 혼잡을 피하기 위해 log level을
.warn 또는 .error로 설정하세요.
자주 나타나는 경고 메시지
경고: 상품이 승인되지 않음(iOS)
text
[RevenueCat] Warning: RevenueCat SDK is configured correctly, but contains some issues you might want to address
Warnings:
• Your products are configured in RevenueCat but aren't approved in App Store Connect yet.
This prevents users from making purchases in production.
Please ensure all products are approved and available for sale in App Store Connect.의미:
- RevenueCat 대시보드에는 상품이 존재합니다.
- 하지만 App Store Connect에서 아직 승인되지 않았습니다.
- 개발 중에는 정상적인 상황입니다.
필요한 조치:
- 테스트 중이라면 StoreKit Configuration File을 사용하거나 승인을 기다리세요.
- 프로덕션이라면 앱과 함께 상품을 심사에 제출하세요.
- 로컬 개발 중에는 무시해도 됩니다.
경고: Offering 구성 문제
text
[RevenueCat] Warning: The offerings 'default' have configuration issues that may prevent users from
seeing product options or making purchases.
Product Issues:
• Package 'monthly' references product 'premium_monthly' which is not available
• Package 'annual' references product 'premium_annual' which is not available의미:
- Offering의 패키지가 찾을 수 없는 상품을 참조하고 있습니다.
- 상품이 스토어에 존재하지 않거나 ID가 일치하지 않을 수 있습니다.
필요한 조치:
- RevenueCat과 스토어 사이에서 상품 ID가 일치하는지 확인하세요.
- 상품이 스토어에서 활성/승인 상태인지 확인하세요.
- 상품이 StoreKit Configuration에 추가되었는지 확인하세요(iOS).
자주 나타나는 오류 메시지
오류: 상품을 하나도 가져오지 못함
text
[RevenueCat] Error fetching offerings - The operation couldn't be completed.
(RevenueCat.OfferingsManager.Error error 1.)
There's a problem with your configuration. None of the products registered in the RevenueCat dashboard
could be fetched from App Store Connect (or the StoreKit Configuration file if one is being used).
More information: https://rev.cat/why-are-offerings-empty의미:
- SDK가 스토어에서 상품을 가져오려 했지만 모두 실패했습니다.
- 치명적인 구성 문제입니다.
필요한 조치:
- 상품 ID가 정확히 일치하는지 확인하세요.
- 번들 ID 및 패키지 이름이 일치하는지 확인하세요.
- iOS의 경우 StoreKit Configuration을 사용하거나 상품 승인을 기다리세요.
- Android의 경우 서비스 계정 권한을 확인하세요.
자세한 문제 해결 방법은 위의 Offering 가져오기 오류 단계를 참고하세요.
오류: 네트워크/API 문제
text
[RevenueCat] Error: Unable to fetch offerings
NetworkError: The Internet connection appears to be offline
URLError: The request timed out의미:
- 기기에 네트워크 연결이 없습니다.
- 또는 RevenueCat 서버에 연결할 수 없습니다.
필요한 조치:
- 기기의 인터넷 연결을 확인하세요.
- 다른 앱이나 웹사이트가 작동하는지 테스트하세요.
- VPN을 사용 중이라면 비활성화하세요.
- 앱에 재시도 로직을 구현하세요.
오류: 잘못된 API 키
text
[RevenueCat] Error: Invalid API key
The API key provided is invalid or doesn't have access to this app의미:
- API 키가 잘못되었거나 오타가 있습니다.
- 플랫폼에 맞지 않는 키를 사용하고 있습니다(Android에 iOS 키를 사용하거나 그 반대).
필요한 조치:
- RevenueCat 대시보드의 API keys로 이동하세요.
- 플랫폼에 맞는 올바른 키를 복사하세요.
- iOS:
appl_로 시작합니다. - Android:
goog_로 시작합니다.
- iOS:
- 코드를 업데이트하세요.
스토어 오류 코드 이해하기
iOS StoreKit 오류 코드
| 코드 | 이름 | 의미 |
|---|---|---|
| 0 | unknown | 알 수 없거나 예기치 못한 오류 |
| 1 | clientInvalid | 클라이언트가 요청을 보낼 수 없음 |
| 2 | paymentCancelled | 사용자가 구매를 취소함 |
| 3 | paymentInvalid | 구매 식별자가 유효하지 않음 |
| 4 | paymentNotAllowed | 기기에서 결제가 허용되지 않음 |
| 5 | storeProductNotAvailable | 스토어에서 상품을 사용할 수 없음 |
Android Billing 응답 코드
| 코드 | 이름 | 의미 |
|---|---|---|
| 0 | OK | 성공 |
| 1 | USER_CANCELED | 사용자가 구매를 취소함 |
| 2 | SERVICE_UNAVAILABLE | 네트워크 연결이 끊김 |
| 3 | BILLING_UNAVAILABLE | Billing API 버전이 지원되지 않음 |
| 4 | ITEM_UNAVAILABLE | 구매할 수 있는 상품이 아님 |
| 5 | DEVELOPER_ERROR | API에 잘못된 인자가 전달됨 |
| 6 | ERROR | API 동작 중 치명적 오류 발생 |
| 7 | ITEM_ALREADY_OWNED | 사용자가 이미 이 상품을 보유함 |
| 8 | ITEM_NOT_OWNED | 사용자가 상품을 보유하지 않음(복원) |
구매 흐름 로그 해석하기
성공적인 구매 흐름이 로그에서 어떻게 보이는지 살펴봅니다.
text
[RevenueCat] DEBUG: Fetching offerings from cache
[RevenueCat] DEBUG: Offerings retrieved successfully
[RevenueCat] DEBUG: makePurchase called for package: monthly
[RevenueCat] DEBUG: Starting purchase flow for product: premium_monthly
[RevenueCat] DEBUG: Purchase initiated
[RevenueCat] DEBUG: Finishing purchase transaction
[RevenueCat] DEBUG: Transaction finished successfully
[RevenueCat] INFO: Purchase completed successfully
[RevenueCat] DEBUG: CustomerInfo updated핵심 정리:
- 구매의 전체 생명주기를 보여 줍니다.
- 트랜잭션이 자동으로 완료됩니다.
- 구매 후
CustomerInfo가 업데이트됩니다.
자주 나타나는 SDK 메시지 빠른 참조
| 로그 메시지 | 의미 | 필요한 조치 |
|---|---|---|
| "Products not approved in App Store" | RevenueCat가 대시보드에서 상품을 찾았지만, 아직 Apple의 승인을 받지 못했습니다. | 개발 중에는 정상적인 상황입니다. 로컬 테스트에는 StoreKit Configuration File을 사용하거나, 앱 바이너리와 함께 상품을 심사에 제출하세요. 개발 중에는 무시해도 됩니다. |
| "Offering configuration issue" | 패키지가 스토어에서 찾을 수 없는 상품을 참조하고 있습니다. | RevenueCat과 스토어 사이에서 상품 ID가 일치하는지 확인하세요. 상품이 활성(Android) 또는 승인(iOS) 상태인지 확인하세요. Offering에서 더 이상 유효하지 않은 상품 참조를 제거하세요. |
| "None of the products registered" | 모든 상품을 스토어에서 불러오지 못했습니다. 치명적인 구성 오류입니다. | 상품 ID, 번들 ID 및 패키지 이름, API 키, 스토어 계정 상태를 확인하세요. 자세한 정보를 보려면 logLevel = .debug를 활성화하세요. 가장 흔하게 발생하는 연동 오류입니다. |
| "Error performing request" | RevenueCat API로의 네트워크 요청이 실패했습니다. | 인터넷 연결을 확인하세요. VPN이나 프록시를 잠시 비활성화하세요. api.revenuecat.com에 연결할 수 있는지 확인하세요. 일시적인 실패의 경우 SDK가 지수 백오프 방식으로 자동 재시도합니다. |
| "Invalid API Key" | Purchases.configure()에 전달된 API 키가 유효하지 않거나 플랫폼에 맞지 않습니다. |
RevenueCat 대시보드의 API keys로 이동하세요. 올바른 키를 복사하세요. iOS는 appl_, Android는 goog_입니다. 복사할 때 불필요한 공백이나 문자가 추가되지 않았는지 확인하세요. |
| "There is already a configure call" | 앱 생명주기 안에서 SDK가 두 번 이상 구성되고 있습니다. | Purchases.configure()는 한 번만 호출하세요. 보통 AppDelegate(iOS) 또는 Application.onCreate()(Android)에서 호출합니다. 서로 다른 앱 진입점(예: SceneDelegate, SwiftUI App init)에서 중복 호출이 있는지 확인하세요. |
| "Finishing transaction" | 정상적인 SDK 동작입니다. SDK가 스토어 트랜잭션을 완료하고 있습니다. | 별도의 조치가 필요 없습니다. 구매가 성공한 뒤에 나타나는 정상적인 메시지입니다. 대응하는 구매 없이 이 메시지가 보인다면, 이전에 완료되지 않은 트랜잭션을 마무리하는 중일 수 있습니다. |
| "CustomerInfo updated" | 사용자의 Entitlement 상태가 변경되었습니다. | 별도의 조치가 필요 없습니다. 구매, 복원, 구독 변경 후에 나타나는 정상적인 메시지입니다. UI를 갱신하려면 CustomerInfo 리스너에서 이 업데이트를 받아야 합니다. |
| SKError Code 0 (unknown) | iOS에서 StoreKit이 알 수 없는 오류를 반환했습니다. | 대개 일시적인 문제입니다. 작업을 다시 시도하세요. 계속된다면 Apple의 System Status를 확인하세요. 기기에서 샌드박스 계정을 로그아웃했다가 다시 로그인해 보세요. |
| SKError Code 2 (paymentCancelled) | 사용자가 구매 다이얼로그를 취소했습니다. | 별도의 조치가 필요 없습니다. 오류 메시지를 띄우지 않도록 앱에서 자연스럽게 처리하세요. 사용자가 구매를 진행하지 않기로 선택한 것입니다. |
| BillingResponseCode 1 (USER_CANCELED) | 사용자가 Google Play 구매 다이얼로그를 닫았습니다. | 별도의 조치가 필요 없습니다. iOS의 취소와 동일합니다. 자연스럽게 처리하고, 사용자가 준비되면 다시 시도할 수 있게 하세요. |
| BillingResponseCode 3 (BILLING_UNAVAILABLE) | 기기에서 Google Play Billing을 사용할 수 없습니다. | 기기에 Google Play 스토어가 설치되어 있고 최신 상태인지 확인하세요. 기기에 Google 계정이 로그인되어 있는지 확인하세요. 에뮬레이터는 "Google APIs"가 아니라 "Google Play" 시스템 이미지를 사용해야 합니다. |
| BillingResponseCode 5 (DEVELOPER_ERROR) | 잘못된 인자가 전달되었거나 Google Play에서 앱이 잘못 구성되었습니다. | 패키지 이름이 일치하는지, 앱이 테스트 트랙에 게시되었는지, 상품 ID가 존재하는지 확인하세요. 보통 Google Play Console 구성이 앱 빌드와 일치하지 않을 때 발생합니다. |
| "Purchases not completed" | 구매가 시작되었지만 끝나지 않았습니다. | 구매 중에 앱이 포그라운드에 머물도록 하세요. Android에서는 `Activity`가 다시 생성되고 있지 않은지 확인하세요. iOS에서는 구매 콜백이 UI 스레드 작업에 막히고 있지 않은지 확인하세요. |
| ConfigurationError Code 23 | 일반적인 구성 오류 래퍼입니다. 실제 원인은 하위 오류에 담겨 있습니다. | 하위 오류를 확인하려면 전체 오류 객체를 로그로 출력하세요(JSON.stringify(e) 또는 userInfo 확인). 상품 ID 불일치, Google Play의 하위 호환성 누락, 서명하지 않은 계약이 흔한 원인입니다. 커뮤니티 토론을 참고하세요. |
| "BillingClient is not connected yet" | BillingClient의 연결이 끝나기 전에 SDK가 Play 스토어에 쿼리했습니다. | SDK가 재연결을 자동으로 처리합니다. 기기에서 Google Play 서비스가 최신 상태인지 확인하세요. configure() 직후에 Offering을 가져오지 마세요. 연결 처리가 개선된 최신 SDK 버전으로 업데이트하세요. 커뮤니티 토론을 참고하세요. |
| 로그인/로그아웃 후 Entitlement 손실 | 구매가 익명 ID에 연결되어, logIn() 이후에 이어지지 않았습니다. |
인증 직후, 어떤 구매보다도 먼저 사용자 ID로 Purchases.logIn()을 호출하세요. 인증 상태가 바뀐 뒤에는 syncPurchases()를 구현하세요. 대비책으로 사용자에게 "Restore Purchases"를 안내하세요. 커뮤니티 토론을 참고하세요. |
부여한 Entitlement이 getCustomerInfo()에 없음 |
서버 측에서 Entitlement을 부여한 뒤 SDK 캐시가 갱신되지 않았습니다. | 새로 가져오도록 강제하려면 getCustomerInfo() 전에 Purchases.shared.invalidateCustomerInfoCache()를 호출하세요. SDK는 고객 정보를 5분간 캐시합니다. 서버 측 변경(예: 프로모션 부여)에는 캐시 비우기가 필요합니다. 커뮤니티 토론을 참고하세요. |
효과적인 디버깅을 위한 팁
- 문제를 해결할 때는 항상 디버그 로깅부터 활성화하세요.
- SDK 메시지만 걸러 보려면 로그에서 "RevenueCat"을 검색하세요.
- 오류와 경고를 빠르게 찾으려면 오류 및 경고 기호를 살펴보세요.
- 각 작업(Offering 가져오기, 구매, 복원) 직후에 로그를 확인하세요.
- 지원을 요청할 때는 전체 오류 메시지를 복사하세요.
- 성능 문제를 피하려면 프로덕션에서는 비활성화하세요.