관리 메뉴

김종권의 iOS 앱 개발 알아가기

[iOS - swift] 2. 인앱 결제 StoreKit 개념 - 상품 구매 (SKPaymentQueue, SKPaymentTransactionObserver, transaction 추적) 본문

iOS 응용 (swift)

[iOS - swift] 2. 인앱 결제 StoreKit 개념 - 상품 구매 (SKPaymentQueue, SKPaymentTransactionObserver, transaction 추적)

jake-kim 2022. 11. 16. 22:16

* 인앱 결제 포스팅 글 목차

UI에 상품정보 표출과 결제 정보

  • productID를 가지고 앱스토어에 상품 정보 요청하여 SKProduct 획득
    • 1편에서 알아본대로 productID는 로컬이나 서버에 저장된 형태
  • 유저가 특성 상품을 선택하면, SKProduct를 인수로하는 SKMutablePayment로 결제에 관한 정보 입력
let payment = SKMutablePayment(product: product)
payment.quantity = 3
  • StoreKit에서 제공하는 queue에 위 payment를 추가하여, 앱스토어에 결제 요청을 제출
SKPaymentQueue.default().add(payment)
  • 앱스토어와 통신하기 (Transaction Observer)
    • 앱에서 transaction observer라는 것을 옵저빙하여 transaction 상태를 추적이 가능
    • 앱 런치 직후에 SKPaymentQueue를 이용하여 transaction observer를 옵저빙
func application(
  _ application: UIApplication,
  didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
	SKPaymentQueue.default().add(observer)
	return true
}

Transaction Observer 주요 처리

  • paymentQueue(_:updatedTransactions:) 메소드가 핵심
    • 유저가 앱에서 상품을 구매한 직후 인터넷이 끊긴다면, 구매한 상품을 전달해주지 못하는 상태
    • 다시 앱을 실행할 때, 친절하게도 StoreKit은 PaymentQueue(_:updatedTransactions:) 메소드를 호출해주기 때문에 이 상태를 처리
  • 인수로 얻을 수 있는 updatedTransaction 인스턴스 내부에 transactionState에서 정보 획득이 가능
    • SKPaymentTransactionState 5가지 상태에 따라 적절한 처리가 필요
    • .purchasing: 서버 큐에 트랜잭션이 추가된 형태 (진행 중이라는 UI 표출)
    • .deferred: 지연되고 있다는 UI 표출
    • .failed: error 프로퍼티를 통해 유저에게 실패 메시지 UI 표출
    • .restored: 같은 앱을 다른 기기에서 사용하거나 앱을 지웠다가 재설치하여 이전에 구매한 프로덕트를 사용하고자 할때 사용
    • .purchased: 구매한 제품 UI 표출
  • updatedTransaction 인스턴스의 메소드를 사용하여 최신 트랜잭션의 상태를 얻어올수 있음

앱에서 제공하는 부가 기능에 대한 결제 요청 SKPayment

  • SKPayment
    • 추가적인 부가 가능에 대한 요청
init(product: SKProduct)

var productIdentifier: String
var quantity: Int // 수량
var requestData: Data?  // (개발단에서 Reserved for future use.) nil로 보내지 않으면 리젝
var applicationUsername: String?

var simulatesAskToBuyInSandbox: Bool // true이면 sandbox에서 수행

var paymentDiscount: SKPaymentDiscount? // payment에 관한 할인 정보

  • SKPaymentDiscount
/// 
init(identifier: String, keyIdentifier: String, nonce: UUID, signature: String, timestamp: NSNumber)

var identifier: String
var keyIdentifier: String // 시그니처를 generate하기 위한 key 식별자

var nonce: UUID
var signature: String // 암호로 서명된 특정 할인 혜택의 속성을 나타냄 (utf-8 string)
var timestamp: NSNumber // unix epoch time 포맷된 시그니처의 생성 시간

SKPaymentTransaction

  • 결제 SKPayment 인스턴스가 결제 대기열에 추가될 때 자동으로 생성
  • 앱 스토어가 결제 처리를 완료했을 때 이 transaction이 앱으로 전송
    • 완료된 트랜잭션은 영수증, 트랜잭션 id 제공
    • 이를 통해 앱에서 처리된 결제에 대한 영구적인 기록 가능
var payment: SKPayment // 트랜잭션에 관한 결제 정보
var transactionIdentifier: String? // 성공적인 결제 트랜잭션을 고유하게 식별
var transactionDate: Data? // 트랜잭션이 앱스토어의 결제 대기열에 추가된 일자
var original: SKPaymentTransaction? // 앱스토어에 의해 복원된 트랜잭션
var error: Error? // 트랜잭션 처리 중 발생한 에러 객체

var downloads: [SKDownload] // 트랜잭션에 엮인 downloadable content

var transactionState: SKPaymentTransactionState // 트랜잭션의 현재 상태

*참고

https://developer.apple.com/documentation/storekit/skpayment

https://developer.apple.com/documentation/storekit/skpaymenttransaction

https://developer.apple.com/documentation/storekit/skpaymenttransactionobserver

Comments