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一一对应,这种情况下如何处理还需要注意。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。