在iOS 7中,由appStoreReceiptURL(NSData)返回无效的事务接收
我使用以下方法获取收据数据:
// Use this method instead of accessing transaction.transactionReceipt directly! - (NSData *)appStoreReceiptForPaymentTransaction:(SKPaymentTransaction *)transaction { NSData *receiptData = nil; // This is just a quick/dummy implementation! if (kiOS7) { NSURL *receiptFileURL = [[NSBundle mainBundle] appStoreReceiptURL]; receiptData = [NSData dataWithContentsOfURL:receiptFileURL]; // Returns valid NSData object } else { receiptData = transaction.transactionReceipt; // Returns valid NSData object } return receiptData; }
我正在使用以下代码来阅读JSON收据:
NSData *receipt = [self appStoreReceiptForPaymentTransaction:transaction]; NSError *error = nil; NSDictionary *receiptDict = [receipt dictionaryFromPlistData:&error]; NSString *transactionPurchaseInfo = [receiptDict objectForKey:@"purchase-info"]; NSString *decodedPurchaseInfo = [NSString stringWithUTF8String:[[NSData dataFromBase64String:transactionPurchaseInfo] bytes]]; NSDictionary *purchaseInfoDict = [[decodedPurchaseInfo dataUsingEncoding:NSUTF8StringEncoding] dictionaryFromPlistData:&error]; NSString *transactionID = [purchaseInfoDict objectForKey:@"transaction-id"]; NSString *purchaseDateString = [purchaseInfoDict objectForKey:@"purchase-date"]; NSString *signature = [receiptDict objectForKey:@"signature"]; NSString *signatureDecoded = [NSString stringWithUTF8String:[[NSData dataFromBase64String:signature] bytes]]; // Convert the string into a date NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init]; [dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss z"]; NSDate *purchaseDate = [dateFormat dateFromString:[purchaseDateString stringByReplacingOccurrencesOfString:@"Etc/" withString:@""]]; NSLog(@"Raw receipt content: \n%@", [NSString stringWithUTF8String:[receipt bytes]]); NSLog(@"Purchase Info: %@", purchaseInfoDict); NSLog(@"Transaction ID: %@", transactionID); NSLog(@"Purchase Date: %@", purchaseDate); NSLog(@"Signature: %@", signatureDecoded);
dictionaryFromPlistData:
方法为transactionReceipt
返回的数据返回合适的NSDictionary
对象,但是它返回nil
使用使用appStoreReceiptURL
返回的数据 – 并且很appStoreReceiptURL
,我没有得到有效的收据!
- (NSDictionary *)dictionaryFromPlistData:(NSError **)outError { NSError *error; NSDictionary *dictionaryParsed = [NSPropertyListSerialization propertyListWithData:self options:NSPropertyListImmutable format:nil error:&error]; if (!dictionaryParsed) { if (error) { *outError = error; } return nil; } return dictionaryParsed; }
为什么上面的代码不在iOS 7中工作?
只要重申, dictionaryFromPlistData:
正确地转换由transaction.transactionReceipt
返回的NSData
。
iOS 7已经改变了接收validation的完成方式。 我经历了你下来的确切path,并得到相同的结果。 我发现从[[NSBundle mainBundle] appStoreReceiptURL]
的收据需要一个不同于以前的transaction.transactionReceipt
解码方法。
以下是苹果公司的文档片段:
最外面的部分是由RFC 2315定义的PKCS#7容器,其有效负载使用ITU-T X.690定义的ASN.1(抽象语法表示法1)编码。 有效载荷由一组收据属性组成。 每个收据属性都包含一个types,一个版本和一个值。
如果你正在寻找一个快速解决scheme,我已经看到成功在这里: https : //github.com/rmaddy/VerifyStoreReceiptiOS