ALC(Application License Checker) V2 적용

개요

ALC V2(Application License Checker V2)는 원스토어에서 제공하는 앱 라이선스 검증 서비스의 최신 버전으로, 유료 앱 및 인앱 구매 콘텐츠의 무단 사용을 방지하고, 정품 사용자만 앱을 이용할 수 있도록 보장하는 기능을 제공합니다.

프로젝트 설정

레파지토리 및 종속 항목 추가

프로젝트 최상위 gradle 파일에 원스토어 maven 주소를 등록합니다.

Android Studio (version: bumblebee) 이상에서는 settings.gradle파일에서 추가합니다.

repositories {
    maven { url 'https://repo.onestore.net/repository/onestore-sdk-public' }
}

앱의 build.gradle 파일에 원스토어 결제 라이브러리 종속 항목을 추가합니다.

dependencies {
    implementation "com.onestorecorp.sdk:sdk-licensing:2.2.1"
}

<queries> 태그 설정

AndroidManifest.xml 파일에 <queries>를 설정 해야합니다. 자세한 내용은 공지사항을 참조하세요.

<manifest>
    <!-- 
        if your binary use ONE store's In-app SDK,
        Please make sure to declare the following query on Androidmanifest.xml. 
        Refer to the notice for more information.
        https://dev.onestore.net/devpoc/support/news/noticeView.omp?noticeId=32968
     -->
    <queries>
        <intent>
            <action android:name="com.onestore.extern.licensing.LicensingService.ACTION" />
        </intent>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="onestore" />
        </intent>
    </queries>
    ...
    <application>
        ...
    </application>
</manifest>

스토어 선택을 위한 개발자 옵션 설정

v2.2.0 업데이트 - 글로벌 스토어 선택 기능 추가

ALC SDK 2.2.0 부터 아래와 같이 onestore:dev_optionandroid:value 값을 설정하면, SDK와 연동되는 스토어 앱을 지정 할 수 있습니다.

<manifest>
    <application>
        <meta-data android:name="onestore:dev_option" android:value="onestore_01" />
    </application>
</manifest>
값 (android:value)
적용 대상 국가

onestore_00

대한민국 (South Korea) (기본값)

onestore_01

싱가포르, 타이완 (Singapore, Taiwan)

onestore_02

미국 – Digital Turbine (United States)

ALC 라이브러리 적용하기

로그 레벨 설정

개발 단계에서 로그 레벨을 설정하여 SDK의 데이터의 흐름을 좀 더 자세히 노출할 수 있습니다. android.util.Log에 정의된 값을 기반으로 동작합니다.

/**
 * Set the log level.<br/>
 * {@link Log#VERBOSE}, {@link Log#DEBUG}, {@link Log#INFO},
 * {@link Log#WARN}, {@link Log#ERROR}
 * @param level int
 */
com.gaa.sdk.base.Logger.setLogLevel(2)
상수

VERBOSE

2

DEBUG

3

INFO (default)

4

WARN

5

ERROR

6

원스토어 로그인 하기

GaaSignInClient 초기화

GaaSignInClient는 원스토어 로그인을 하기 위한 라이브러리입니다. getClient() 통해 인스턴스를 생성합니다.

val signInClient = GaaSignInClient.getClient(activity)

백그라운드에서 로그인하기

silentSignIn() 통해 백그라운도 로그인을 호출합니다.

사용자가 이미 원스토어 계정에 로그인 되어있을 경우 이후 부터는 백그라운드에서 토큰로그인을 시도합니다. 성공 또는 실패에 대한 결과값으로 SignInResult 객체로 응답을 받습니다.

signInClient.silentSignIn { signInResult ->
  
}

포그라운드에서 로그인하기

slientSignIn()과 달리 해당 함수는 UiThread 에서만 호출해야 합니다.

기본적으로 먼저 백그라운드 로그인을 시도하지만 실패에 대한 처리를 SDK에서 전담하여 처리합니다. 이 후, 로그인 화면을 띄워 사용자에게 로그인을 유도합니다.

signInClient.launchSignInFlow(activity) { signInResult ->
  
}

AppLicenseChecker 초기화

AppLicenseChecker란?

AppLicenseChecker는 개발사가 유료 앱을 판매할 때 라이선스 무단 사용을 방지하고 정품 사용자만 앱을 이용할 수 있도록 보호하는 기능을 제공합니다. 이를 통해 앱이 불법적으로 배포되거나 무단으로 사용되는 것을 차단할 수 있습니다.

초기화 방법

유효한 라이선스를 확인하려면 AppLicenseChecker의 인스턴스를 생성해야 합니다.

초기화 과정에서는 개발자 센터에서 발급받은 라이선스 키를 전달해야 하며, 라이선스 검증 결과는 LicenseCheckerListener를 통해 확인할 수 있습니다. 따라서, AppLicenseChecker 초기화 시 리스너 객체도 함께 설정해야 합니다.

