본문 바로가기

Programming

[google API] 정기구독 결제 검증하기

이 망할 구글 플레이ㅎㅎ

구글링하면 전부 최근 버전이 없어서 삽질을 반복에 반복했다.

 

여기저기 선배님들께서 남기신 포스팅에 기웃거리면서 짬뽕으로 어찌저찌 완성..

 

gcp(google cloud platform) > API 및 서비스 > 사용자 인증 정보 에서 OAuth 2.0 클라이언트 생성&서비스 계정 생성

google play console > 설정 > API 액세스 > gcp에 등록한 프로젝트 연결 및 클라이언트, 서비스 계정 불러왔는지 확인

(이 때 불러온 서비스 계정의 권한에서 재무데이터 보기는 꼭 체크해줘야함)

 

그리고 발급된 OAuth 클라이언트 아이디랑 시크릿키로 authorization code > Refresh token&Access token 순서로 발급

구글링해서 찾은 포스팅부터 유튜브 생활코딩 강의까지 겁나 참고하고 짬뽕하면 완성이 가능하다

*참고한 포스팅*

https://ndb796.tistory.com/309 (gcp, google play console 관련 설정 상세설명)

https://smarthink.tistory.com/24 (code, token 발급관련 참고)

https://movefast.tistory.com/104 (참고할 링크들이 많음)

https://blog.naver.com/ssplas/220884235186

 

authorization code, Refresh token, Access token 생성은 구글플레이그라운드에서 하면 편리하다

https://developers.google.com/oauthplayground

https://opens.kr/97 (플레이그라운드 상세 설명 참고)

 

구글 공식 레퍼런스

https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions/get

 

Method: purchases.subscriptions.get  |  Google Play Developer API  |  Google Developers

Method: purchases.subscriptions.get Checks whether a user's subscription purchase is valid and returns its expiry time. HTTP request GET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/{packageName}/purchases/subscriptions/{subscri

developers.google.com

https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions#SubscriptionPurchase

 

REST Resource: purchases.subscriptions  |  Google Play Developer API  |  Google Developers

REST Resource: purchases.subscriptions Resource: SubscriptionPurchase A SubscriptionPurchase resource indicates the status of a user's subscription purchase. JSON representation { "kind": string, "startTimeMillis": string, "expiryTimeMillis": string, "auto

developers.google.com

정기 구독이 아닌 일회성 결제의 경우 subscriptions가 아니고 products 참고하면 됨

 

access token은 대략 한시간 단위로 갱신해서 사용해야하기 때문에 구독검증을 위해 크론을 실행할 때마다 새로운 토큰을 받아와서 서버에 있는 데이터와 대조하도록 한다.

 

//refresh token을 사용하여 access token을 갱신하고 api를 호출한다.
//https://developers.google.com/oauthplayground 에서 테스트 가능
$param = array(
    'refresh_token' => '1//********************gie$g9shrew/4j94',
    'client_id' => '790000wefwf003-egwe5w64g***********.apps.*************.com',
    'client_secret' => 'GWEF40gsdr.042glksjdgx.aafwe-******8',
    'grant_type' => 'refresh_token',
);

$ch = curl_init();
curl_setopt( $ch, CURLOPT_URL, 'https://oauth2.googleapis.com/token' );
curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded') );
curl_setopt( $ch, CURLOPT_HEADER, 0 );
curl_setopt( $ch, CURLOPT_POST, TRUE );
curl_setopt( $ch, CURLOPT_POSTFIELDS, http_build_query($param) );
curl_setopt( $ch, CURLOPT_TIMEOUT, 300 );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, false );

$result = curl_exec($ch);
if ($result === FALSE) {
    die('Curl failed: '.curl_error($ch));
}
curl_close($ch);
$tres = json_decode($result);

$re_access_token = $tres->access_token;

$query = "구독을 검증할 영수증 데이터(purchases token)값을 불러오는 쿼리";
$list = sql_fetch_query($query);
foreach ($list as $row) {
    $receipt_status = GoogleInappPurchaseVerify($row['purcharse_token'], $re_access_token);
    if($receipt_status == '1') { //상태값이 1이면 영수증 정상.
       //구독갱신중
    }else{
       //구독중아님(회원등급강등 or 상황에 맞는 처리)
    }
}


function GoogleInappPurchaseVerify($purchase_token, $access_token){
    $package_name = "package name";
    $product_id = "product id";

    $sUrl = "https://androidpublisher.googleapis.com/androidpublisher/v3/";
    $sUrl .= "applications/{$package_name}/";
    $sUrl .= "purchases/subscriptions/{$product_id}/";
    $sUrl .= "tokens/{$purchase_token}/";
    $sUrl .= "?access_token={$access_token}";
    $rResult = file_get_contents("$sUrl");
    
    // 리턴값 https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.subscriptions#SubscriptionPurchase 참고해서 상황에 맞게 수정가능

    if (!$rResult || $rResult=="") {
        return "error";
    }
    else {
        return $rResult['paymentState'];
    }
}

 

 

++++++++++++++++++++++++++ 2023.04.17 추가 ++++++++++++++++++++++++++

 

전 플젝에선 함께 작업한 프론트 개발자분이 구글 설정등을 모두 해두셨던 상황이라 정말 결제 검증 부분만 했던 것..

+ 내가 한 포스팅인데 텍스트를 제대로 안읽음의 환장파티로 인해

이번에 아무것도 안되어있는 상태로 저 소스만으로 개발할려고 하다가 삽질을 좀 했다..ㅎㅎ

지금보니깐 설정해줘야 하는부분 텍스트로 설명이 있는데 왜...저걸 안보고 무슨 자신감이였을까

구글클라우드 설정부분
구글 플레이콘솔의 설정 부분

 

해당 두가지가 모두 맞게 설정이 되어있지 않으면 플레이그라운드에서는 성공적으로 토큰이 발급되지만

실제 개발소스에서는 토큰 발급이 에러가 뜬다...ㅎㅎ

물론 개발환경도 방화벽이나 기타 사항들 등등을 체크도 해야함