모바일 앱들은 사용자들과 직접 맞닿아 있는 창구로서, 많은 앱들이 결제 기능을 지원합니다.
앱 자체가 유료인 경우도 있지만, 앱 내부에서 상품을 판매하는 경우가 많습니다.
이러한 결제는 어떻게 구현할 수 있을까요?
iOS에서 결제는 StoreKit을 사용하여 구현됩니다.
아직 StoreKit에 대해서 잘 모르시는 분들(저요)이 개념과 흐름을 이해하는데 도움이 되기 위해
StoreKit의 각 문서들을 요약하여 전체적인 결제의 과정과 그 구현에 대해서 정리하였습니다.
상품 ID가져오기
모든 상품에는 product identifier가 있습니다.(상품을 등록할때 정해줘야 합니다)
이 product identifier를 앱 번들이나 서버에 저장했다가
이것을 사용해 앱스토어에서 상품의 정보들(가격 등)을 가져올 수 있습니다.
앱스토어에서 상품 정보 가져오기
상품 정보를 불러오기 위해서는
product identifier를 사용해서 SKProductsRequest를 생성해주어야 합니다.
request = SKProductsRequest(productIdentifiers: productIdentifiers)
request.delegate = self
request.start()
이때, request에 대한 reference를 유지하지 않으면 결과가 오기전에 메모리에서 해제될 수 있습니다.
상품 정보를 불러온 것에 대한 결과는 delegate를 통해서 받을 수 있습니다.
아래 코드에 나오듯이 delegate의 func productRequest(_ request, didReceive response)
에서
identifier에 매칭되는 상품들과 유효하지 않은 identifier들에 대한 정보들도 전달합니다.
func productRequest(_ requst: SKProductsRequest, didReceive response: SKProductResponse) {
if !response.products.isEmpty { ... }
for invalidIdentifier in response.invalidProductIdentifiers { ... }
}
결과로 온 SKProduct의 reference는 유지했다가 결제 요청 시에 사용합니다.
앱스토어에 결제 요청하기
사용자가 상품을 선택해서 구매를 하려고 하면
해당 상품의 SKProduct 를 사용해서 payment request를 생성합니다.
let payment = SKMutablePayment(product: product)
payment.quantity = 2
그 다음, 해당 요청을 payment queue에 넣어 앱스토어에 요청을 보내면 결제가 진행됩니다.
결제를 요청하기 전에 transaction observer가 등록되어 있어야 합니다.
SKPaymentQueue.default().add(payment)
Transaction 처리하기
결제가 진행되면서 결제 상태를 StoreKit이 transaction queue에 등록한 observer를 호출하여 알려줍니다.
TransactionObserver
결재 진행상황을 처리하기 위해 앱런치때 payment queue에 observer를 등록해야 합니다.
SKPaymentTransactionObserver를 상속한 객체의 인스턴스인 observer를 아래의 코드를 호출하면 StoreKit이 옵저버를 큐에 붙입니다.
SKPaymentQueue.default().add(observer)
SKPaymentTransactionObserver에서 아래의 메소드를 통해 transaction의 변화를 처리합니다.
두 번째 인자인 transactions은 각 결제에 대한 상태를 나타내고 있어 이에 대해서 적절하게 처리해 줍니다.
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]
Transaction 끝내기
transaction을 끝낸다는 것은 앱에서 결제에 대한 처리를 모두 끝내고 StoreKit에게 결제가 끝났다는 것을 알려주는 것을 의미합니다.
transaction을 끝내지 않으면 StoreKit이 해당 transaction을 계속 큐에 가지고 있기 때문에
결제 작업이 다 끝나면 반드시 transaction을 종료해주어야 합니다.
반대로 앱과 서버에서 결제에 대한 처리를 다 완료하지 않았는데 transaction을 끝내버리면 앞으로의 진행상황을 더 이상 제공받지 못합니다.
transaction은 다음의 코드를 통해서 끝낼 수 있습니다.
SKPaymentQueue.default().finishTransaction(transaction)
정리
StoreKit의 기본 요소들과 흐름에 대해서 정리해보았습니다.
- 앱 시작 시 SKPaymentQueue에 SKPaymentTransactionObserver를 등록하여 결제 상태 전달받기
- product id를 통해 상품정보(SKProduct) 가져오기
- SKPayment를 SKProduct로 생성하여 결제 요청 만들기
- 만든 결제 요청(SKPayment)을 SKPAymentQueue에 추가하기
- SKPaymentTransactionObserver를 통해 결제 진행 상태(SKPaymentTransaction) 전달 받기 및 결제 처리
- 결제 처리가 완료된 후 transaction 끝내기
많은 문서가 있는 StoreKit 세상에서 흐름을 파악하는데 도움이 되셨길 바라면서
공식 문서를 꼼꼼하게 살펴보며 자세한 내용들을 익히시길 바랍니다.
'Tech' 카테고리의 다른 글
iOS 개발자가 코틀린 코드를 볼 때 필요한 몇 가지 문법 (0) | 2023.09.19 |
---|---|
Swift Dependencies (0) | 2023.08.26 |
스냅샷 테스트 (0) | 2023.08.26 |
alignmentGuide 활용하기 (0) | 2023.08.26 |
코드 리뷰를 잘하는 법 (0) | 2023.08.26 |