Promoted In-App Purchase trong iOS

Overview

Bắt đầu từ iOS 11, Apple cung cấp tính năng promote in-app purchase trên App Store. Nghĩa là các item in-app purchase thay vì chỉ có thể được mua bên trong app, chúng còn có thể được "promote" ở trên product page trên App Store.

User có thể chọn mua trực tiếp các item, subscribe các subscription và chuyển đến giao diện thanh toán bên trong app. User sẽ được yêu cầu download và cài đặt app nếu app chưa được cài.

Việc promote in-app purchase yêu cầu 2 bước cơ bản:

  • Upload ảnh cho các item, subscription in-app purchase mà bạn muốn bày bán lên App Store Connect. Chúng ta có thể sử dụng App Store Promotions tool trong App Store Connect để quản lý, thay đổi thứ tự của chúng khi xuất hiện trên App Store.
  • Implement delegate method của protocol SKPaymentTransactionObserver để handle các purchase.

Guildline về việc marketing các in-app purchase trên App Store có thể tham khảo tại Promoting Your In-App Purchases.

Để customize list các promoted in-app purchase, chúng ta có thể sử dụng SKProductStorePromotionController để override các setting mặc định của App Store Connect như việc ẩn, hiện và thứ tự xuất hiện của các item. Những override setting này là riêng biệt với mỗi device và chúng không được đồng bộ với tài khoản iCloud. Chú ý rằng feature nâng cao này phụ thuộc vào dung lượng bộ nhớ device và API của nó chỉ hoạt động sau khi app đã được khởi động ít nhất một lần. Không bắt buộc phải implement SKProductStorePromotionController mới có thể promote các in-app purchase lên App Store.

Complete a Purchase

Khi một user chọn mua một in-app purchase item trên App Store thì StoreKit sẽ tự động mở app của bạn lên rồi gửi các thông tin transaction qua các method delegate của protocol SKPaymentTransactionObserver. Việc của chúng ta là phải tiếp tục các purchase transaction và hoàn các phần việc còn lại sau giao dịch. Ví dụ: xác thực, cộng coin, unlock level, item...

Trong method delegate, return true để tiếp tục transaction, return false để tạm hoãn hoặc hủy bỏ giao dịch.

Nếu như app chưa được cài thì khi tap vào item in-app purchase thì App Store sẽ tự động yêu cầu user download và cài đặt nó (nếu app mất phí thì sẽ yêu cầu mua). Nếu app đã cài nhưng version hiện tại của app là bản chưa có tính năng promote in-app purchase này, App Store sẽ yêu cầu user upgrade app lên version mới nhất.

Continue a Transaction

Để tiếp tục một in-app purchase transaction, chúng ta chỉ cần implement delegate method paymentQueue(_:shouldAddStorePayment:for:) của protocol SKPaymentTransactionObserver và return true. StoreKit sẽ hiển thị trang thanh toán và sau đó user có thể hoàn thành giao dịch bình thường như mua in-app purchase truyền thống.

// Tiếp tục transaction từ App Store

//MARK: - SKPaymentTransactionObserver

func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment,
        forProduct product: SKProduct) -> Bool {
    // Check xem có thể hoàn thành transaction hay không?
    // Return true nếu có thể.
    return true
}

Defer or Cancel a Transaction

Nếu như bạn cần tạm hoãn hoặc hủy bỏ transaction đó, hãy return false. Ví dụ khi không kết nối được với server của app (không xác thực được giao dịch, service unavailable...), chúng ta cần tạm hoãn transaction này lại và tiếp tục khi server hoạt động. Hoặc khi user vốn đã unlock item, đã subscribe subscription đó rồi thì cần phải cancel transaction.

Để tạm hoãn một transaction:

  1. Lưu lại payment cần tạm dừng để tiếp tục khi app sẵn sàng. SKPayment chứa các thông tin về product, không được tạo mới instance SKPayment mới.
  2. Return false.
  3. Sau khi đủ điều kiện hoàn thành giao dịch, add lại payment đã lưu vào payment queue để tiếp tục transaction như bình thường.

Để hủy bộ một transaction:

  1. Return false.
  2. Đưa ra feedback, thông báo tới user. Mặc dù bước này là không bắt buộc nhưng nếu không thông báo cho user, app của bạn sẽ thiếu action, không phản hồi lại gì sau user tap vào mua in-app purchase trong App Store. Điều này trông giống như bug, sẽ khiến trải nghiệm người dùng không được tốt.
// Handle transaction từ App Store

//MARK: - SKPaymentTransactionObserver

