AppStore in-App Purchase Receipt Verification Issues

后端 未结 3 490
忘掉有多难
忘掉有多难 2020-12-29 13:53

I know there have been quite a few posts on this but none seem to address the issues we\'re running into. So far I think I have everything setup correctly as specified in th

3条回答
  •  野趣味
    野趣味 (楼主)
    2020-12-29 14:32

    For anyone else in the future getting the 21002 error. It took a few hours to figure what was going wrong. It generally means that the base 64 encoded string within the JSON you send to Apple's servers is incorrect. This probably means that you're not Base-64 encoding or that your encoding routine is buggy. These are the steps you should use:

    1) Base-64 encode all the NSData you receive from the transactionReceipt property of your SKPaymentTransaction object into a NSString object. You can use the method below.

    2) Insert that into a JSON string. In objective-C code it would be:

    NSString* json = [NSString stringWithFormat:@"{ 'receipt-data' : '%@' }", base64String];
    

    3) HTTP POST that

    4) You will get a JSON string back - extract the value for 'status'. If it is 0 your receipt has been confirmed - otherwise it is an unverified purchase.

    Below is the code I use to convert the NSData to a Base-64 encoded string:

    @interface NSData (Base64Encoding)
    
    - (NSString*)base64Encode;
    
    @end
    
    @implementation NSData (Base64Encoding)
    
    - (NSString*)base64Encode
    {
        static char table [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    
        NSInteger length = [self length];
        NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
        uint8_t* input = (uint8_t*)[self bytes];
        uint8_t* output = (uint8_t*)data.mutableBytes;
    
        for (NSInteger i = 0; i < length; i += 3)
        {
            NSInteger value = 0;
            for (NSInteger j = i; j < (i + 3); ++j)
            {
                value <<= 8;
    
                if (j < length)
                {
                    value |= (0xff & input[j]);
                }
            }
    
            NSInteger index = (i / 3) * 4;
            output[index + 0] =                    table[(value >> 18) & 0x3f];
            output[index + 1] =                    table[(value >> 12) & 0x3f];
            output[index + 2] = (i + 1) < length ? table[(value >> 6) & 0x3f] : '=';
            output[index + 3] = (i + 2) < length ? table[(value >> 0) & 0x3f] : '=';
        }
    
        return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
    }
    
    @end
    

    To use it just do something like:

    NSString* base64string = [transaction.transactionReceipt base64Encode];
    

提交回复
热议问题