【问题标题】:iOS in app purchase receipt, missing recent transactionsiOS 应用内购买收据,缺少最近的交易
【发布时间】:2019-05-15 18:21:42
【问题描述】:

我能够读取应用内购买的收据(在沙盒中)。我想验证它们以检查已取消的订阅。但问题是,当我订阅任何产品时,我会获得 'transaction_id' 值,但是当我重新启动我的应用并再次获得收据时,我之前的 'transaction_id' 值会丢失.我希望我订阅的“transaction_id”始终显示在我的收据数组中。

这是我的代码:

func receiptValidation() {

    let receiptFileURL = Bundle.main.appStoreReceiptURL
    let receiptData = try? Data(contentsOf: receiptFileURL!)
    let recieptString = receiptData?.base64EncodedString(options: NSData.Base64EncodingOptions(rawValue: 0))
    let jsonDict: [String: AnyObject] = ["receipt-data" : recieptString! as AnyObject, "password" : "My-App-Shared-Secret" as AnyObject]
    do {
        let requestData = try JSONSerialization.data(withJSONObject: jsonDict, options: JSONSerialization.WritingOptions.prettyPrinted)
        let verifyReceiptURL = "https://sandbox.itunes.apple.com/verifyReceipt"
        let storeURL = URL(string: verifyReceiptURL)!
        var storeRequest = URLRequest(url: storeURL)
        storeRequest.httpMethod = "POST"
        storeRequest.httpBody = requestData

        let session = URLSession(configuration: URLSessionConfiguration.default)
        let task = session.dataTask(with: storeRequest, completionHandler: { [weak self] (data, response, error) in
            do {
                let jsonResponse = try JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)
                print("=======>",jsonResponse)
                if let date = self?.getExpirationDateFromResponse(jsonResponse as! NSDictionary) {
                    print(date)
                }
            } catch let parseError {
                print(parseError)
            }
        })
        task.resume()
    } catch let parseError {
        print(parseError)
    }
}

func getExpirationDateFromResponse(_ jsonResponse: NSDictionary) -> Date? {

    if let receiptInfo: NSArray = jsonResponse["latest_receipt_info"] as? NSArray {

        let lastReceipt = receiptInfo.lastObject as! NSDictionary

        // Get last receipt
        print("LAST RECEIPT INFORMATION \n",lastReceipt)

        let formatter = DateFormatter()
        formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
        formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX") as Locale

        if let expiresDate = lastReceipt["expires_date"] as? String {
            print("\n   - DATE SUBSCRIPTION EXPIRES = \(expiresDate)")
            return formatter.date(from: expiresDate)
        }

        return nil
    }
    else {
        return nil
    }
}

任何帮助将不胜感激。

谢谢

【问题讨论】:

  • 您在问题中提到了transaction_id,但在您发布的代码中没有提及它。你到底想达到什么目的?

标签: ios swift in-app-purchase


【解决方案1】:

我认为您不应该依赖 transaction_id 来检查已取消的订阅。

As per Apple's documentation(搜索“transaction_id”),可以随时间变化:

对于恢复之前交易的交易,该值为 不同于原始购买的交易标识符 交易。在自动更新订阅收据中,新值 交易标识符是每次生成的 订阅会自动续订或在新设备上恢复。

相反,最好使用latest_receipt_info 数组中的最新expires_date
将其与今天的日期进行比较,以检查订阅是否过期。


此字段也可能支持您的用例:auto_renew_status

如(来自 Apple 的验证 JSON 响应):

{
  "status": 0,
  "environment": "Sandbox",
  "receipt": {...},
  "latest_receipt_info": [{...}],
  "latest_receipt": "...",
  "pending_renewal_info": [
    {
      "auto_renew_product_id": "<yourAutoRenewProductID>",
      "original_transaction_id": "<transacionID>",
      "product_id": "<yourProductID>",
      "auto_renew_status": "1" <<=== This one here
    }
  ]
}

"1" - 订阅将在当前订阅结束时续订 期间。

“0” - 客户已为其关闭自动续订 订阅。

记住:

此密钥仅适用于自动更新订阅收据,用于 有效或过期的订阅。此键的值不应为 解释为客户的订阅状态。你可以用这个 在您的应用中显示替代订阅产品的值,用于 例如,客户可以使用的较低级别的订阅计划 降级到他们当前的计划。


如果您真的需要知道原始的transaction_id,那么就有original_transaction_id 字段。再次来自 Apple:

该值对于已为 具体订阅。该值对于关联在一起很有用 同一个人的多个 iOS 6 样式交易收据 客户的订阅。

但根据您写的内容,这似乎过于复杂了。 ¯\_(ツ)_/¯

【讨论】:

    猜你喜欢
    • 2017-12-19
    • 2013-07-20
    • 1970-01-01
    • 2012-09-26
    • 1970-01-01
    • 2011-09-30
    • 2014-07-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多