func paymentQueue(_ queue: SKPaymentQueue, shouldAddStorePayment payment: SKPayment,
        forProduct product: SKProduct) -> Bool {

    // ... Check nếu như app không đủ điều kiện để hoàn thành transaction, phải tạm hoãn
    let shouldDeferPayment = ...
    // Nếu như phải tạm hoãn transaction, lưu lại payment và return false
    if shouldDeferPayment {
        self.savedPayment = payment
        return false
    }

    // ... Check nếu như phải hủy bỏ transaction
    let shouldCancelPayment = ...
    // Nếu như phải hủy bỏ transaction, return false:
    if shouldCancelPayment {
        return false
    }
}

// (Nếu như phải hủy bỏ transaction, đưa ra message thông báo tới user)

// Tiếp tục transaction đã lưu khi đủ điều kiện thanh toán tiếp transaction
SKPaymentQueue.default().add(savedPayment)

Visibility Settings

Get Visibility Settings

Để có thể get các setting visibility cho một product, sử dụng method fetchStorePromotionVisibility(for:completionHandler:) và truyền vào thông tin product.

// Get visibility settings của một promoted in-app purchase product
// Fetch product info

let storePromotionController = SKProductStorePromotionController.default()
storePromotionController.fetchStorePromotionVisibility(forProduct: hiddenBeaches,
    completionHandler: { visibility: SKProductSTorePromotionVisiblity, error: Error?) in
        // visibility == .default

Override Visibility Settings

Với mỗi device khác nhau, chúng ta có thể quyết định khi nào thì in-app purchase item đó ẩn hay hiện. Ví dụ, bạn muốn ẩn các item mà user đã mua và chỉ hiện các item mà hiện tại họ còn có thể mua.

Để làm được điều này, đầu tiên, fetch product info và update default store promotion controller với setting .hide, như dưới đây. Product này sẽ không còn hiện trên App Store đối với device này nữa.

// Update visibility settings của một promoted in-app purchase product
// Fetch product info

let storePromotionController = SKProductStorePromotionController.default()
storePromotionController.update(storePromotionVisibility: .hide, forProduct: proSubscription,
    completionHandler: { (error: Error?) in
        // Complete
    })

Ở ví dụ này, visibility được set mặc định bằng .default. Product ẩn hay hiện dựa trên setting mặc định mà bạn đã set trên App Store Connect.

Order of Promoted Products

Override the Order of Promoted Products

Tương tự visibility setting, với mỗi device khác nhau, chúng ta cũng có thể thay đổi thứ tự hiển thị các promoted in-app purchase item trên App Store. Ví dụ trong app game của bạn, user đã vượt qua level 10, bạn có thể thay đổi thứ tự, đưa các item của level lên đầu danh sách để user có thể dễ dàng nhìn thấy và mua chúng.

Để override thứ tự product mặc định, khởi tạo mảng các product theo thứ tự mà bạn muốn rồi truyền vào method update(storePromotionOrder:completionHandler:). Các product trong mảng này sẽ xuất hiện đúng thứ tự ở đầu danh sách, tiếp theo là các product còn lại mà bạn đã set trong App Store Connect.

// Update thứ tự hiển thị của các promoted in-app purchase product

// Fetch product info của các product cần re-order

let storePromotionController = SKProductStorePromotionController.default()
// Thay đổi thứ tự theo ý muốn
let newProductsOrder = [hiddenBeaches, proSubscription, fishingHotSpots]
storePromotionController.updateStorePromotionOrder(newProductsOrder,
    completionHandler: { (error: Error?) in
        // Complete
    })

Cancel Order Overrides

Để hủy các custom order, đơn giản chúng ta chỉ cần truyền mảng rỗng vào method update(storePromotionOrder:completionHandler:). Danh sách in-app purchase item sẽ được hiện thị theo trình tự mặc định.

Fetch Order Overrides

Để get product order của device hiện tại, sử dụng method fetchStorePromotionOrder(completionHandler:). Chúng ta sẽ nhận được một mảng các product theo thứ tự hiện tại. Nếu method này trả về một mảng rỗng, điều này có nghĩa là các product đang được hiện thị theo trình tự mặc định.

// Lấy thứ tự hiển thị của các promoted in-app purchase product

let storePromotionController = SKProductStorePromotionController.default()
storePromotionController.fetchStorePromotionOrder(completionHander: {
    (products: [SKProduct], error: Error?) in
        // products == [hiddenBeaches, proSubscription, fishingHotSpots
    })

Source article: Promoting In-App Purchases


All Rights Reserved