从验证收据中检查自动续订的订阅到期日期

时间:2017-08-10 13:17:02

标签: objective-c ios7 in-app-purchase

我在app delegate中调用收据验证方法来检查可再生流程。它在开发模式下工作正常但在从app store发布之后它总是返回yes,即使用户还没有购买该产品。请建议我做错了什么。在沙盒模式下它的工作正常,但在发布之后我发现了它总是返回真实的问题。为验证收据我使用下面的代码

//验证收据

+(BOOL)PurchasedSubscriptionStatues:(NSDictionary *)transactionReceipt
{
    if ([[transactionReceipt allKeys] containsObject:@"pending_renewal_info"]) {

        NSArray *arrData = [transactionReceipt objectForKey:@"pending_renewal_info"];
        NSDictionary *dicPendinRenew = [arrData objectAtIndex:0];
        if ([[dicPendinRenew allKeys] containsObject:@"expiration_intent"] || [[dicPendinRenew objectForKey:@"auto_renew_status"] integerValue]==0) {
            return NO;
        }else if ([[dicPendinRenew objectForKey:@"auto_renew_status"] integerValue]==1) {

            return YES;
        }else{
           return NO;
        }
    }else{
        return YES;
    }

    return NO;
}

检查是否存在可再生的待定......

+(NSString *)getJsonStringFromDictionary:(NSDictionary *)dicVal
{
    NSError *error = nil;
    NSData *postData = [NSJSONSerialization dataWithJSONObject:dicVal options:NSJSONWritingPrettyPrinted error:&error];
    NSString *postString = @"";
    if (! postData) {
        NSLog(@"Got an error: %@", error);
        return nil;
    }
    else { postString = [[NSString alloc] initWithData:postData encoding:NSUTF8StringEncoding];
        return postString;
    }
}
Convert  Dictionary to string
+(NSDictionary *) getJsonDictionaryWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
    NSString *jsonString = [self getStringWithPostFromUrlString:urlString andDataString:dataString];
    NSLog(@"getJsonDictionaryWithPostFromUrlString-->%@", jsonString); // see what the response looks like
    return [self getDictionaryFromJsonString:jsonString];
}


+ (NSDictionary *) getDictionaryFromJsonString:(NSString *)jsonstring {
    NSError *jsonError;
    NSDictionary *dictionary = (NSDictionary *) [NSJSONSerialization JSONObjectWithData:[jsonstring dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&jsonError];
    if (jsonError) {
        dictionary = [[NSDictionary alloc] init];
    }
    return dictionary;
}

将字符串转换为字典

+ (NSString *) getStringWithPostFromUrlString:(NSString *)urlString andDataString:(NSString *)dataString {
    NSString *s = @"";
    @try {
        NSData *postdata = [dataString dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
        NSString *postlength = [NSString stringWithFormat:@"%d", [postdata length]];
        NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
        [request setURL:[NSURL URLWithString:urlString]];
        [request setTimeoutInterval:60];
        [request setHTTPMethod:@"POST"];
        [request setValue:postlength forHTTPHeaderField:@"Content-Length"];
        [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
        [request setHTTPBody:postdata];
        NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
        if (data != nil) {
            s = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
        }
    }
    @catch (NSException *exception) {
        s = @"";
    }
    return s;
}


// from https://stackoverflow.com/questions/2197362/converting-nsdata-to-base64
+ (NSString*)base64forData:(NSData*)theData {
    const uint8_t* input = (const uint8_t*)[theData bytes];
    NSInteger length = [theData length];
    static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";
    NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t* output = (uint8_t*)data.mutableBytes;
    NSInteger i;
    for (i=0; i < length; i += 3) {
        NSInteger value = 0;
        NSInteger j;
        for (j = i; j < (i + 3); j++) {
            value <<= 8;

            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }
        NSInteger theIndex = (i / 3) * 4;
        output[theIndex + 0] =                    table[(value >> 18) & 0x3F];
        output[theIndex + 1] =                    table[(value >> 12) & 0x3F];
        output[theIndex + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
        output[theIndex + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
    }
    return [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
}


------------------------------------------------------------------------

//请求post方法获取recipt

    function BubbleSort(arr) {
      const sortedArray = Array.from(arr);
      let swap;
      do {
        swap = false;
        for (let i = 1; i < sortedArray.length; ++i) {
          if (sortedArray[i - 1] > sortedArray[i]) {
            [sortedArray[i], sortedArray[i - 1]] = [sortedArray[i - 1], sortedArray[i]];
            swap = true;
          }
        }
      } while (swap)
      return sortedArray;
    }
console.log(BubbleSort([3, 12, 9, 5]));

1 个答案:

答案 0 :(得分:0)

我认为您的PurchasedSubscriptionStatues方法有错误:如果收据中不包含pending_renewal_info密钥,则返回YES。尝试创建一个新的沙箱用户,看看收据是否包含此密钥,如果没有 - 那么在这种情况下此方法应该返回NO

此外,您可以尝试使用一些可以管理InApp购买的库,例如RMStore,以简化收据验证。