Google Play 소모성 상품에 대해서, 가장 최근 예약된 구매건인데 소모처리 안되었다면 조회(모바일/PC 공용)

기본 정보

  1. Google Play에서 유저가 구매를 진행했고 금액 청구까지 되었지만, 클라이언트가 어떤 사유로 종료되어서 게임서버 및 빌링에 완료 요청이 전달되지 않은 데이터 단건을 조회하는 클라이언트(SDK)전용 API

  2. 해당 API를 이용해서 클라이언트 사이드에서 발생한 실패 건을 재 처리에 구현하는데 사용 가능

    1. 클라이언트가 예약 시점에 boid를 저장하지 않았을 경우에 사용할 수 있음

    2. boid가 있다면 기존 프로세스 그대로 사용 가능

항목
내용
비고

호출주체

게임 클라이언트(또는 Game Platform SDK)

HTTP 메소드

POST

Content-Type

application/json

Request

HTTP Request end point

POST https://각 환경별 빌링시스템 도메인 /billing/him-platform-sdk/v1/google/play/common/getLatestReservedNotConsumed

HTTP Request Parameter

  • Content-Type: application/json 으로 요청되어야 합니다.

이름
데이터 타입
설명

pjid

String(20)

프로젝트ID

  • 동일 게임이라면 서비스ID가 여러개일 수 있지만 프로젝트ID는 같음

1004

appStore

String

앱을 다운로드한 플랫폼 스토어

  • 구글 모바일과 PC를 구분해서 응답해줘야해서 파라미터로 전달 받음

  1. 모바일: GOOGLE_PLAY

  2. 구글PC: GOOGLE_PLAY_PC

playerId

String

대상 유저 ID

  • 해당 id로 게임서버는 빌링API에 예약을 진행했어야함

googleOrderId

String

Google의 'orderId'(주문ID)

GPA.3340-4023-4149-75538

googlePurchaseToken

String

Google의 purchaseToken

googleProductId

String

Google의 'productId'(구매한 상품ID)

googleResponseOriginJson

String

SDK 등에서 얻은 구글에서 응답온 JSON 원본 전문

  • 추가 필드가 필요할 때 SDK 배포 없이 기능 구현을 위해서 전문을 받음

아래 참고

googleResponseOriginJson 예시

{
    "kind": "androidpublisher#productPurchase",
    "purchaseTimeMillis": 1704950296551,
    "purchaseState": 0,
    "consumptionState": 0,
    "orderId": "GPA.3340-4023-4149-75538",
    "purchaseType": 0,
    "acknowledgementState": 0,
    "purchaseToken": "ogkbpllihcbjbifglbceoihe.AO-J1OwtOCXpN6cE5ULFcLqwbjYIzbtcWWldhHTUPAe-poGQEPvMP9tfcKkWXFEZ68_b2E9j1cWBx-Gw6xOKS9nqkG_gX2Ljig",
    "productId": "item.bag.blue",
    "regionCode": "KR"
}

Response

응답은 JSON형태로 전달됩니다.

  • 대상 데이터가 존재하는 경우에만 resultData가 리턴되며 존재하지 않는 경우에는 null 입니다.

    • 예) 예약된 데이터가 없거나, 예약되었더라도 이미 소모처리된 경우에는 null

Response property

key

data type

description

example

boid

String(20)

빌링 시스템의 주문ID

4

reservedAtUnixTS

Long

빌링 시스템에 예약처리된 일시 유닉스 Time stamp

1707900667

Sample

Success sample

  • 해당 유저의 가장 마지막 예약된 데이터 1건을 조회 후 → 구글 API를 통해서 상태정보 체크 결과 대상 데이터인 경우

    • 구글에 구매 요청되었지만 아직 소모처리 안되어서 소모처리 가능한 상태로 구글 API가 응답한 데이터

{
    "resultCode": "SUCCESS",
    "resultMessage": "There is data that was most recently reserved but has not been consumed.",
    "resultData": {
        "boid": "17",
        "reservedAtUnixTS": 1707900667
    }
}

Error sample

  • 해당 유저가 예약한 데이터가 존재하지 않음

{
    "resultCode": "SUCCESS",
    "resultMessage": "Request success. But not exist reserved data.",
    "resultData": null
}
  • 잘못된 purchase token으로 요청되어 구글 API가 에러 발생

{
    "resultCode": "EXTERNAL_API_ERROR",
    "resultMessage": "Google Play Developer API(purchases.products.get) error: '400 Bad Request\nGET https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.hybeim.intheseom/purchases/products/item.bag.blue/tokens/ogkbpllihcbjbifglbceoihe.AO-J1OwtOCXpN6cE5ULFcLqwbjYIzbtcWWldhHTUPAe-poGQEPvMP9tfcKkWXFEZ68_b2E9j1cWBx-Gw6xOKS9nqkG_gX2Ljig\r\n{\n  \"code\": 400,\n  \"errors\": [\n    {\n      \"domain\": \"androidpublisher\",\n      \"location\": \"token\",\n      \"locationType\": \"parameter\",\n      \"message\": \"The purchase token does not match the package name.\",\n      \"reason\": \"purchaseTokenDoesNotMatchPackageName\"\n    }\n  ],\n  \"message\": \"The purchase token does not match the package name.\"\n}'",
    "resultData": null
}
  • 가장 최근 구매 예약건이 소모처리 불가능한 경우

{
    "resultCode": "SUCCESS",
    "resultMessage": "Request success. But Current consumptionState is '1' not allow(from google). boid:'17' | see https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products.",
    "resultData": null
}

에러 코드 정의

  • resultCode에 올 수 있는 에러 코드입니다.

  • SDK 스펙상 해당 코드일 경우에도 상태코드는 200으로 리턴 됩니다.

에러코드
비고

INVALID_PARAMETER

EXTERNAL_API_ERROR

빌링 API가 호출하는 외부 API가 에러인 경우

  • 예) 구글 API 장애로 구매의 상태 정보를 받아오지 못하는 경우

  • 게임 서버는 지수 백오프 알고리즘으로 재 시도하거나 클라이언트의 미 처리 영수증 처리 기능으로 처리할 수 있음

요청 curl 샘플

  • 도메인은 각 환경에 맞게 변경 필요

curl --location 'https://api-dev.pub-dev.hybegames.io/billing/him-platform-sdk/v1/google/play/common/getLatestReservedNotConsumed' \
--header 'Content-Type: application/json' \
--data '{
  "pjid": "1201",
  "appStore": "GOOGLE_PLAY",
  "playerId": "playerId",
  "googleOrderId": "GPA.3340-4023-4149-75538",
  "googlePurchaseToken": "bkdcnncmkeegcekfcmjaeppj.AO-J1OxMzEQ0nV5GJvj1ytipiX90uRpWtyyn4cgozqFYeRp1euFxm2lFbH3XR8mPBPWeXgIIsxhkpMvDeey1_lRJ7WLmFMJdbg",
  "googleProductId": "seom_tany_100022",
  "googleResponseOriginJson": "클라에서 획득한 구글의 Json 전체 내용"
}'

Last updated