강좌게시판

제목 [게임서버] 구글영수증 검증 (강좌마감)
글쓴이 ci세상 작성시각 2015/02/24 17:52:30
댓글 : 5 추천 : 0 스크랩 : 0 조회수 : 42590   RSS
<강좌마감하며>

간만에 심플한 강좌를 올려드렸네요^^

CI 코어는 그만큼 잘 되어 있어서 어떻게 활용 하는가에 따라서 최상의(?) 성능을 발휘 할 수 있는것 같습니다.

게임서버만큼 CI 코어 퍼포먼스를 자랑할 곳이 없는것 같았습니다.

게임서버 개발자분들께 CI코어 도입을 적극 도입 부탁드리며 구글영수증 검증으로 강좌를 마감합니다.

CI 포럼 좌측메뉴에 "CI게임 소개"란이 추가되길 간절히 기원합니다. ^^


<구글영수증 검증 설명>
모바일 게임은 대부분 인앱결제를 사용하는데요 결제가 성공하면 영수증을 검증해서 최종 포인트를 지급하게 됩니다.

클라이언트에서도 처리가 가능하지만 보안상 서버에서 처리하도록 권장하는 편입니다.

안드로이드만 샘플로 되어 있구요 아이폰, t스토어, 올레마켓등도 유사한 방식입니다.

이 과정을 생략하면 핵파일에 의해 무한대 포인트 충전당하여 게임 밸런스가 많이 무너지는 경우를 종종 보게 됩니다.^^


1. 사전준비
- 결제로그가 별도 파일로 저장되도록 코어가 확장되어 있어야 합니다.
http://www.cikorea.net/lecture/view/517/page/1

- file_get_contents 함수를 사용할 수 있도록 php.ini > allow_url_fopen 설정이 on되어 있어야 합니다.

- 구글 인앱결제와 관련한 문서를 사전 숙지가 필요로 합니다.
https://developers.google.com/android-publisher/archive/v1_1/
http://ideaargo.phps.kr/tc/182
http://cbkman1111.cafe24.com/Android_1/1310

2. 스트링추가
application/language/korean/payment_lang.php 파일추가
 
<?php
$lang["android_success"] = "결제 성공하였습니다.";
$lang["android_fail"] = "결제 실패하였습니다.";
3. 컨트롤추가
application/controllers/payment.php 파일추가  
 
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Payment extends CI_Controller {

    public function __construct() {
        parent::__construct();       
        $this->lang->load("payment","korean");
  $this->strings = $this->lang->language;

  // 공통헤더정보 (헤더값호출)
  $this->nation = "korean";
  $this->market = "android";
  $this->device = "android";
  $this->version = "v1.0.0";

  log_message('info', "API PATH : ".$_SERVER["REQUEST_URI"]);
    }

 /**
 * @Author : CI
 * @Date : 20150224
 * @Version : v1.0.0
 * @param : bill (영수증정보)
 * @param : token (토큰정보)
 * @Method 설명 : 결제완료처리
 */
 public function Index()
 {
  // IN DATA
  // 클라이언트로부터 전달된 파라미터를 받습니다.
  $bill = '{
  "orderId":"1299912121692121212121.1320812112121",
  "packageName":"com.test.runrunrun",
  "productId":"com.test.runrunrun.item_001",
  "purchaseTime":1393377621833,
  "purchaseState":0,
  "purchaseToken":"sekadakadaaxgjhsrLn61wGoyAl..._8-l8zsUhVpY7o7Zq08s"
  }'; // sample
  $token = '{
    "access_token" : "ya29.ZStBkRnGyZ2mUYOLgls7QVBxOg82XhBCFo8UIT5gM",
    "token_type" : "Bearer",
    "expires_in" : 3600,
    "refresh_token" : "1/zaaHNytlC3SEBX7F2cfrHcqJEa3KoAHYeXES6nmho"
  }'; // sample

  $this->billArr = json_decode($bill, true);
  $this->tokenArr = json_decode($token, true);

  log_message('info', "IN DATA : ".$bill);
  log_message('info', "IN DATA : ".$token);

  // 마켓별 영수증 재검증
  if($this->market == "android") {
   $data = $this->Android_Check();
  } else if($this->market == "iphone") {
   $data = $this->Iphone_Check();
  }

  // OUT DATA
  // 클라이언트로 데이터를 규격대로 전달해 줍니다.
  // 공백은 항시 NULL 처리를 필요로 합니다.

  $json["result"] = $data["result"];
  $json["message"] = $data["message"];

  $result = json_encode( $json );
  log_message('info', "OUT DATA : ".$result);

  echo $result;
 }


 /**
 * @Author : CI
 * @Date : 20150224
 * @Version : v1.0.0
 * @param : packageName (앱의 패키지명)
 * @param : productId (상품 ID)
 * @param : purchaseToken  (구매 토큰)
 * @param : access_token  (유효 토큰 )
 * @Method 설명 : 안드로이드 영수증 검증
 */
 public function Android_Check()
 {
  $sUrl = "https://www.googleapis.com/androidpublisher/v1.1/";
  $sUrl .= "applications/".$this->billArr["packageName"]."/";
  $sUrl .= "inapp/".$this->billArr["productId"]."/";
  $sUrl .= "purchases/".$this->billArr["purchaseToken"]."/";
  $sUrl .= "?access_token=".$this->tokenArr["access_token"];

  log_message('pay', "Google API URL : ".$sUrl);
  $rResult = @file_get_contents($sUrl);
  log_message('pay', "Google API DATA : ".$rResult);

  if ($rResult["purchaseState"] == 1) {
   $data['result'] = "Y";
   $data['message'] = $this->strings["android_success"];
  }
  else {
   $data['result'] = "N";
   $data['message'] = $this->strings["android_fail"];
  }

  return $data;
 }

 /**
 * @Author : CI
 * @Date : 20150224
 * @Version : v1.0.0
 * @Method 설명 : 아이폰 영수증 검증
 */
 public function Iphone_Check()
 {
 }


 /**
 * @Author : CI
 * @Date : 20150224
 * @Version : v1.0.0
 * @param : price (결제금액)
 * @Method 설명 : 결제처리
 */
 public function Point_Save()
 {
  // 결제로직 처리
 }
}



 
 다음글 queue 배치 작업 (1)
 이전글 [게임서버] 로그파일 분리하기 (1)

댓글

한대승(불의회상) / 2015/02/24 18:38:20 / 추천 0
와우!!! 결제 관련 부분까지 거의 모든걸 공개 하셨네요.
좋은 강좌 감사 드립니다.
변종원(웅파) / 2015/02/25 17:31:46 / 추천 0
좋은 정보 감사합니다. ^____^
아스초코 / 2015/04/01 14:47:07 / 추천 0
아 정리 완전 잘하신거 같아요!!
좋은 정보 잘 보고 갑니다!!
스미 / 2015/04/16 07:12:23 / 추천 0
고맙습니다.
아담 / 2016/07/28 18:07:27 / 추천 0

감사합니다. 정리 정말 잘하셨네요... 

아이폰 검증하는 부분은 없을가요?