게임 내 인앱 결제의 보안성을 위해서 클라이언트가 지급 받은 영수증과 Google API를 이용하여서
그 영수증이 유효한 영수증인지를 확인할 필요가 있다.
서버 검증이 진행되는 순서는 다음과 같다.
- 클라이언트의 요청이 오면 developerPayload(임의의 String)를 발급하고, 서버 DB등에 저장을 한다.
- 클라이언트가 서버에게 발급받은 developerPayload를 이용해서 구글 플레이에 결제요청을 하고, 그 결과로 받은 developerPayload를 서버에 보낸다.
- 서버는 클라이언트에게 받은 developerPayload가 자신이 발급한 developerPayload가 맞는지 확인한다.
- developerPayload가 일치하는지를 확인하고 그 결과를 보내준다.
- 일치한다면 클라이언트는 서버에 영수증 정보를 보내고, 서버는 그 영수s증 정보를 가지고 Google API에 검증요청을 한다.
- 검증이 완료되면 Client에게 상품을 지급한다.
여기서 3번 이후 과정에 대해서 자세히 설명해 보겠다.
구글 개발자 콘솔, 구글 플레이 개발자 콘솔 설정
먼저 구글 API를 사용하기 위해서는 Credential을 만들어야 한다.
에서 프로젝트를 생성을 한다.
생성을 한 후에 좌측 상단에 있는 메뉴 버튼을 눌러서 ‘권한’ 으로 이동한다.
여기서 서비스 계정 만들기를 클릭한다.
이렇게 생성을 하면 자동으로 내 컴퓨터에 json 파일이 다운로드 받아진다.
이 json 파일 내부에는 여러가지 정보가 기술되어 있다. 그리고 이 json 파일은 프로젝트 내부에서 접근할 수 있도록 관리를 한다.
그리고 API 관리자 개요에 들어가서 만든 프로젝트를 사용하도록 사용 버튼을 누른다.
여기까지가 google 개발자 콘솔에서 하는 작업이다.
이제 실제로 앱을 등록하는 Google Play Console에 들어간다.
왼쪽에 있는 설정을 누른다.
API 액세스에 들어가면 시작하기가 나오고 밑에 프로젝트들이 나열되어 있는데 이전에 만든 프로젝트를 클릭해서 사용하게 한다.
그러면 이제 사용준비가 완료가 된 것이다.
서버구현
파이썬을 이용하기 때문에 구글 api를 사용하기 위해서
$ pip install --upgrade google-api-python-client
를 이용해서 클라이언트 모듈을 설치를 한다.
이제 구글 API를 사용하기 위해서는 먼저 사용자가 API를 사용하기에 적합한 사용자인지를 검증해야한다.
그래서 Credentials 객체를 생성하도록 한다. 우리는 json파일을 받았기 때문에 다음과 같이 코드를 작성한다.
from oauth2client.service_account import ServiceAccountCredentials
scopes = ['https://www.googleapis.com/auth/androidpublisher']
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'app/google/Idletower-174c42ca2fb9.json', scopes)
credentials = ServiceAccountCredentials.from_json_keyfile_name(
'app/google/Idletower-174c42ca2fb9.json', scopes)
생성한 credentials 객체의 authorize 메소드를 이용해서 http 인스턴스를 생성하도록 한다.
from httplib2 import Http
http_auth = credentials.authorize(Http())
여기서
Client가 구글 플레이 스토어로 부터 받는 영수증 정보는 다음과 같다.
{
"orderId":"1299912121692121212121.1320812112121",
"packageName":"com.test.runrunrun",
"productId":"com.test.runrunrun.item_001",
"purchaseTime":1393377621833,
"purchaseState":0,
"purchaseToken":"sekadakadaaxgjhsrLn61wGoyAl..._8-l8zsUhVpY7o7Zq08s"
}
- orderId : 주문번호
- packageName : 앱의 패키지명(구글 내에서는 중복되지 않습니다.)
- productId : 상품 ID
- purchaseTime : 구매시각 ms 입니다.
- purchaseState : 구매상태
- purchaseToken : 구매 token
위의 정보 중에 Server가 필요로 하는 것은 세 가지 이다.
packageName, productId, purchaseToken
googleapiclient.discovery.build를 이용해서 build를 다음과 같이한다.
그리고 클라이언트에서 받아온 productId, packageName, token을 이용해서 api 호출을 한다.
from googleapiclient.discovery import build
androidpublisher = build('androidpublisher', 'v2', credentials=credentials, http=http_auth)
product = androidpublisher.purchases().products().\
get(productId=productId, packageName=packageName, token=token)
purchase = product.execute()
product = androidpublisher.purchases().products().\
get(productId=productId, packageName=packageName, token=token)
purchase = product.execute()
purchase는 다음과 같은 정보를 나타내고 JSON 객체이기 때문에 바로 사용이 가능하다.
{
"kind": "androidpublisher#productPurchase",
}
"kind": "androidpublisher#productPurchase",
"purchaseTimeMillis": long,
"purchaseState": integer, // 0 이면 구매 된 것, 1이면 cancel 된것
"consumptionState": integer, // 0 이면 아직 consume이 되지 않았고, 1이면 consumed된 것.
"developerPayload": string}
이 것을 이용해서 구매 확인을 하고 물품을 지급하면 된다.
'Developer > 모아두기' 카테고리의 다른 글
[AWS] 우분투 인스턴스 생성시 ssh 접속 에러 (mac) (0) | 2016.03.24 |
---|---|
[python] 파이썬 datetime 관련 (0) | 2016.03.24 |
(공유) python 내부 logging 모듈 사용하기 (0) | 2016.03.22 |
(공유) Flask에서 메일로 error 로그 보내기. (0) | 2016.03.22 |
(공유) 파이썬 코딩 컨벤션 (0) | 2016.03.17 |