IOS应用内支付返回新旧Receipt适配的方法
ios7.0后ios支付成功返回的票据Receipt的获取方式有了新的方式,
原来的SKPaymentTransaction中的transactionReceipt属性获取票据的方式已经过期,虽然还能使用,但是苹果官方建议使用新的
新版的获取Receipt的方式是通过新接口如下
NSURL*receiptURL=[[NSBundlemainBundle]appStoreReceiptURL]; NSData*receipt=[NSDatadataWithContentsOfURL:receiptURL];
当然,低于ios7.0的还是需要使用老版本接口,对两种版本进行适配的代码如下:
NSData*receipt=nil; if(SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){ //iosafter7.0 NSURL*receiptURL=[[NSBundlemainBundle]appStoreReceiptURL]; receipt=[NSDatadataWithContentsOfURL:receiptURL]; NSString*receiptURLStr=[receiptURLabsoluteString]; NSRangerangeSandbox=[receiptURLStrrangeOfString:@"sandbox"]; if(rangeSandbox.location!=NSNotFound){ record[kIAPEnvironment]=[NSNumbernumberWithInt:1]; } }else{ //ios3.0~7.0 receipt=transaction.transactionReceipt; NSDictionary*dict=[NSDictionarydictionaryWithContentsOfData:receipt]; if(dict){ NSString*env=[dictobjectForKey:@"environment"]; if([envisEqualToString:@"Sandbox"]){ record[kIAPEnvironment]=[NSNumbernumberWithInt:1]; } } }
判断是否是沙盒支付,新版本可以直接判断receiptURL中是否存在“sandbox“
老版本receipt可以解析NSData查看environment是否为Sandbox来判断
+(NSDictionary*)dictionaryWithContentsOfData:(NSData*)data{ CFPropertyListRefplist=CFPropertyListCreateFromXMLData(kCFAllocatorDefault,(__bridgeCFDataRef)data, kCFPropertyListImmutable,NULL); if(plist==nil)returnnil; if([(__bridgeid)plistisKindOfClass:[NSDictionaryclass]]){ return(__bridgeNSDictionary*)plist; }else{ CFRelease(plist); returnnil; } }
客户端receipt验证方式:
NSError*error; NSDictionary*requestContents=@{ @"receipt-data":[receiptbase64EncodedString] }; NSData*requestData=[NSJSONSerializationdataWithJSONObject:requestContents options:0 error:&error]; if(!requestData){ return; } //CreateaPOSTrequestwiththereceiptdata. NSURL*storeURL=[NSURLURLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];//根据是否是沙盒支付验证取正确的地址 NSMutableURLRequest*storeRequest=[NSMutableURLRequestrequestWithURL:storeURL]; [storeRequestsetHTTPMethod:@"POST"]; [storeRequestsetHTTPBody:requestData]; //MakeaconnectiontotheiTunesStoreonabackgroundqueue. NSOperationQueue*queue=[[NSOperationQueuealloc]init]; [NSURLConnectionsendAsynchronousRequest:storeRequestqueue:queue completionHandler:^(NSURLResponse*response,NSData*data,NSError*connectionError){ if(connectionError){ /*...Handleerror...*/ }else{ NSError*error; NSDictionary*jsonResponse=[NSJSONSerializationJSONObjectWithData:dataoptions:0error:&error]; if(!jsonResponse){/*...Handleerror...*/} /*...Sendaresponsebacktothedevice...*/ } }];
老版本返回格式:
{ bid="com.coodezhang.test"; bvrs="1.0"; "item_id"=892617314; "original_purchase_date"="2017-12-1407:43:14Etc/GMT"; "original_purchase_date_ms"=1626147394550; "original_purchase_date_pst"="2017-12-1412:43:14America/Los_Angeles"; "original_transaction_id"=1000001127239959; "product_id"="com.coodezhang.test_coins99M_Tier1"; "purchase_date"="2017-12-1407:43:14Etc/GMT"; "purchase_date_ms"=1626147394550; "purchase_date_pst"="2017-12-1412:43:14America/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-1407:18:56Etc/GMT"; "original_purchase_date_ms"=1513235936000; "original_purchase_date_pst"="2017-12-1323:18:56America/Los_Angeles"; "original_transaction_id"=1000000359369424; "product_id"="com.coodezhang.test_coins99M_Tier1"; "purchase_date"="2017-12-1407:18:56Etc/GMT"; "purchase_date_ms"=1513235936000; "purchase_date_pst"="2017-12-1323:18:56America/Los_Angeles"; quantity=1; "transaction_id"=1000000359369424; } ......可能存在多条 ); "original_application_version"="1.0"; "original_purchase_date"="2013-08-0107:00:00Etc/GMT"; "original_purchase_date_ms"=1375340400000; "original_purchase_date_pst"="2013-08-0100:00:00America/Los_Angeles"; "receipt_creation_date"="2017-12-1407:18:56Etc/GMT"; "receipt_creation_date_ms"=1513235936000; "receipt_creation_date_pst"="2017-12-1323:18:56America/Los_Angeles"; "receipt_type"=ProductionSandbox; "request_date"="2017-12-1407:19:23Etc/GMT"; "request_date_ms"=1513235963829; "request_date_pst"="2017-12-1323:19:23America/Los_Angeles"; "version_external_identifier"=0; }; status=0; }
值得注意的是,新版中数据结构中的in_app字段,可能包含多个transaction的receipt。当完成transaction后,还没有成功调用读取过receipt的接口,那下一次读取recept时会把所有的都读取出来,从而出现多条数据。
一般开发商app支付都有自己的支付系统,可能每次下单之前都会创建自己的订单号,需要与ios支付后返回的receipt一一对应,这种情况下如何处理还需要注意。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。