Apple 구매 예약(소모성)
기본 정보
- 각 결제 스토어를 통해서 결제를 진행하는 과정에서 빌링 시스템에 예약이 진행되어야 합니다.
- 애플의 소모성 상품에 대한 예약을 진행하는 API입니다.
| 항목 | 내용 | 비고 |
|---|---|---|
| 호출주체 | 게임서버(s2s API) | |
| 도메인 | 각 환경별 도메인 | |
| 인증 방식 | HTTP 헤더 인증 정보 | |
| HTTP 메소드 | POST | |
| Content-Type | application/x-www-form-urlencoded |
Request
HTTP Request end point
// TODO: Manual review - had fullWidth or overflow attributes
POST https://각 환경별 빌링시스템 도메인/billing/api-game/v1/purchase/apple/appstore/consumable/reserve
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 으로 호출하면 됩니다.
| key | data type | description | example |
|---|---|---|---|
| reqId | String(100) | 중복 요청을 막거나 요청 추적을 위한 값 | userId_UUID 등과 같은 방식으로 생성
|
| pjid | String(50) | 프로젝트ID
| 1004 |
| svcId | String(20) | 서비스ID | 10040020 |
| imid | String(40) | IMID
| aaaabbbb-ccccddd-fffccc-tttggg |
| playerId | String(50) | 결제를 진행하는 유저의 ID
| |
| ipCountry | String(10) | player의 IP기반 국가코드로 법적 대응을 위해서 수집
| KR |
| payment | String(20) | 결제가 진행된 스토어(돈을 지급한 행위가 발생한 스토어) | GOOGLE_PLAY, APPLE_APP_STORE 등
|
| appStore | String(20) | 앱을 다운로드한 플랫폼 스토어(개발사 입장에서는 배포한 스토어)
|
|
| productId | String(200) | 구매 진행하는 상품ID(SKU와 같은 값) | apple_gem_500 |
| os | String(10) | 구매한 디바이스의 OS 종류 | 코드표 OS참고 |
| microPrice | long | 구매 금액 micro단위
| 구매 금액 micro단위(예. $0.99는 990,000 µ$. 100만을 곱함) |
| currency | String(10) | 구매 금액의 화폐 단위
| USD |
Response
응답은 JSON형태로 전달됩니다.
Response property
| key | data type | description | example |
|---|---|---|---|
| boid | String(20) | 빌링 시스템의 주문ID | 4 |
Success sample
application/json;charset=UTF-8
{
"resultCode": "SUCCESS",
"resultMessage": "request success",
"resultData": {
"boid": "4"
}
}
Error sample
- 한도 제한으로 추가 처리가 필요한 경우
- PURCHASE_MONTHLY_LIMITED 에러코드가 리턴됩니다.
- 게임쪽에서 추가 로직을 구현에 사용하실 수 있도록 해당 에러코드가 리턴되면
monthlyLimitedDetail을 추가로 응답합니다.
- 게임쪽에서 추가 로직을 구현에 사용하실 수 있도록 해당 에러코드가 리턴되면
- 추가 정보 필드들에 대한 설명
- PURCHASE_MONTHLY_LIMITED 에러코드가 리턴됩니다.
| key | data type | description | example |
|---|---|---|---|
| appliedPolicy | String | 한도제한이 적용된 정책코드 |
|
| currency | String | 통화 | KRW, JPY |
| limitConfigMircoPrice | Long | 설정된 한도 금액 micro단위 | 30000000000 |
| thisMonthAmountMircoPrice | Long | 이번달 구매 금액의 micro단위
| 29500000000 |
| countryCreated | String | 해당 유저 계정에 생성된 국가 코드
| JP, KR |
| debugMessage | String | 개발자 디버깅 참고용 응답 메시지
| 일본 미성년자('16세') 한도 초과로 구매 중단. 한도 설정: '30000' | 이번달 구매한 대상 금액(JPY):'29500.0000' | 추가 구매하려는 금액:'550.950000' | 총합:'30050.950000 |
- 한국 한도제한 적용됨: KR_MINOR
{
"resultCode": "PURCHASE_MONTHLY_LIMITED",
"resultMessage": "Requests exceeding the monthly purchase limit.",
"resultData": {
"monthlyLimitedDetail": {
"appliedPolicy": "KR_MINOR",
"limitConfigMircoPrice": 70000000000,
"currency": "KRW",
"thisMonthAmountMircoPrice": 68000000000,
"countryCreated": "KR",
"debugMessage": "한국 한도 초과로 구매 중단('9세'). 한도:'70000' | 이번달 구매한 대상 금액(특정 다운로드 앱 스토어 & KRW):68000.0000 | 추가 구매하려는 금액:'59000.000000' | 총합:127000.000000"
}
}
}
- 한국 한도제한 적용됨: KR_ADULT
{
"resultCode": "PURCHASE_MONTHLY_LIMITED",
"resultMessage": "Requests exceeding the monthly purchase limit.",
"resultData": {
"monthlyLimitedDetail": {
"appliedPolicy": "KR_ADULT",
"limitConfigMircoPrice": 1000000000000,
"currency": "KRW",
"thisMonthAmountMircoPrice": 990000000000,
"countryCreated": "KR",
"debugMessage": "한국 한도 초과로 구매 중단('22세'). 한도:'1000000' | 이번달 구매한 대상 금액(특정 다운로드 앱 스토어 & KRW):990000.0000 | 추가 구매하려는 금액:'120000.000000' | 총합:1110000.000000"
}
}
}
- 일본 한도제한 적용됨: JP_MINOR_UNDER_AGE_16
{
"resultCode": "PURCHASE_MONTHLY_LIMITED",
"resultMessage": "Requests exceeding the monthly purchase limit.",
"resultData": {
"monthlyLimitedDetail": {
"appliedPolicy": "JP_MINOR_UNDER_AGE_16",
"limitConfigMircoPrice": 5000000000,
"currency": "JPY",
"thisMonthAmountMircoPrice": 4800000000,
"countryCreated": "JP",
"debugMessage": "일본 미성년자('10세') 한도 초과로 구매 중단. 한도 설정: '5000' | 이번달 구매한 대상 금액(JPY):'4800.0000' | 추가 구매하려는 금액:'550.950000' | 총합:'5350.950000'"
}
}
}
- 일본 한도제한 적용됨: JP_MINOR_UNDER_AGE_18_OVER_16
{
"resultCode": "PURCHASE_MONTHLY_LIMITED",
"resultMessage": "Requests exceeding the monthly purchase limit.",
"resultData": {
"monthlyLimitedDetail": {
"appliedPolicy": "JP_MINOR_UNDER_AGE_18_OVER_16",
"limitConfigMircoPrice": 30000000000,
"currency": "JPY",
"thisMonthAmountMircoPrice": 29500000000,
"countryCreated": "JP",
"debugMessage": "일본 미성년자('16세') 한도 초과로 구매 중단. 한도 설정: '30000' | 이번달 구매한 대상 금액(JPY):'29500.0000' | 추가 구매하려는 금액:'550.950000' | 총합:'30050.950000'"
}
}
}
- 중복 요청으로 발생한 에러
{
"resultCode": "INVALID_PARAMETER",
"resultMessage": "duplicated reqeust. Check your 'reqId' or duplicated request data."
}
- 파라미터 에러
{
"resultCode": "INVALID_PARAMETER",
"resultMessage": "invalid PaymentStoreCd | paymentStore 'null' not allow."
}
에러 코드 정의
- 아래와 같은 에러코드가 resultCode에 응답될 수 있습니다. (참고 링크)
- 아래의 에러코드들은 모든 빌링 API에서 발생 가능한 에러 코드들입니다.
- 해당 에러코드 외에 각 API에서만 발생가능한 에러코드들도 있습니다.
- 각 에러 코드를 바탕으로 필요시 비즈니스 로직을 작성하시면 됩니다.
| 에러코드 | 비고 |
|---|---|
| SYSTEM_ERROR | 빌링 API에서 발생한 시스템 에러
|
| NOT_ALLOW_AUTH | API 인증 헤더 누락이거나 기타 권한이 없는 요청에서 발생 |
- 아래 에러 코드들은 해당 API에서 발생 가능한 추가 에러 코드들입니다.
- 특정 결제 수단인 경우 아래와 같은 에러 코드가 resultCode에 응답될 수 있습니다.
- 특정 국가에서 요구하는 월 구매금액 한도 제한을 빌링 시스템에서 제공하기 위한 에러코드가 포함됩니다.
- 한국: ‘결제 한도 자율 규제’에 따라서 PC 자체 서비스에 대해서, 한국에서 생성된 계정에 대한 정책
- 일본: ‘일본 청소년 소셜 게임 결제 자율 규제’에 따라서 1) 성인 2)18세 미만~16세 이상 3)16세 미만
| 에러코드 | 비고 |
|---|---|
| INVALID_PARAMETER | 요청된 파라미터 오류 |
| JAPANESE_DATE_BIRTH_REQUIRED | 일본 IP에서 생성된 계정(imid)인데 생년월일 정보를 입력하지 않아서 입력 필요
|
| PURCHASE_MONTHLY_LIMITED | 한국 또는 일본에서 생성된 계정이고, 한도 체크 대상에 포함되는 대상인데 이번달 결제 금액이 한도를 초과
|
요청 curl 샘플
- 샘플 curl 커맨드입니다. 요청 정보에 맞게 변경해서 호출하세요.
Apple curl 샘플
curl --location 'https://billing-game-api-dev.pub-dev.hybegames.io/billing/api-game/v1/purchase/apple/appstore/consumable/reserve' \
--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_reserve-appl_98b50907-0928-493b-a816-dac8dbca1f53-2023-11-22-01' \
--data-urlencode 'pjid=9001' \
--data-urlencode 'appStore=APPLE_APP_STORE' \
--data-urlencode 'payment=APPLE_APP_STORE' \
--data-urlencode 'svcId=90010000' \
--data-urlencode 'imid=aaaabbbb-ccccddd-fffccc-tttggg' \
--data-urlencode 'playerId=playerId' \
--data-urlencode 'ipCountry=JP' \
--data-urlencode 'productId=seom_popup_400031' \
--data-urlencode 'microPrice=550950000' \
--data-urlencode 'currency=JPY' \
--data-urlencode 'os=IOS'