빌링에 구매 예약을 진행하며, 유저가 결제를 진행할 수 있는 PG 결제 URL을 요청
기본 정보
- PG를 이용해서 유저가 결제를 진행할 수 있도록 결제 URL을 요청하는 API입니다.
- 판매 가능한 상품은 빌링에 등록되어야 합니다.
- 다만, 실제 유저에게 판매할 상품(즉, 전시상품)은 게임쪽에서 따로 관리해주셔도 됩니다.(ex. 횟수 제한 상품, 레벨 제한 상품)
- 현재 국내 PG만 연동되어 있기 때문에 결제는 ‘KRW’ 금액으로 ‘한글 상품명’으로 진행 됩니다.
- PG 결제를 유도하기 위해서 할인기능을 제공합니다.
- 다만, 할인포인트가 '선불전자지급수단'에 해당되어 전자금융거래법 대상이 될 수 있기 때문에 할인 포인트를 빌링시스템에서 관리해주지는 않습니다.
정보
- 토스 최소 결제 금액은 200원인 결제 수단으로 설정되어 있습니다.
- 100%할인되어 0원 결제는 자체 처리하여 지원하지만, 그렇지 않은 경우에는 최소 200원 이상 결제 요청되어야합니다.
- 청구 금액과 할인금액의 간단한 유효성 검사를 지원하기 위해서 API는 정보를 전달받습니다.
- 유저의 결제 허들을 최소화 하도록 동일 상품에 대해서 최대 100개까지의 수량결제를 지원하고 있습니다.
| 항목 | 내용 | 비고 |
|---|---|---|
| 호출주체 | 게임서버(s2s API) | |
| 도메인 | 각 환경별 도메인 | |
| 인증 방식 | HTTP 헤더 인증 정보 | |
| HTTP 메소드 | POST | |
| Content-Type | application/x-www-form-urlencoded | |
| 사전 필요사항 |
|
Request
HTTP Request end point
POST https://각 환경별 빌링시스템 도메인/billing/api-game/v1/purchase/pg/reserve/withGetPaymentUrl
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 으로 호출하면 됩니다.
- PG결제는 해당 상품을 N개 구매할 수 있는 기능을 제공하며, 빌링 시스템에 등록된 상품만 결제 가능하기 때문에 모바일 결제와 파라미터가 틀립니다.
| key | required Y/N | type | 설명 | 예 |
|---|---|---|---|---|
| reqId | Y | String(100) | 중복 요청을 막거나 요청 추적을 위한 값 | userId_UUID 등과 같은 방식으로 생성 |
| pjid | Y | String(20) | 프로젝트ID
| 1201 |
| svcId | Y | String(20) | IMID의 서비스ID | 12010000 |
| serverId | N | String(20) | 게임서버ID
| ASIA-1 |
| imid | Y | String(40) | IMID
| 87DDCADUCX7WLK7D55HY |
| playerId | Y | String(50) | 결제를 진행하는 유저의 ID
| |
| ipCountry | Y | String(10) | player의 IP기반 국가코드로 법적 대응을 위해서 수집
| KR |
| productId | Y | String(200) | 구매 진행하는 상품ID
| pg_gem_100 |
| quantity | Y | integer | 해당 상품 구매 수량 1~100 사이의 값(최대 100) | 1 |
| currency | Y | String(3) | 구매 금액의 화폐 단위
| KRW |
| chargeAmountMicroPrice | Y | long | 유저에게 실제 결제 청구를 요청하는 금액
| 예) 1000원은 1000000000. 100만을 곱함) |
| discountAmountMicroPrice | Y | long | 할인 금액. 단위는 micro를 사용
| |
| os | Y | String(10) | 구매한 디바이스의 OS 종류 | WIN64, WIN32 |
| appStore | Y | String(20) | 앱을 다운로드한 플랫폼 스토어(개발사 입장에서는 배포한 스토어)
|
|
| playerNameValue | Y | String(250) | 사용자 이름
| 닉네임, 케릭터명 |
| playerLang | Y | String(2) | 사용자의 언어
| ko |
Response
응답은 JSON형태로 전달됩니다.
Success sample
- 성공으로 응답하면 게임 서버는 게임 클라이언트에 paymentUrl을 리턴하여 웹브라우저(또는 웹뷰)를 이용해서 결제를 유도할 수 있습니다.
- 웹뷰를 사용할 경우 페이지 이동이 자유롭지 않으면 결제가 진행되지 않을 수 있습니다.
- 웹뷰 사용 시 해당 내용을 주의해야하며 특정 앱으로 이동하거나 새로운 창이 띄워지는 부분을 웹뷰에서 허용해야합니다
- 즉, 상세한 테스트가 필요하기에 외부 브라우저 사용을 추천드립니다.
{
"resultCode": "SUCCESS",
"resultMessage": "request success",
"resultData": {
"boid": "94",
"paymentUrl": "도메인/payment/pg/1202/checkout?token=09245e98b8264180892ea45c24bfd4d4_YzDbSE2V_1202_TOSS_INGAME&vk=0eeed83227821689ed29df31fc06d928f59b2a76",
"expiredAtUnixTS": 1775107598
}
}
Response property
- 응답 성공인 경우의 resultData에 json 필드 설명입니다.
| key | data type | description | example |
|---|---|---|---|
| boid | String | 빌링에서 생성된 유니크한 id | |
| paymentUrl | String(500) | 결제 URL(해당 URL을 유저에게 보여줘서 결제를 유도) | 도메인/payment/pg/1202/checkout?token=09245e98b8264180892ea45c24bfd4d4_YzDbSE2V_1202_TOSS_INGAME&vk=0eeed83227821689ed29df31fc06d928f59b2a76 |
| expiredAtUnixTS | long | 결제 URL의 만료일시의 유닉스 타임스탬프 초 값 | 1775107598 |
Error sample
- reqId 중복 요청
{
"resultCode": "INVALID_PARAMETER",
"resultMessage": "duplicated reqeust. Check your 'reqId' or duplicated request data."
}
- 한도 제한으로 추가 처리가 필요한 경우 에러
- PURCHASE_MONTHLY_LIMITED 에러코드가 리턴됩니다.
- 게임쪽에서 추가 로직을 구현에 사용하실 수 있도록 해당 에러코드가 리턴되면 monthlyLimitedDetail을 추가로 응답합니다.
- 추가 정보 필드들에 대한 설명
| 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에 응답될 수 있습니다.
- 아래의 에러코드들은 모든 빌링 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 -X 'POST' \
'도메인/billing/api-game/v1/purchase/pg/reserve/withGetPaymentUrl' \
-H 'accept: application/json;charset=UTF-8' \
-H 'X-Req-Pjid: 입력필요' \
-H 'X-Auth-Access-Key: 입력필요' \
-H 'Content-Type: application/x-www-form-urlencoded' \
-d 'appStore=BIFROST&os=WIN64&playerNameValue=%EB%8B%89%EB%84%A4%EC%9E%84&productId=pg_test_item_1&quantity=1&ipCountry=KR&playerLang=ko¤cy=KRW&chargeAmountMicroPrice=200000000&pjid=1202&reqId=playerId_reserve_98b50907-0928-4913b-a816-dac8dbca1f53&svcId=12010000&playerId=playerId&discountAmountMicroPrice=300000000&serverId=ASIA-1&imid=87DDCADUCX7WLK7D55HY'