4

我们正在开发具有自动续订订阅的应用程序。我们只有一种选择 - 每月自动续订订阅和一周免费试用。我们还使用“订阅状态 URL”来接收订阅通知。

该应用程序本身类似于“TO DO LIST”应用程序,可以在多个用户之间共享任务。因此,我们将数据保存在服务器上。

每次用户加载应用程序或创建任务时,数据都来自带有 current_subscription_status 参数的服务器,例如,我们通过简单地检查收据到期日期与服务器上的当前日期来在服务器上进行订阅状态验证。

目前我们只有 iOS 版本,但也适用于 Android 版本。并且用户应该能够在具有不同 Apple id 的不同设备上唱歌到他/她的帐户中。

我们遇到的问题是我们没有收到实际的购买(订阅)通知。例如,当用户点击“开始您的免费 1 周试用”按钮并订阅时,我们会收到通知(输入 INITIAL_BUY)。在这个一周的试用期之后,我们应该收到另一份类似“续订”之类的通知,但我们什么也没收到。

我们联系了 Apple 开发人员支持,但没有得到真正的帮助。他们只是发送指向 Apple 文档的链接。我们在哪里找到了以下注释(这里是链接):

“要在处理事件时获取最新信息,您的应用应向 App Store 验证最新收据。”

因此,基于此,我对可能的用例场景有疑问:

用户在 iOS 设备上订阅每月自动续订订阅,例如他/她想从他/她的苹果 iTunes 帐户中收取费用。但是,在初次购买后,他/她会关闭(杀死)应用程序,甚至不再在 iOS 设备上打开它。用户将应用程序下载到 Android 设备并仅在 Android 上使用该应用程序。因此,App Store 应该每月向该用户收费并向服务器发送订阅状态通知,即使用户再也没有在他的 iOS 设备上打开过该应用程序。因此,iOS 应用程序永远不会发生“...最新收据验证...”。如何实施?

技术细节:

我们使用 SwiftyStoreKit。这是应用内购买实现的两个部分:

  1. 在 AppDelegate 中,我们有:

            // Auto-renewal complete transactions
        SwiftyStoreKit.completeTransactions(atomically: true) { purchases in
            for purchase in purchases {
                if purchase.transaction.transactionState == .purchased || purchase.transaction.transactionState == .restored {
                    if purchase.needsFinishTransaction {
                        // Deliver content from server, then:
                        SwiftyStoreKit.finishTransaction(purchase.transaction)
                    }
                }
            }
        }
    
  2. 这是用户点击“开始免费试用按钮”时调用的订阅功能:

    func subscribe(completion: @escaping (_ response:Bool, _ message: String?) -> Void) {
    
    SwiftyStoreKit.purchaseProduct(self.productId, atomically: true) { result in
    
        if case .success(let purchase) = result {
            if purchase.needsFinishTransaction {
                SwiftyStoreKit.finishTransaction(purchase.transaction)
            }
            let appleValidator = AppleReceiptValidator(service: self.env, sharedSecret: self.sharedSecret)
            SwiftyStoreKit.verifyReceipt(using: appleValidator) { result in
    
                if case .success(let receipt) = result {
                    let purchaseResult = SwiftyStoreKit.verifySubscription(
                        type: .autoRenewable,
                        productId: self.productId,
                        inReceipt: receipt)
                    switch purchaseResult {
                    case .purchased(let expiryDate, let receiptItems):
    
                        if let receiptItem = receiptItems.first {
                            // Send receipt to the server functionality
                            .............................
                        }
                        completion(true, nil)
                    case .expired(let expiryDate, let receiptItems):
                        completion(false, "Receipt has been expired")
                    case .notPurchased:
                        completion(false, "Purchase has not been processed")
                    }
                } else {
                    // receipt verification error
                    completion(false, "ERROR OCCURED")
                }
            }
        } else {
            // purchase error
            completion(false, "Canceled")
        }
    }}
    
4

0 回答 0