728x90
implementation ("com.google.apis:google-api-services-androidpublisher:v3-rev20230313-2.0.0")
Android
private fun verifyGoogle(request: PurchaseRequestDto, customerId: String) {
val token = googleCredentialsConfig.getToken()
val url = "https://androidpublisher.googleapis.com/androidpublisher/v3/applications/${googleApplicationPackageName}/purchases/products/${request.packageType.productId}/tokens/${request.receiptId}?access_token=$token"
val response = webClient
.get()
.uri(url)
.header("Content-Type", "application/json")
.retrieve()
.bodyToMono(GoogleProductPurchaseResponseDto::class.java)
.onErrorResume { Mono.error(it) }
.block()
if (response?.purchaseState != 0) {
throw IllegalArgumentException("purchase_not_completed")
}
if (response.acknowledgementState == 0) {
throw IllegalArgumentException("purchase_not_acknowledged")
}
if (repository.existsById(request.transactionId)) {
throw InvalidRequestException("이미 사용된 토큰입니다.")
}
savePurchase(
transactionId = response.orderId?:throw InvalidRequestException("유효하지 않은 결제 요청입니다. : ${request.receiptId}"),
customerId = customerId,
type = request.packageType
)
}
구글 인증 토큰 생성
@Component
class GoogleCredentialsConfig {
fun getToken(): String {
val inputStream = ClassPathResource("keys/android-iap-key.json").inputStream
val credentials = GoogleCredentials.fromStream(inputStream)
.createScoped(AndroidPublisherScopes.ANDROIDPUBLISHER)
return credentials.refreshAccessToken().tokenValue
}
}
막간의 트러블 슈팅( malformed JSON )
Use JsonReader.setLenient(true) to accept malformed JSON at line 2 column 4 path
AndroidPublisher 를 통해 Publisher 를 만들고, 요청을 보내주었다.
하지만 로컬 서버에서는 요청이 잘 가는게 운영서버만 가면 위와 같은 에러가 발생하였다.
AndroidPublisher -> WebClient 로 변경 하였다.
google Key 파일을 줍줍 하러 가보자.
GCP Publisher Key
Google 클라우드 플랫폼
로그인 Google 클라우드 플랫폼으로 이동
accounts.google.com
시작하기 | Google Play Developer API | Google for Developers
Google Play 개발자 계정에 관한 API 액세스 권한을 설정하는 방법을 알아보세요. API 호출을 만들기 위한 필수 단계입니다.
developers.google.com
GCP 에서 IAM 서비스 계정 생성 > 생성한 계정 클릭 > 키 탭 > 키 를 생성 해준다.

키를 생성하고 키를 다운받으면 JSON 파일이 받아진다.
다시 코드로 돌아가서
@Value("\${google-keyfile-path}")
private lateinit var googleAccountFilePath: String
부분에 경로를 넣어주고 키를 Load 해준다.
URL
https://androidpublisher.googleapis.com/androidpublisher/v3
/applications/${googleApplicationPackageName}
/purchases/products/${request.packageType.productId}
/tokens/${request.receiptId}
?access_token=$token
마지막에 생성한 토큰을 파라메터로 넘겨준다.
현재 필자는 소모성 아이템이기 때문에 products() 로 요청을 보낸다.
728x90
'개-발 > Java + Spring + Kotlin' 카테고리의 다른 글
| [Spring] itemReader 에서 ReadOnly DB 읽기 (0) | 2025.09.05 |
|---|---|
| [spring] React Native FCM 푸시 알림 구현 (f.Kotlin) (0) | 2025.08.20 |
| [Spring] storekit2 / expo 인 앱 아이템 구매 확인 구현 2 (IOS) (2) | 2025.08.07 |
| [kotlin] 슬랙 봇 연동하기 (0) | 2025.06.20 |
| [spring] read , write 분리하기 (DB Replication) (0) | 2025.06.12 |