Google Play 검증 성공한 구매에 대해서 소모(Consume) 및 완료처리 요청

기본 정보

  1. 검증 성공한 구매 완료건에 대해서 Google에 소모처리(Consume) 요청 및 빌링에 완료처리하는 API

    1. 꼭, 게임 서버에서 상품 지급 성공 후 호출되어야 합니다.

    2. 해당 API를 통해서 빌링 완료처리되지 않고 VERIFY_SUCCESS로 남아있는 구매 건은, 게임 서버에서 아이템이 지급되지 않은 상태로 간주되며 재 처리 대상에 포함됩니다.

    3. 과거에는 안드로이드 클라이언트에서 진행되던 소모 처리를 서버 기능으로 개발 후 빌링 완료와 함께 제공해드리는 기능입니다.

항목
내용
비고

호출주체

게임서버(s2s API)

HTTP 메소드

POST

Content-Type

application/x-www-form-urlencoded

Request

HTTP Request end point

POST https://각 환경별 빌링시스템 도메인/billing/api-game/v1/purchase/google/play/consumable/complete/withGoogleConsume

HTTP Request Header

  • 아래의 HTTP Header들을 API 요청에 포함시켜야합니다.

이름
비고

X-Req-Pjid

프로젝트ID

기술 PM 등에게 전달받은 프로젝트ID

X-Auth-Access-Key

인증용 키

기술 PM 등에게 전달받은 해당 게임용 인증 키

HTTP Request Parameter

  • Content-Type: application/x-www-form-urlencoded 으로 요청되어야 합니다.

이름
데이터 타입
설명

reqId

String(100)

중복 요청을 막거나 요청 추적을 위한 값

userId_UUID 등과 같은 방식으로 생성

pjid

String(20)

프로젝트ID

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

1004

boid

String(20)

빌링 시스템 구매 예약 API를 통해서 생성된 ID

1234

playerId

String(50)

결제를 진행하는 유저의 ID

  • 게임에서 결제 스콥을 관리하고 싶은 id값으로 사용

    • 하이브 IM의 uid값이 될 수도 있음

Response

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

Sample

Success sample

  • 게임 서버에서도 필요 로그를 저장해두시는게 좋습니다.

{
    "resultCode": "SUCCESS",
    "resultMessage": "Success consume:'1' | google purchaseToken: 'bkdcnncmkeegcekfcmjaeppj.AO-J1OxMzEQ0nV5GJvj1ytipiX90uRpWtyyn4cgozqFYeRp1euFxm2lFbH3XR8mPBPWeXgIIsxhkpMvDeey1_lRJ7WLmFMJdb'."
}

Error sample

  • 구매 완료된 boid에 대해서 다시 완료 요청

{
    "resultCode": "INVALID_PARAMETER",
    "resultMessage": "'boid: 1' purchaseState is not BILLING_RESERVED. The current value is 'COMPLETED"
}
  • 이미 소모된 데이터(purchaseToken기준)를 다시 소모 요청한 경우

{
    "resultCode": "INVALID_PARAMETER",
    "resultMessage": "Consumption processing is possible only when the purchase status value is 0. boid:'1' | purchaseToken:'bkdcnncmkeegcekfcmjaeppj.AO-J1OxMzEQ0nV5GJvj1ytipiX90uRpWtyyn4cgozqFYeRp1euFxm2lFbH3XR8mPBPWeXgIIsxhkpMvDeey1_lRJ7WLmFMJdbg' | google return purchaseState:'0'"
}
  • Google로부터 확인한 consumptionState가 0이 아니어서 Consume불가

    • 해당 API 요청 시점에 어뷰징 방지를 위해서 현재 상태 검사를 구글API로 진행하고 있습니다.(변경될 수 있음)

    • 즉, Consume되서 최종 완료된 boid로 요청한 경우

{
    "resultCode": "INVALID_PARAMETER",
    "resultMessage": "Current consumptionState is '1' not allow(from google). boid:'1' | Google purchaseToken:'bkdcnncmkeegcekfcmjaeppj.AO-J1OxMzEQ0nV5GJvj1ytipiX90uRpWtyyn4cgozqFYeRp1euFxm2lFbH3XR8mPBPWeXgIIsxhkpMvDeey1_lRJ7WLmFMJdbg' | see https://developers.google.com/android-publisher/api-ref/rest/v3/purchases.products."
}
  • Google 에서 Consume 실패 리턴

{
    "resultCode": "EXTERNAL_API_CONSUME_FAIL",
    "resultMessage": "400 Bad Request\nPOST https://androidpublisher.googleapis.com/androidpublisher/v3/applications/com.hybeim.intheseom/purchases/products/seom_tany_100022/tokens/bkdcnncmkeegcekfcmjaeppj.AO-J1OxMzEQ0nV5GJvj1ytipiX90uRpWtyyn4cgozqFYeRp1euFxm2lFbH3XR8mPBPWeXgIIsxhkpMvDeey1_lRJ7WLmFMJdbg:consume\r\n{\n  \"code\": 400,\n  \"errors\": [\n    {\n      \"domain\": \"androidpublisher\",\n      \"message\": \"The product purchase is not owned by the user.\",\n      \"reason\": \"productNotOwnedByUser\"\n    }\n  ],\n  \"message\": \"The product purchase is not owned by the user.\"\n}"
}

에러 코드 정의

  • 아래와 같은 에러코드가 resultCode에 응답될 수 있습니다. (참고 링크)

  • 아래의 에러코드들은 모든 빌링 API에서 발생 가능한 에러 코드들입니다.

    • 해당 에러코드 외에 각 API에서만 발생가능한 에러코드들도 있습니다.

    • 각 에러 코드를 바탕으로 필요시 비즈니스 로직을 작성하시면 됩니다.

에러코드
비고

SYSTEM_ERROR

빌링 API에서 발생한 시스템 에러

  • HTTP 상태코드 500 리턴

NOT_ALLOW_AUTH

API 인증 헤더 누락이거나 기타 권한이 없는 요청에서 발생

  • 아래 에러 코드들은 해당 API에서 발생 가능한 추가 에러 코드들입니다.

에러코드
비고

INVALID_PARAMETER

NOT_ALLOW_PURCHASE

구매 기능을 사용할 수 없는 상황

  • 빌링 시스템에 스토어 관련 설정 누락

  • 다른 유저의 결제건에 대한 시도 등

EXTERNAL_API_CONSUME_FAIL

소모 요청 결과가 Google로부터 실패로 리턴 됨

NOT_VALID_RECEIPT

구매 영수증 검증결과 유효하지 않은 영수증

  • 영수증 변조 여부 검사와 같은 어뷰징 방지 검사

  • 구글 API로부터 구매의 현재 상태를 검사

EXTERNAL_API_ERROR

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

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

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

요청 curl 샘플

  • 도메인 및 인증 헤더 등은 변경 필요

curl --location 'https://billing-game-api-dev.pub-dev.hybegames.io/billing/api-game/v1/purchase/google/play/consumable/complete/withGoogleConsume' \
--header 'X-Req-Pjid: 9001' \
--header 'X-Auth-Access-Key: test-auth-key' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'reqId=userId_consume_170083bf-8d85-433f-8bd2-67674b7482db-2023-11-27-01' \
--data-urlencode 'pjid=9001' \
--data-urlencode 'boid=1' \
--data-urlencode 'playerId=playerId'

Last updated