탕구리's 블로그

StoreKits2 영수증 검증 - Apple 본문

마켓

StoreKits2 영수증 검증 - Apple

탕구리당 2023. 7. 18. 14:09
반응형

개요

  • apple InApp Purchase API의 최신 업데이트 변경점을 확인
  • 개발사에서 new IAP를 연동하기 위한 정보를 정리
  • deprecat 된 vreify API 의 대체 가이드 안을 마련
  • Client SDK : StoreKit2에 대한 정리
  • Server API : App Store Server API 중 IAP 관련된 변경점에 대한 정리

Client : StoreKit2

Original StoreKit → StoreKit2 변경점

  • StoreKit 2는 iOS, macOS, tvOS, watchOS에서 IAP 처리를 위한 New Swift API
  • Swift 우선으로 설계 , iOS 15 이상에서만 사용 가능
  • 기존 Original Storekit 내부에 API 추가 형태로 존재
  • async/await를 지원
    • 기존 대리자 SKProductsResponse을 호출하고 SKProductsRequestDelegate 사용하지 않아도 됨
    • 아래의 형태로 async/await 대리자 없이 간단히 사용 가능
`func getProducts() async throws -> [Product] {`

`let` `products = try await Product.request(with: Set(["item", "item_1"]))`

`**return**` `products`

`}`
  • 보안성 향상
  • Client에서의 영수증 검증 기능 추가
    • StoreKit.VerificationResult
  • 구독 관련 API 추가
  • 환불 API 추가
    • 기존 : 마켓에 환불 요청
    • 변경 : 게임 내 환불 버튼 추가 → apple web UI 오픈 → 애플에 환불 요청
    • 환불 내역 반환 API 추가
  • StoreKit2의 구조

  • Products
    • 판매 제품에 대한 정보
  • Purchases
    • 제품에 대한 구매 처리
    • Purchase Option 
      • 구매 시 각종 구매 옵션을 앱스토어 쪽에 전달이 가능하다.
      • 수량, 구독에 대한 프로모션 제안 정보
      • appAccountToken에 KG paymentUserID를 넣어서 Validation에 이용한다.
  • Transaction Info
    • 구매를 진행하는 상품에 대한 정보
    • JSON Web Signature 형태로 정보가 제공 됨
    • transaction id 하나에 대한 거래 정보이다.
    • 상품정보, 구매 유형, 구매 실패 정보 제공
    • appAccountToken(UUID) 정보 제공
  • Transaction history
    • 유저의 완료된 거래 내역 리스트 조회게임 클라이언트에서 유저의 구매 내역을 조회 할 수 있는 기능 추가가 가능하다.
    • 가장 마지막 거래, 제품 하나에 대한 거래 정보 또한 가져 올 수 있다.
    • 다른 기기에서 구매한 구매 내역 확인이 가능하다. (다른 기기에서 구매 시 실시간 알람을 받는다.)
    • Transaction Info 처럼 사용 할 수 있으나 목적이 다른 것 같다.
  • Subscription
    • 구독 기능
 

Product.PurchaseOption | Apple Developer Documentation

Optional settings for a product purchase.

developer.apple.com

Server : App Store Server API

  • Get Transaction Info (링크)
    • deprecat 된 verifyRequest의 대체 API
    • 클라이언트에서 결제 완료 후 생성된 transactionId를 전달 받아 단일 결제 건에 대한 정보 조회
  • Get Transaction History (링크)
    • 유저의 결제 건에 대한 모든 내역을 조회 가능
    • 게임 내에서 유저 구매 기록을 보여주는 기능에 이용 가능
    • transactionId 기준으로 revision startDate/endDate에 해당 되는 결제 건의 획득이 가능

 

기존 IAP Process

  • 클라이언트에서 영수증 전문을 게임서버로 보내어 게임서버에서 영수증 자체를 검증하여 처리
  • Client : Original StoreKit (링크)
    • 상품 리스트 조회 : SKProducts
    • 영수증 정보(receipt-data) : SKPaymentTransaction
    • 마켓 국가정보 등 획득 : SKStorefront / countryCode
  • Server : /verifyRequest
    • 영수증 검증
      • request : receipt-data
      • responseBody.Receipt :
        • bundle id, product id, purchase date 등을 검증 후 아이템 지급

변경 된 IAP Process

  • 1안 : Get Transaction Info 사용
    • 클라이언트에서는 transtionid를 서버로 보내어 get_transaction_info API를 이용 → 구매 내역을 획득 후 검증
    • Client : Original StoreKit
      • SKPaymentTransactionState.purchased or SKPaymentTransactionState.restored 상태의 transactionIdentifier (링크)
    • Server : Get Transaction Info (링크)
      • deprecat 된 verifyRequest의 대체 API
      • 클라이언트에서 결제 완료 후 생성된 transactionId를 전달 받아 단일 결제 건에 대한 정보 조회
  • JWS(JSON Web Signature) 형태로 값이 리턴된다. (링크)
  • 해당 값을 서버에서 검증 후 아이템 지급 처리를 한다.
{
	"appAccountToken": "546734356456"
	"bundleId": "com.test.test",
	"productId": "test.test.product",
	"transactionId": "12820209329",
	"originalTransactionId": "12820209329",
	"webOrderLineItemId": "12820209329",
	"subscriptionGroupIdentifier": "12345678",
	"type": "Auto-Renewable Subscription",
	"environment": "Production",
	"quantity": 1,
	"purchaseDate": 1683302400000,
	"originalPurchaseDate": 1683302400000,
	"inAppOwnershipType": "PURCHASED",
	"signedDate": 1685980800000,
	"expiresDate": 1683302400000,
	"revocationDate": 1685302400000,// 환불에 대한 정보
	"revocationReason": 0 // 환불에 대한 정보,
	"isUpgraded": true,
	"appAccountToken": "t000-kekkken-t99844es88st-token",
	"storefront": "USA",
	"storefrontId": "143441",
	"transactionReason": "PURCHASE"
}

 

2안 : Get Transaction History 사용

  • storekit1 -> storekit2 변경 작업 시 가장 적은 리소스가 들것으로 예상 됨
  • 클라이언트에서는 영수증 정보를 서버로 보내어 transtionid를 획득 → get_transaction_history API를 이용하여 구매 내역을 검증
  • Client : Original StoreKit
    • Client에서 기존과 동일한 방식으로 영수증을 서버로 전송
  • Server : get_transaction_history (링크)
    • 기존 영수증 전문에서 "latest_receipt_info":[{transtionid}] 획득
    • 영수증 Response 전문 확인하기
    • 획득한 transaction_id 값을 이용하여 get_transaction_history API 에서 구매 내역 검증
GET https://api.storekit.itunes.apple.com/inApps/v1/history/{transactionId}

workflow

 

3안 : Device에서 영수증 검증을 하여 아이템 지급 처리(링크)

  • Validating receipts on the device
  • device에 설치된 app 내부에 생성된 인증서를 이용하여 검증

디바이스에서 영수증 검증

  • 로컬로, 장치에서. 영수증을 로컬에서 확인하려면 Apple이 PKCS #7 컨테이너로 인코딩하고 서명하는 바이너리 파일을 읽고 확인하는 코드가 필요합니다.

 

영수증은 앱 번들의 단일 파일로 구성됩니다. 파일은 PKCS #7 형식입니다 . 이것은 암호화 가 적용된 데이터의 표준 형식입니다 . 컨테이너에는 페이로드, 인증서 체인 및 디지털 서명이 포함되어 있습니다. 인증서 체인과 디지털 서명을 사용하여 Apple이 영수증을 생성했는지 확인합니다.

 

반응형
Comments