3

I'm following the documentation here.

https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html

I have a receipt-data from my team that I'm trying to validate, they're getting error code 21002 which was malformed JSON. It looks like they had extra parameters appended to the base64 data, so I tried removing those and sending:

- (void)viewDidLoad {
    [super viewDidLoad];

    NSData *receipt; // Sent to the server by the device



    // Create the JSON object that describes the request

    NSError *error;

    NSDictionary *requestContents = @{
                                      @"receipt-data": @"<<$mybase64data>>", @"password" : @"<<$thepassword>>"};

    NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error];



    if (!requestData) { /* ... Handle error ... */ }



    // Create a POST request with the receipt data.

    NSURL *storeURL = [NSURL URLWithString:@"https://buy.itunes.apple.com/verifyReceipt"];

    NSMutableURLRequest *storeRequest = [NSMutableURLRequest requestWithURL:storeURL];

    [storeRequest setHTTPMethod:@"POST"];

    [storeRequest setHTTPBody:requestData];



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

    NSOperationQueue *queue = [[NSOperationQueue alloc] init];

    [NSURLConnection sendAsynchronousRequest:storeRequest queue:queue

                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {

                               if (connectionError) {

                                   /* ... Handle error ... */

                                   NSLog(@"conerror %@", connectionError);
                               } else {

                                   NSError *error;

                                   NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];

                                   NSLog(@"hello %@", jsonResponse);
                                   NSLog(@"error %@", error);

                                   if (!jsonResponse) {

                                   }

                               }

                           }];



}

result:

2017-03-03 22:45:47.454 receipttest[89851:352604] hello {
    exception = "com.apple.jingle.mzfairplay.validators.DrmInvalidArgumentException";
    status = 21002;
}
2017-03-03 22:45:47.455 receipttest[89851:352604] error (null)
quantumpotato
  • 9,637
  • 14
  • 70
  • 146
  • Did you ever get to the bottom of this @quantumpotato? – WickedW Jul 19 '17 at 13:23
  • @WickedW , it started working about a week after that. I think Apple's servers were down; about th esame time (just a few days after), they were having 500s on iTunesConnect pages then updated the site. Seems to be working ok. Also, now Aple offers more resources for validating subscriptiosn and notifying server http://appleinsider.com/articles/17/07/18/apple-rolls-out-new-developer-tools-to-aid-in-subscription-retention – quantumpotato Jul 20 '17 at 14:05

4 Answers4

2

Something to keep in mind: In this example the data is sent to Apple straight from the App, but you might do this from a server too. When you testing your server App don't use NSLog() to print your base64 data, NSLog truncates data.

Larcho
  • 536
  • 5
  • 10
  • 2
    Straight from app allows for man-in-the-middle attacks, so imo there should always be server-server model for verifying receipts. – AppreciateIt Jul 19 '17 at 16:41
2

I had this issue when using a receipt from a test user that was a couple days old with a yearly auto-renewable subscription.

I checked the above helpful responses about extra characters etc (I also checked I had supplied my app secret for auto-renewable) with no joy.

In the end I tried creating A NEW SANDBOX user and it worked first time 
with no other changes other than the new Receipt!

Hope this helps someone.

WickedW
  • 2,331
  • 4
  • 24
  • 54
1

I also received the same error response for serveral receipts. The solution for me was to remove all occurrences of \r\n.

Maybe you have the same issue. I still haven't figured out when and why these chars are inserted.

Timo
  • 166
  • 6
  • I have seen this before working with binary data on iOS. However, when I paste my receipt-data into my text editor, I don't see `\r` or `\n`. When I remove these characters in Xcode with stringByReplacingOccurancesOfString, I do not see any change. – quantumpotato Mar 08 '17 at 16:27
  • The data being uploaded is the original paste from base64encodedString from the Swifty framework and Aplpe accepts it – quantumpotato Mar 08 '17 at 16:30
  • 1
    I uploaded receip via Ruby script and got the error mentioned here. Replacing `Base64.encode64` with `Base64.strict_encode64` helped. The first version produced base64 string with newlines. – silvansky Nov 16 '18 at 11:42
0

Pay attention to URLENCODE:

- (NSString *)URLEncodedString
{
    // CharactersToBeEscaped = @":/?&=;+!@#$()~',*";
    // CharactersToLeaveUnescaped = @"[].";

    NSString *unencodedString = self;
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)unencodedString,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));

    return encodedString;
}
piet.t
  • 11,718
  • 21
  • 43
  • 52
starry
  • 1