iOS在应用购买收据中,缺少近期交易

时间:2019-04-25 15:30:54

标签: ios swift in-app-purchase

我能够读取应用内购买(在沙箱中)的收据。我想验证他们的支票取消订阅。但是问题是,当我订阅任何产品时,我会得到“ 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
    }
}

任何帮助将不胜感激。

谢谢

1 个答案:

答案 0 :(得分:0)

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

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

  

对于还原先前事务的事务,此值为   与原始购买的交易标识符不同   交易。在自动续订的订阅收据中,一个新值   每次生成交易标识符时,   订阅会自动续订或在新设备上恢复。

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


此字段也可能支持您的用例: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字段。再次来自苹果公司:

  

此值对于为一个发票生成的所有收据都相同   具体订阅。该值对于将它们关联在一起很有用   同一个人的多个iOS 6样式的交易收据   客户的订阅。

但是,根据您所写的内容,这似乎使事情变得过于复杂。 ¯\_(ツ)_/¯