1

我正在使用 AFNetworking 编写以下代码以进行收据验证,它给了我 status=210002 而它在 NSMutableURLRequest 中给了我 status=0

请帮助我获得解决方案

 NSString *strurl = @"https://sandbox.itunes.apple.com/verifyReceipt";   
 NSData *receipt = [NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL]];

 NSDictionary *parameter=@{
                          @"receipt-data" : [receipt base64EncodedStringWithOptions:0],
                          @"password" : @"xxxxxxxxxxxxxxxxxxxx",
                         };


 NSData *jsonParam = [NSJSONSerialization dataWithJSONObject:parameter options:NSJSONWritingPrettyPrinted error:nil];

 AFHTTPRequestOperationManager *manager =  [AFHTTPRequestOperationManager manager];
 manager.responseSerializer.acceptableContentTypes = [manager.responseSerializer.acceptableContentTypes setByAddingObject:@"text/plain"];
 [manager POST:strurl parameters:jsonParam success:^(AFHTTPRequestOperation *oprtation, id responseObject){
    NSLog(@"JSON: %@", responseObject);

 }failure:^(AFHTTPRequestOperation *operation, NSError *error){
    NSLog(@"Error: %@", error);

 }];

谢谢

4

2 回答 2

2

这是我在我的应用程序中使用的收据验证代码,但我很快就实现了。

我还使用 NSMutableURLRequest 对 iTunes 服务器进行 Web 服务调用。

    func verifyPaymentReceipt(){

    let mainBundle = NSBundle.mainBundle() as NSBundle;
    let receiptUrl = mainBundle.appStoreReceiptURL;
    let isPresent = receiptUrl?.checkResourceIsReachableAndReturnError(NSErrorPointer());

    if(isPresent == true){

        let data = NSData(contentsOfURL: receiptUrl! );

        // Create the JSON object that describes the request

        let requestContents  = NSMutableDictionary();
        //            let encodeddata = data!.base64EncodedStringWithOptions(NSDataBase64EncodingOptions());
        let encodeddata = data!.base64EncodedString();

        print("encodeddata = \(encodeddata)");

        requestContents.setObject(encodeddata, forKey: "receipt-data");
        requestContents.setObject("xxxxxxxxxxxxxxxxxxxxxxx", forKey: "password");
        var requestData : NSData?
        do{
            requestData = try NSJSONSerialization.dataWithJSONObject(requestContents, options: NSJSONWritingOptions());
        }catch{
            NSLog("Error in json data creation at verifyPaymentReceipt");
        }

        let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
        let file = "\(documentsPath)/requestData"

        if(NSFileManager.defaultManager().createFileAtPath(file, contents: data, attributes: nil)){
            NSLog("File %@ ",file);
        }
        else{
            NSLog("error File %@ ",file);
        }



        if(requestData != nil){

            let strRequestData = NSString(data: requestData!, encoding: NSUTF8StringEncoding);
            print(" strRequestData = \(strRequestData)");
            // Create a POST request with the receipt data.

            let storeURL = NSURL(string: "https://sandbox.itunes.apple.com/verifyReceipt");
            let storeRequest = NSMutableURLRequest(URL: storeURL!);
            storeRequest.HTTPMethod = "POST";
            storeRequest.HTTPBody = requestData;

            // Make a connection to the iTunes Store on a background queue.

            let queue = NSOperationQueue();
            NSURLConnection.sendAsynchronousRequest(storeRequest, queue: queue, completionHandler: { (response : NSURLResponse?, data : NSData?, error : NSError?) -> Void in

                if(error != nil){
                    //Handle Error
                }
                else{
                    let d = NSString(data: data!, encoding: NSUTF8StringEncoding);
                    NSLog("DATA:%@", d!);

                    var jsonResponse: NSMutableDictionary?
                    do{
                        jsonResponse = try NSJSONSerialization.JSONObjectWithData(data!,
                            options: NSJSONReadingOptions.AllowFragments) as? NSMutableDictionary;
                        print(jsonResponse);

                    }catch{
                        NSLog("Parsing issue : verifyPaymentReceipt");
                    }

                    if(jsonResponse != nil){

                        let expirationDate: NSDate? = self.expirationDateFromResponse(jsonResponse!);
                        NSLog("Expiration Date: %@", expirationDate!);

                    }
                }
            });

        }

    }

}

As you mention that your code works fine with NSMutableURLRequest but it returns 21002 with AFNetworking.

21002 - 收据数据属性中的数据格式不正确或丢失。

这意味着您的编码收据数据在使用 AFNetworking 时格式不正确。所以我认为这是使用 AFNetworking 进行编码的问题。

在 iOS 7 中,Apple 在 NSData 上引入了新的 base64 方法,使得无需使用第 3 方 base 64 解码库,但我仍然建议您尝试使用Base64编码进行收据编码。我希望这能解决您使用 AFNetworkig 的问题。因为当我验证来自服务器端的收据时,我也面临同样的 21002 问题,并且此编码库在这种情况下有效。不知道如何,但它解决了我在服务器端的收据验证呼叫问题。希望它也对你有用。

于 2015-12-24T13:25:59.433 回答
1

这是我在目标 C 中使用的 iOS 收据验证代码片段,用于检查应用启动时的续订。这有助于我在应用启动时从 App Store 获取订阅续订收据数据。

- (void)verifyPurchaseWithPaymentTransaction:(SKPaymentTransaction *)transaction isTestServer:(BOOL)flag{
    NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
    NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
    [self handleActionWithType:kIAPPurchSuccess data:receipt];

    NSError *error;
    NSDictionary *requestContents = @{
                                      @"receipt-data": [receipt base64EncodedStringWithOptions:0],
                                      @"password": @"INSERT_PASSWORD_HERE",
                                      @"exclude-old-transactions": @"true"
                                      };
    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents
                                                          options:0
                                                            error:&error];

    NSString *serverString = @"https://buy.itunes.apple.com/verifyReceipt";
    NSURL *storeURL = [NSURL URLWithString:serverString];
    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];
    [storeRequest setHTTPMethod:@"POST"];
    [storeRequest setHTTPBody:requestData];

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                               if (connectionError) {
                                   [self handleActionWithType:KIAPPurchVerFailed data:nil];
                               } else {
                                   NSError *error;
                                   NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
                                   if (!jsonResponse) {
                                       [self handleActionWithType:KIAPPurchVerFailed data:nil];
                                   }
                                   NSString *status = [NSString stringWithFormat:@"%@",jsonResponse[@"status"]];
                                   if (status && [status isEqualToString:@"21007"]) {
                                       [self verifyPurchaseWithPaymentTransaction:transaction isTestServer:YES];
                                   }else if(status && [status isEqualToString:@"0"]){
                                       [self handleActionWithType:KIAPPurchVerSuccess data:nil];
                                   }
#if DEBUG
                                   NSLog(@"log-IAP> jsonResults: %@",jsonResponse);
#endif
                               }
                           }];
    [[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}

希望这可以帮助。如果你能尽快将你的 Objective C 项目转换为 swift 最好,因为它越来越难找到关于 Objective C 的教程,尤其是对于更新的实现。

于 2020-05-26T19:39:42.430 回答