English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية
ios7After version .0, the way to obtain the票据Receipt returned by iOS payment has a new method
The method of obtaining the票据from the transactionReceipt attribute in the original SKPaymentTransaction has become outdated, although it can still be used, Apple officially recommends using the new one
The way to obtain the Receipt in the new version is through the new interface as follows
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
Of course, below ios7.0 still needs to use the old version interface, and the code for adapting both versions is as follows:
NSData*receipt= nil; if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){ //ios after 7.0 NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL]; receipt = [NSData dataWithContentsOfURL:receiptURL]; NSString *receiptURLStr = [receiptURL absoluteString]; NSRange rangeSandbox = [receiptURLStr rangeOfString:@"sandbox"]; if (rangeSandbox.location != NSNotFound){ record[kIAPEnvironment] = [NSNumber numberWithInt:1]; } } //ios 3.0~7.0 receipt = transaction.transactionReceipt; NSDictionary *dict = [NSDictionary dictionaryWithContentsOfData:receipt]; if (dict){ NSString *env = [dict objectForKey:@"environment"]; if ([env isEqualToString:@"Sandbox"]) { record[kIAPEnvironment] = [NSNumber numberWithInt:1]; } } }
Determine if it is a sandbox payment, in the new version it can directly determine if there is 'sandbox' in the receiptURL
The old version of receipt can be parsed NSData to check if environment is Sandbox to determine
+ (NSDictionary *)dictionaryWithContentsOfData: (NSData *)data{ CFPropertyListRef plist = CFPropertyListCreateFromXMLData(kCFAllocatorDefault, (__bridge CFDataRef)data, kCFPropertyListImmutable, NULL); if(plist == nil) return nil; if ([(__bridge id)plist isKindOfClass:[NSDictionary class]]){ return (__bridge NSDictionary *)plist; } CFRelease(plist); return nil; } }
Client receipt verification method:
NSError *error; NSDictionary *requestContents = @{ @"receipt-data": [receipt base64EncodedString] }; NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContents options:0 error:&error]; if (!requestData) { return; } // Create a POST request with the receipt data. NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt];//According to whether it is sandbox payment verification, get the correct address 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 ... */ } else {}} NSError *error; NSDictionary *jsonResponse = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error]; if (!jsonResponse) { /* ... Handle error ...*/ } /* ... Send a response back to the device ... */ } };
Old version return format:
{ bid = "com.coodezhang.test"; bvrs = "1.0"; "item_id" = 892617314; "original_purchase_date" = "2017-12-14 07:43:14 Etc/GMT" "original_purchase_date_ms" = 1626147394550; "original_purchase_date_pst" = "2017-12-14 12:43:14 America/Los_Angeles "original_transaction_id" = 1000001127239959; "product_id" = "com.coodezhang.test_coins"99M_Tier1"; "purchase_date" = "2017-12-14 07:43:14 Etc/GMT" "purchase_date_ms" = 1626147394550; "purchase_date_pst" = "2017-12-14 12:43:14 America/Los_Angeles quantity = 1; "transaction_id" = 1000001127239959; "unique_identifier" = 0000b0124819; "unique_vendor_identifier" = "ASDGF"2DB-DSAD-5A21-9611-642A4B9CASDE7"; }; status = 0; }
Official documentation of the new version return format:Official documentation
New version return format:
{ environment = Sandbox; receipt = { "adam_id" = 0; "app_item_id" = 0; "application_version" = 1; "bundle_id" = "com.coodezhang.test"; "download_id" = 0; "in_app" = ( { "is_trial_period" = false; "original_purchase_date" = "2017-12-14 07:18:56 Etc/GMT" "original_purchase_date_ms" = 1513235936000; "original_purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles "original_transaction_id" = 1000000359369424; "product_id" = "com.coodezhang.test_coins"99M_Tier1"; "purchase_date" = "2017-12-14 07:18:56 Etc/GMT" "purchase_date_ms" = 1513235936000; "purchase_date_pst" = "2017-12-13 23:18:56 America/Los_Angeles quantity = 1; "transaction_id" = 1000000359369424; } ...... May exist multiple ); "original_application_version" = "1.0"; "original_purchase_date" = "2013-08-01 07:00:00 Etc/GMT" "original_purchase_date_ms" = 1375340400000; "original_purchase_date_pst" = "2013-08-01 00:00:00 America/Los_Angeles "receipt_creation_date" = ""2017-12-14 07:18:56 Etc/GMT" "receipt_creation_date_ms" = 1513235936000; "receipt_creation_date_pst" = ""2017-12-13 23:18:56 America/Los_Angeles "receipt_type" = ProductionSandbox; "request_date" = ""2017-12-14 07:19:23 Etc/GMT" "request_date_ms" = 1513235963829; "request_date_pst" = ""2017-12-13 23:19:23 America/Los_Angeles "version_external_identifier" = 0; }; status = 0; }
It is worth noting that the in_app field in the new version of the data structure may contain multiple transaction receipts. If the interface for reading the receipt has not been successfully called after completing the transaction, all of them will be read out next time, resulting in multiple data.
Generally, developers' app payments have their own payment systems, and they may create their own order numbers before each order, which need to be matched one by one with the receipts returned by iOS payment. In this case, how to handle it needs to be paid attention to.
That's all for this article, I hope it will be helpful to everyone's learning, and I also hope everyone will support the Shouting Tutorial more.
Statement: The content of this article is from the Internet, the copyright belongs to the original author, the content is contributed and uploaded by Internet users spontaneously, this website does not own the copyright, does not undergo manual editing, and does not assume relevant legal liabilities. If you find any content suspected of copyright infringement, please send an email to: notice#w3Please report any violations by email to codebox.com (replace # with @) and provide relevant evidence. Once verified, the website will immediately delete the suspected infringing content.