iOS验证verifyReceipt

在iOS应用开发中,很多应用都需要使用In-App Purchase(应用内购买)功能。为了确保用户购买的商品是合法的,我们需要对用户的购买凭证进行验证。而在iOS中,验证购买凭证的过程被称为verifyReceipt。

什么是verifyReceipt?

verifyReceipt是指对用户购买凭证进行验证的过程。在iOS应用中,每个应用都有一个独立的应用内购买凭证(Receipt),用于记录用户的购买信息。这个凭证是由苹果服务器签发的,包含了用户购买的商品信息、交易ID等等。

在应用内购买凭证被传递给我们的服务器时,我们需要将其发送给苹果服务器进行验证。验证的目的是确保该凭证是有效且未被篡改的,以及该凭证对应的商品是否被成功购买。

如何进行verifyReceipt?

在iOS中,我们可以通过两种方式进行verifyReceipt的验证:本地验证和服务器验证。

本地验证

本地验证是指在iOS设备上进行验证,这种方式比较简单,但相对不够安全。本地验证只能验证凭证的合法性,无法验证交易是否被成功处理。

本地验证的代码如下所示:

func verifyReceiptLocally(receiptData: Data) -> Bool {
    // 解码凭证数据
    guard let receipt = try? JSONSerialization.jsonObject(with: receiptData, options: []) as? [String: Any] else {
        return false
    }
    
    // 检查凭证是否合法
    guard let status = receipt["status"] as? Int, status == 0 else {
        return false
    }
    
    // 检查凭证是否被篡改
    guard let receiptHash = receipt["receiptHash"] as? String else {
        return false
    }
    
    let computedHash = computeHash(receiptData)
    guard computedHash == receiptHash else {
        return false
    }
    
    return true
}

func computeHash(data: Data) -> String {
    // 计算凭证的哈希值
    // ...
}

在本地验证中,我们首先需要将凭证数据解码成JSON格式,然后检查凭证的状态是否为0(表示合法)。接下来,我们需要计算凭证的哈希值,与凭证中的哈希值进行比较,以确保凭证未被篡改。

服务器验证

服务器验证是指将凭证发送给苹果服务器进行验证,这种方式更加安全可靠。服务器验证可以通过验证凭证的方式来确保交易的合法性和成功处理。

服务器验证的代码如下所示:

func verifyReceiptOnServer(receiptData: Data) {
    let url = URL(string: "
    var request = URLRequest(url: url)
    request.httpMethod = "POST"
    request.httpBody = receiptData
    
    let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
        guard let data = data, error == nil else {
            // 网络请求失败
            return
        }
        
        // 解析服务器返回的数据
        guard let receipt = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any] else {
            // 数据解析失败
            return
        }
        
        // 检查服务器返回的数据
        // ...
    }
    
    task.resume()
}

在服务器验证中,我们首先需要将凭证发送给苹果服务器进行验证。验证的URL可以使用沙盒环境(sandbox)或正式环境(production),具体选择哪个环境取决于应用的当前状态。然后,我们需要解析服务器返回的数据,并根据返回的结果进行相应的处理。

verifyReceipt的返回结果

无论是本地验证还是服务器验证,verifyReceipt的返回结果都是一个JSON对象。这个对象中包含了验证的结果信息,如购买状态、商品信息等等。

下面是一个示例的返回结果:

{
    "status": 0,
    "receipt": {
        "appId": "com.example.app",
        "bundleId": "com.example.app",
        "inApp": [
            {
                "productId": "com.example.product1",
                "