IAP实际验证收据(Swift)

问题描述 投票:3回答:3

我一直试图在我的spritekit游戏中实施收据验证。我一直在关注各种教程,并且基本上以以下代码结束]

enum RequestURL: String {
   case production = "https://buy.itunes.apple.com/verifyReceipt"
   case sandbox = "https://sandbox.itunes.apple.com/verifyReceipt"
   case myServer = "my server address"
}

enum ReceiptStatusCode: Int {

// Not decodable status
case unknown = -2

// No status returned
case none = -1

// valid status
case valid = 0

// The App Store could not read the JSON object you provided.
case JSONNotReadable = 21000

// The data in the receipt-data property was malformed or missing.
case malformedOrMissingData = 21002

// The receipt could not be authenticated.
case receiptCouldNotBeAuthenticated = 21003

// The shared secret you provided does not match the shared secret on file for your account.
// Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
case sharedSecretNotMatching = 21004

// The receipt server is currently not available.
case receiptServerUnavailable = 21005

// This receipt is valid but the subscription has expired. When this status code is returned to your server, the receipt data is also decoded and returned as part of the response.
// Only returned for iOS 6 style transaction receipts for auto-renewable subscriptions.
case subscriptionExpired = 21006

//  This receipt is from the test environment, but it was sent to the production environment for verification. Send it to the test environment instead.
case testReceipt = 21007

// This receipt is from the production environment, but it was sent to the test environment for verification. Send it to the production environment instead.
case productionEnvironment = 21008
 }

  func validateReceipt(forTransaction transaction: SKPaymentTransaction) {

    guard let receiptURL = NSBundle.mainBundle().appStoreReceiptURL else { return }

    guard let receipt = NSData(contentsOfURL: receiptURL) else { return }

    let receiptData = receipt.base64EncodedStringWithOptions(NSDataBase64EncodingOptions(rawValue: 0))
    let payload = ["receipt-data": receiptData]

    var receiptPayloadData: NSData?

    do {
        receiptPayloadData = try NSJSONSerialization.dataWithJSONObject(payload, options: NSJSONWritingOptions(rawValue: 0))
    }
    catch let error as NSError {
        print(error.localizedDescription)
        return
    }

    guard let payloadData = receiptPayloadData else { return }
    guard let requestURL = NSURL(string: RequestURL.sandbox.rawValue) else { return }

    let request = NSMutableURLRequest(URL: requestURL)
    request.HTTPMethod = "POST"
    request.HTTPBody = payloadData

    let task = NSURLSession.sharedSession().dataTaskWithRequest(request) { (data, response, error) in
         if let error = error {
            print(error.localizedDescription)
            return
        }  
         guard let data = data else { return }          

         do {
            let jsonData = try NSJSONSerialization.JSONObjectWithData(data, options: .MutableLeaves) as? NSDictionary

            guard let json = jsonData else { return }

            // Correct ?
            guard let status = json["status"] as? Int where status == ReceiptStatusCode.valid.rawValue else { return }

            // Unlock product here?
            // Other checks needed?
        }

        catch let error as NSError {
            print(error.localizedDescription)
            return
        }
     }

    task.resume()
}

这是漂亮的样板代码,可以正常工作。我现在的问题是,我不知道如何在最后一步(标记行)实际验证收据。我相信我现在必须携带5张左右的支票以验证收据。我只是不知道其中大多数将如何迅速完成。大多数教程要么太旧了,要么不包含此步骤,要么不迅速编写。

[如果成功使用收据验证的人可以帮助我朝正确的方向前进,将不胜感激。非常感谢你

更新:

在获得JSA986I和cbartel的好评后,我将其转变为github上的帮助器。非常感谢您的帮助

https://github.com/crashoverride777/SwiftyReceiptValidator

swift validation in-app-purchase receipt
3个回答
4
投票

这就是您以JSON返回收据并可以访问它的地方。即

if parseJSON["status"] as? Int == 0 {
    println("Sucessfully returned purchased receipt data")
}

将告诉您您是否已成功获得收据,因为["status"] 0表示已将其退还好

您可以进一步查询并使用收据数据来查找和使用JSON响应中的项目。在这里您可以打印最新的收据信息

if let receiptInfo: NSArray = parseJSON["latest_receipt_info"] as? NSArray {
    let lastReceipt = receiptInfo.lastObject as! NSDictionary
    // Get last receipt
    println("LAST RECEIPT INFORMATION \n",lastReceipt)
}

现在您拥有要使用的json数据

您现在可以查询该数据,在本示例中,我们正在从JSOn响应中查找自动续订的订阅何时到期

// Format date
var formatter = NSDateFormatter()
formatter.dateFormat = "yyyy-MM-dd HH:mm:ss VV"
formatter.locale = NSLocale(localeIdentifier: "en_US_POSIX")

// Get Expiry date as NSDate
let subscriptionExpirationDate: NSDate = formatter.dateFromString(lastReceipt["expires_date"] as! String) as NSDate!
println("\n   - DATE SUBSCRIPTION EXPIRES = \(subscriptionExpirationDate)")

将以上代码发布在]下>

if let parseJSON = json {
    println("Receipt \(parseJSON)")
}

9
投票

这里是Apple guide之后使用Swift 2.1的解决方案。


0
投票

今天,我遇到了这个问题。我引用了这个答案。但是我发现了一种检查订阅是否过期的新方法。

© www.soinside.com 2019 - 2024. All rights reserved.