본문으로 건너뛰기

Apple 유저의 구매 완료 데이터를 빌링에 저장 요청 - 게임에서 결제 기능을 직접 구현한 경우

정보

해당 API는 게임에서 결제를 직접 구현한 경우에 구매 완료 데이터를 빌링 시스템에 전송하는 API입니다.

기본 정보

  1. 협의된 특정 게임은 자체 구현한 결제를 사용할 수 있습니다.
    1. 단, 결제 어뷰징 방지는 게임쪽에서 잘 구현해주셔야합니다.
      1. 예) 저렴한 상품 구매 후 비싼 상품 지급 요청 방지
  2. 게임에서 결제를 구현했지만 매출 인식과 같은 재무 처리 및 플랫폼 기능을 일부 활용하기 위해서 ‘구매 완료 데이터’를 전송해줄 필요가 있습니다.
항목내용비고
호출주체게임서버(s2s API)
도메인각 환경별 도메인
인증방식HTTP 헤더 인증 정보
HTTP 메소드POST
Content-Typeapplication/json

Request

HTTP Request end point

POST https://각 환경별 빌링시스템 도메인/billing/api-game/v1/purchase/apple/appstore/implement/self/consumable/completed/save

HTTP Request Header

  • 아래의 HTTP Header들을 API 요청에 포함시켜야합니다.
이름비고
X-Req-Pjid프로젝트ID기술 PM 등에게 전달받은 프로젝트ID
X-Auth-Access-Key인증용 키기술 PM 등에게 전달받은 해당 게임용 인증 키

HTTP Request Parameter

  • Content-Type: application/json 으로 요청되어야 합니다.
    • 영수증 관련 정보들의 길이 및 escape 등의 문제 때문
이름데이터 타입필수 Y/N설명
pjidString(20)Y프로젝트ID 동일 게임이라면 서비스ID가 여러개일 수 있지만 프로젝트ID는 같음,1004
playerIdString(50)Y주문 완료를 진행하는 유저ID
ipCountryString(10)Nplayer의 IP기반 국가코드로 법적 대응을 위해서 수집 3166-1 alpha-2 국가코드, AWS CloudFront를 사용한다면 HTTP헤더의 CloudFront-Viewer-Country에서 쉽게 얻을 수 있음,
productIdString(200)Y구매를 진행한 상품ID(SKU와 같은 값)apple_gem_01
microPricelongY구매 금액 micro단위 사용측의 부동 소수점 오차등을 방지하기 위해서 micro단위 사용,구매 금액 micro단위(예. $0.99는 990,000 µ$. 100만을 곱함)
currencyString(10)Y구매 금액의 화폐 단위 3글자 포맷의 ISO-4217,USD
memoString(2000)N메모 필요시 옵셔널하게 사용,
transactionIdStringY구매 단건의 transaction_id 애플 → SDK → 클라이언트 → 게임서버 → 빌링으로 전달 필요, 멀티 디바이스 사용할 경우 소모성 상품이더라도 동일 영수증내 in_app이 N건이 존재 가능하기 때문에 거래를 특정할 수 있는 애플 transactionId가 필요,2000000574982560
receiptDataStringY애플 구매 영수증참고 클라이언트에서 receiptString 부분 // Get the receipt if it's available. if let appStoreReceiptURL = Bundle.main.appStoreReceiptURL, FileManager.default.fileExists(atPath: appStoreReceiptURL.path) do { let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped) print(receiptData) let receiptString = receiptData.base64EncodedString(options: []) // Read receiptData. } catch { print("Couldn't read receipt data with error: " + error.localizedDescription) } ,

Response

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

Success sample

  • 성공할 경우 빌링 시스템에는 구매 완료 데이터가 생성되며 이때 boid가 생성됩니다.
  • 아래는 성공의 경우 샘플 json입니다.
{
"resultCode": "SUCCESS",
"resultMessage": "Saving the purchase completion data was successful. The boid generated by the billing system is '391'"
}

Error sample

  • 이미 전송 완료된 데이터를 다시 요청한 경우
{
"resultCode": "INVALID_PARAMETER",
"resultMessage": "Exist paymentOrderId data:'2000000574982560'. Check your params's transactionId",
"traceId": "b_e527fb31d8d0"
}
  • 잘못된 영수증 데이터로 요청
{
"resultCode": "NOT_VALID_RECEIPT",
"resultMessage": "[apple itunes /verifyReceipt] The receipt for the App Store is incorrect. statusCode: '21002'. See https://developer.apple.com/documentation/appstorereceipts/status",
"traceId": "b_c8b4fb869a64"
}

에러 코드 정의

  • 아래와 같은 에러코드가 resultCode에 응답될 수 있습니다. (참고 링크)
  • 아래의 에러코드들은 모든 빌링 API에서 발생 가능한 에러 코드들입니다.
    • 해당 에러코드 외에 각 API에서만 발생가능한 에러코드들도 있습니다.
    • 각 에러 코드를 바탕으로 필요시 비즈니스 로직을 작성하시면 됩니다.
에러코드비고
SYSTEM_ERROR빌링 API에서 발생한 시스템 에러 HTTP 상태코드 500 리턴,
NOT_ALLOW_AUTHAPI 인증 헤더 누락이거나 기타 권한이 없는 요청에서 발생
  • 아래 에러 코드들은 해당 API에서 발생 가능한 추가 에러 코드들입니다.
에러코드비고
INVALID_PARAMETER
NOT_VALID_RECEIPT구매 영수증 검증 영수증 변조 등 잘못된 영수증 문제,

요청 curl 샘플

  • 도메인 및 인증 헤더 등은 변경 필요
curl -X 'POST' \
'http://localhost:10001/billing/api-game/v1/purchase/apple/appstore/implement/self/consumable/completed/save' \
-H 'accept: application/json;charset=UTF-8' \
-H 'X-Req-Pjid: TODO' \
-H 'X-Auth-Access-Key: TODO' \
-H 'Content-Type: application/json;charset=UTF-8' \
-d '{
"playerId": "playerId",
"ipCountry": "KR",
"productId": "test.item.bag.blue",
"microPrice": 990000,
"currency": "KRW",
"memo": "test_memo",
"pjid": "1201",
"transactionId": "2000000574982560",
"receiptData": "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"
}'