ios7.0后ios支付成功返回的票据Receipt的获取方式有了新的方式,
原来的SKPaymentTransaction中的transactionReceipt属性获取票据的方式已经过期,虽然还能使用,但是苹果官方建议使用新的
新版的获取Receipt的方式是通过新接口如下
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];
当然,低于ios7.0的还是需要使用老版本接口,对两种版本进行适配的代码如下:
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]; }}else{//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]; } }}
判断是否是沙盒支付,新版本可以直接判断receiptURL中是否存在“sandbox“
老版本receipt可以解析NSData 查看environment是否为Sandbox来判断
+ (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; }else{ CFRelease(plist); return nil; }}
客户端receipt验证方式:
NSError *error;NSDictionary *requestContents = @{@"receipt-data": [receipt base64EncodedString]};NSData *requestData = [NSJSONSerialization dataWithJSONObject:requestContentsoptions:0error:&error];if (!requestData) { return;}// Create a POST request with the receipt data.NSURL *storeURL = [NSURL URLWithString:@"https://sandbox.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:queuecompletionHandler:^(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 ... */ }}];
老版本返回格式:
{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_coins99M_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" = "ASDGF2DB-DSAD-5A21-9611-642A4B9CASDE7";};status = 0;}
新版本返回格式官方文档:官方文档
新版本返回格式:
{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_coins99M_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;}...... 可能存在多条);"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;}
值得注意的是,新版中数据结构中的in_app字段,可能包含多个transaction的receipt。当完成transaction后,还没有成功调用读取过receipt的接口,那下一次读取recept时会把所有的都读取出来,从而出现多条数据。
一般开发商app支付都有自己的支付系统,可能每次下单之前都会创建自己的订单号,需要与ios支付后返回的receipt一一对应,这种情况下如何处理还需要注意。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持VEVB武林网。
新闻热点
疑难解答