override fun onCreate(savedInstanceState: Bundle?) {
	super.onCreate(savedInstanceState)
	val appLicenseChecker = AppLicenseChecker.get(this@MainActivity, getString(R.string.public_key, new AppLicenseListener())
}

...
inner class AppLicenseListener : LicenseCheckerListener {
	override fun granted(license: String, signature: String) {}

	override fun denied() {}  
	
	override fun error(code: Int, message: String) {}
} 

라이선스 키 발급

라이선스 키는 개발자 센터에서 앱을 등록할 때 자동으로 발급됩니다.

LicenseCheckerListener 설정

LicenseCheckerListener 등록

AppLicenseChecker를 초기화할 때, 반드시 LicenseCheckerListener를 등록해야 합니다.

이 리스너는 라이선스 검증 결과를 처리하는 인터페이스로, 검증이 완료되면 반드시 해당 인터페이스의 메서드 중 하나가 호출됩니다.

LicenseCheckerListener 메서드

LicenseCheckerListener는 다음 세 가지 메서드를 제공합니다.

Method
Description

granted()

라이선스가 정상적으로 확인된 경우 호출됩니다.

denied()

라이선스가 유효하지 않거나 인증에 실패한 경우 호출됩니다.

error(int errorCode,String errorMessage)

라이선스 검증 중 오류가 발생한 경우 호출되며, 에러 코드와 메시지를 함께 제공합니다.

에러 코드 참고

error() 메서드에서 제공하는 에러 코드 및 응답 메시지에 대한 상세 내용은 아래 응답 코드 표를 참고하세요.

class AppLicenseListener : LicenseCheckerListener {
    override fun granted(license: String, signature: String) {
        // License check successful
    }

    override fun denied() {
        // License check denied
    }  
    
    override fun error(code: Int, message: String) {
        // License check error occurred
    }
}

라이선스 검증 요청하기

앱에서 라이선스 검증을 요청하면, 원스토어 서버와 통신하여 사용자의 구매 라이선스를 확인합니다. 그러나 네트워크 장애, 비행기 모드 등의 이유로 서버에 접근할 수 없는 경우 앱 실행이 차단될 수 있습니다.

이를 방지하기 위해, 일반적으로 캐시 정책을 사용하여 로컬에 저장된 라이선스를 기반으로 앱을 실행할 수 있도록 보장합니다.

만약 캐시된 라이선스를 사용하지 않고 실시간 검증을 원할 경우, strictQueryLicense API를 사용하면 항상 원스토어 서버에서 최신 라이선스를 조회할 수 있습니다.

QueryLicense API (Cached API) 호출

캐시 정책을 적용하여 동작하는 라이선스 검증 API입니다.

  • 기본적으로 원스토어 서버와 통신하여 사용자의 구매 라이선스를 확인합니다.

  • 그러나 네트워크 장애, 비행기 모드 등으로 서버에 접근할 수 없는 경우, 로컬에 저장된 라이선스를 이용하여 앱 실행을 보장합니다.

  • 로컬 캐시에 저장된 라이선스는 유효 기간 내에서만 사용 가능하며, 만료되면 서버와 다시 통신해야 합니다.

이 방식은 사용자 경험을 개선하고, 일시적인 네트워크 문제로 인해 앱 실행이 차단되는 것을 방지하는 데 유용합니다.

appLicenseChecker.queryLicense()

StrictQueryLicense API (Non-Cached API) 호출

StrictQueryLicense API는 캐시된 라이선스를 사용하지 않고, 항상 원스토어 서버에서 최신 라이선스를 조회하는 방식입니다.

  • 캐시를 사용하지 않기 때문에, 항상 최신 라이선스 정보를 기반으로 검증이 이루어집니다.

  • 그러나 네트워크 장애, 비행기 모드 등의 상황에서는 원스토어 서버에 접근할 수 없기 때문에, 라이선스 검증이 실패하면 앱을 사용할 수 없습니다.

  • 보안이 중요한 경우 유용할 수 있지만, 네트워크 문제로 인해 앱 사용이 제한될 수 있으므로 사용 목적에 맞게 신중히 선택해야 합니다.

appLicenseChecker.strictQueryLicense()

연결 해제

원스토어 서비스와의 불필요한 연결을 방지하고 리소스를 적절히 해제하기 위해, 더 이상 라이선스 검증이 필요하지 않을 경우 AppLicenseCheckerdestroy() 메서드를 호출하여 연결을 해제하는 것을 권장합니다.

이렇게 하면 메모리 누수를 방지하고, 불필요한 서비스 호출을 차단하여 앱의 성능을 최적화할 수 있습니다.

appLicenseChecker.destroy()

StoreEnvironment API 기능 추가

StoreEnvironment.getStoreType() API는 SDK가 탑재된 애플리케이션이 원스토어를 통해 설치되었는지를 판단하는 기능을 제공합니다.

Store Type 정의

해당 API는 StoreType을 반환하며, 아래 네 가지 값 중 하나를 가집니다.

StoreType
value
description

StoreType.UNKNOWN

0

앱 설치 스토어 정보를 알 수 없음 (APK 직접 설치, 출처 불명 등)

StoreType.ONESTORE

1

ONE Store에서 설치됨 (또는 개발자 옵션이 활성화된 경우)

StoreType.VENDING

2

Google Play Store에서 설치됨

StoreType.ETC

3

기타 스토어에서 설치됨

API 사용 방법

해당 API는 StoreEnvironment.getStoreType()을 호출하여 사용할 수 있습니다.

import com.gaa.sdk.base.StoreEnvironment

val storeType = StoreEnvironment.getStoreType()

when (storeType) {
    StoreType.ONESTORE -> println("ONE Store에서 설치된 앱입니다.")
    StoreType.VENDING -> println("Google Play Store에서 설치된 앱입니다.")
    StoreType.ETC -> println("기타 스토어에서 설치된 앱입니다.")
    StoreType.UNKNOWN -> println("스토어 정보를 알 수 없습니다.")
}

스토어 판단 기준

이 API는 세 가지 방법을 통해 설치된 스토어를 판별합니다.

  1. 원스토어 마켓 서명을 통해 배포된 경우

    1. 원스토어의 마켓 서명을 통한 배포 여부를 확인하여, 원스토어에서 설치된 앱인지 확인합니다.

  2. Installer Package Name을 기반으로 판별

    1. 원스토어의 마켓 서명을 통해 배포되지 않은 경우, PackageManager.getInstallerPackageName() API를 이용하여 앱 설치 시 사용된 스토어 정보를 확인합니다.

  3. 개발자 옵션(onestore:dev_option)이 활성화된 경우

    1. onestore:dev_option 이 설정 되어있으면 무조건 StoreType.ONESTORE로 응답합니다.

활용 예시

스토어별 UI 차별화 적용

원스토어와 다른 앱 마켓에서 제공하는 결제 시스템이 다를 경우, UI를 다르게 설정할 수 있습니다.

if (StoreEnvironment.getStoreType() == StoreType.ONESTORE) {
    showOneStorePaymentUI()
} else {
    showDefaultPaymentUI()
}

스토어별 기능 차단

특정 기능을 원스토어에서만 사용하도록 설정할 수 있습니다.

if (StoreEnvironment.getStoreType() != StoreType.ONESTORE) {
    println("이 기능은 ONE Store에서만 사용할 수 있습니다.")
    return
}
enableOneStoreExclusiveFeature()

응답 코드

다음 표는 원스토어 ALC 라이브러리에서 앱으로 전달되는 에러 응답 코드 및 메시지입니다.

라이브러리를 사용하는 앱에서는 각 응답 코드에 대해 적절한 처리를 수행해야 합니다.

Response Code
Value
Description(KR)
Description(EN)
How to handle

RESULT_OK

0

성공

Success

ERROR_CLIENT_NOT_ENABLED

1010

원스토어에 연결할 수 없습니다. 원스토어 앱 실행이 필요합니다.

Unable to connect to the store. ONE store app execution is required.

ERROR_SERVICE_UNAVAILABLE

2000

서비스를 이용할 수 없는 상태입니다.

The service is unavailable.

원스토어에 문의해주세요.

ERROR_DATA_PARSING

2001

파라메터가 유효하지 않습니다.

Parameter is invalid.

원스토어에 문의해주세요.

ERROR_SIGNATURE_VERIFICATION

2002

라이선스 키가 맞지 않거나 구매 내역이 없는 유저 입니다.

The license key is not matched, or the user does not have a purchase history.

원스토어 개발자 센터에서 라이선스 키를 확인해주세요.

ERROR_SERVICE_TIMEOUT

2100

서비스 응답이 없습니다.

There is no response.

네트워크 상태를 체크해주세요.

ERROR_USER_LOGIN_CANCELD

2101

사용자가 로그인을 취소하였습니다.

User canceled login.

원스토어 로그인을 해주세요.

ERROR_INSTALL_USER_CANCELED

2103

원스토어 서비스 설치를 취소하였습니다.

ONE store install has been canceled. Do you want to ONE store installation?

원스토어를 설치해주세요.

ERROR_NOT_FOREGROUND

2104

백그라운드 서비스에서는 진행할 수 없습니다.

Can not run the context is not instance of Activity.

RESULT_UNKNOWN

-1

알 수 없는 오류가 발생하였습니다.

An unknown error occurred.

원스토어에 문의해주세요.

RESULT_USER_CANCELED

1

사용자가 로그인을 취소하였습니다.

User canceled login.

원스토어 로그인을 해주세요.

RESULT_SERVICE_UNAVAILABLE

2

단말 또는 서버 네트워크 오류가 발생하였습니다.

A device or server network error has occurred.

네트워크 상태를 체크해주세요.

RESULT_ALC_UNAVAILABLE

3

ALC api 버전 정보가 낮습니다. 해당 라이브러리를 업데이트 해주세요.

The ALC api has the lower version. Please update the corresponding library.

ALC 라이브러리를 최신버전으로 업데이트 해주세요.

RESULT_DEVELOPER_ERROR

5

파라메터가 유효하지 않습니다.

The parameter is invalid.

원스토어에 문의해주세요.

RESULT_ERROR

6

정의되지 않은 기타 오류가 발생하였습니다.

An unknown error occurred.

원스토어에 문의해주세요.

Last updated