iOS游戏IAP数据服务器验证
来源:互联网 发布:阿里云 vps 编辑:程序博客网 时间:2024/06/13 02:48
我上一篇博客《为iOS应用/游戏内建购买项目(IAP)》对于CP有自己游戏服务器的从安全性来讲并不适用,有自己服务器则需要进一步对数据进行校验。
如果CP具有自己的游戏服务器, Apple建议在服务器端存储产品ID,而不要将其存储在客户端本地。 这样就可以在不升级程序的前提下添加新的产品,这只需要我们向客户端发送哪个产品的ID。
如果要申请商品ID,可参考《为iOS应用/游戏内建购买项目(IAP)》
更多详细流程可参考这篇文章:《Store Kit Guide(In App Purchase)翻译》
IAP充值数据校验流程如图:
而以下代码就是要实现上图数据校验流程的:
//// ViewController.m////#import "ViewController.h"@interface ViewController ()@end@implementation ViewController#pragma mark 数据初始化- (void)viewDidLoad { [super viewDidLoad]; //1 [self setOnListner]; UIButton * btn = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [btn setFrame:CGRectMake(100, 300, self.view.bounds.size.width/2, 50)]; [btn setTitle:@"buy" forState:UIControlStateNormal]; btn.backgroundColor = [UIColor purpleColor]; [btn addTarget:self action:@selector(click) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:btn];}//1,对交易进行监听和设置可购买-(void)setOnListner{ [[SKPaymentQueue defaultQueue] addTransactionObserver:self]; NSString * des; if([SKPaymentQueue canMakePayments]){ des = @"可购买内置项目!"; }else{ des = @"不可购买内置项目!"; } NSLog(@"%@",des);}-(void)click{ [self reqBuyData];}//2,请求商品信息-(void)reqBuyData{ // 所注册的商品ID数组 NSArray * arr = [[NSArray alloc] initWithObjects:@"com.xx.gold100",@"com.xx.gold200", nil]; NSSet *set = [NSSet setWithArray:arr]; SKProductsRequest * req = [[SKProductsRequest alloc] initWithProductIdentifiers:set]; req.delegate = self; [req start];}#pragma mark SKProductsRequestDelegate代理实现//3, 得到商品信息,并自动购买第一个-(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{ NSArray * myProducts = response.products; //如果是无效的商品将会出现在这里,如AppleID账号没完善银行信息之类也会导致 NSArray * dArr = response.invalidProductIdentifiers; NSLog(@"接受到产品返回信息%lu", (unsigned long)myProducts.count); NSLog(@"接受到无效的产品返回信息%lu", (unsigned long)dArr.count); if(myProducts.count < 1){ NSLog(@"无有效商品信息!"); return; } SKProduct * buyProduct; for (SKProduct * product in myProducts) { NSLog(@"---pay : %@", product.localizedDescription); NSLog(@"product title:%@", product.localizedTitle); NSLog(@"price:%@", product.price); buyProduct = product; } //这里我直接对最后一个商品进行下单购买, // 游戏中应该把商品列表列出来给玩家选择,然后把要买的add到[SKPaymentQueue defaultQueue],到add这里开始发送购买请求 SKPayment * pay = [SKPayment paymentWithProduct:buyProduct]; [[SKPaymentQueue defaultQueue] addPayment:pay];}//SKProductsRequestDelegate代理实现,请求商品有错log-(void)request:(SKRequest *)request didFailWithError:(NSError *)error{ NSLog(@"---------error log----%@", error.localizedDescription);}//SKProductsRequestDelegate代理实现-(void)requestDidFinish:(SKRequest *)request{ NSLog(@"信息请求结束");}#pragma mark SKPaymentTransactionObserver代理实现//4,SKPaymentTransactionObserver代理实现,也就是购买的结果-(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions{ NSString * des = @""; for(SKPaymentTransaction * trans in transactions){ switch (trans.transactionState) { case SKPaymentTransactionStatePurchased: des = @"客户端本地购买完成!将向服务器验证数据!"; //购买成功,那么将要向cp游戏服务器发送订单,cp游戏服务器再去通过iap服务器验证数据,再返回结果到客户端 //5, [self completeTransaction:trans]; //pop出用过的交易 [[SKPaymentQueue defaultQueue] finishTransaction:trans]; break; case SKPaymentTransactionStateFailed: des = @"购买失败!"; [self failedTransaction:trans]; //pop出用过的交易 [[SKPaymentQueue defaultQueue] finishTransaction:trans]; break; case SKPaymentTransactionStateRestored: des = @"购买重复!"; //pop出用过的交易 [[SKPaymentQueue defaultQueue] finishTransaction:trans]; break; case SKPaymentTransactionStatePurchasing: //des = @"购买ing!"; break; default: break; } UIAlertView * a = [[UIAlertView alloc] initWithTitle:@"result" message:des delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil]; if (![des isEqual: @""]) { [a show]; } }}#pragma mark 自定义的函数,由本地购买成功后验证数据和打印信息用//5,购买成功后调用,-(void)completeTransaction:(SKPaymentTransaction*) transaction{ //模拟向游戏服务器验证数据 [self verifyTransaction:transaction];}//6,//假设以下函数是游戏服务器的//这里应该交给游戏服务器去验证,然后把结果返回客户端,直接现在这里模拟游戏服务器吧-(void)verifyTransaction:(SKPaymentTransaction*) transaction{ //沙盒测试用url NSString * urlStr = @"https://sandbox.itunes.apple.com/verifyReceipt"; NSURL * url = [NSURL URLWithString:urlStr]; NSMutableURLRequest * req = [NSMutableURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:5000]; req.HTTPMethod = @"POST"; //要求Base64编码 NSString * transactionReceipt = [transaction.transactionReceipt base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]; NSString * jsonStr = [NSString stringWithFormat:@"{\"receipt-data\":\"%@\"}", transactionReceipt]; NSData * jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES]; [req setHTTPBody:jsonData]; NSData * result = [NSURLConnection sendSynchronousRequest:req returningResponse:nil error:nil]; //这个验证函数里应该是服务器的,得到下面结果后返回给本客户端就OK啦 if (result == nil) { NSLog(@"验证到有误数据"); }else{ NSDictionary * dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingAllowFragments error:nil]; /*应该返回的json receipt = { ....... }; status = 0; */ //status == 0 才算成功 if (dic!= nil && [dic[@"status"] == 0]) { NSLog(@"数据验证成功!购买成功!"); NSLog(@"返回数据:"); NSLog(@"%@",dic); }else{ NSLog(@"验证到有误数据"); if (dic != nil) { NSLog(@"%@", dic); } } }}//给交易失败后调用-(void)failedTransaction:(SKPaymentTransaction*)transaction{ NSString * errorDes; NSInteger errorCode = transaction.error.code; NSLog(@"payment error ; %@", transaction.error.localizedDescription); switch (errorCode) { case SKErrorUnknown: errorDes = @"unknown"; break; case SKErrorPaymentCancelled: errorDes = @"payment cancel"; break; case SKErrorPaymentInvalid: errorDes = @"payment invalid"; break; case SKErrorPaymentNotAllowed: errorDes = @"not allowed"; break; case SKErrorClientInvalid: errorDes = @"client invalid"; break; default: break; } UIAlertView * alert = [[UIAlertView alloc] initWithTitle:@"title" message:errorDes delegate:self cancelButtonTitle:@"ok" otherButtonTitles:nil, nil]; [alert show];}@end
运行就可以得到结果了:
查看打印数据:
0 0
- iOS游戏IAP数据服务器验证
- java服务器IAP验证
- iOS IAP 服务器二次验证突然断网了怎么办
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!!
- iap支付服务器验证python版本
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!拒绝iap Free!让iphone越狱用户无从下手!
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!!让iphone越狱用户无从下手!!!
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!!让iphone越狱用户无从下手!!!
- 【iOS-iap防护】验证用户付费收据!拒绝iap Cracker!!让iphone越狱用户无从下手!!!
- iOS 游戏安全之 IAP 破解原理与防御
- iOS游戏如何防御外挂及IAP破解
- iOS游戏如何防御外挂及IAP破解
- iOS游戏如何防御外挂及IAP破解
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- Cocos2d-x使用iOS游戏内付费IAP(C++篇)
- Linux 下 C 语言实现 Copy 复制命令
- hdu3944 DP? (lucas定理+预处理)
- 较简单的正则匹配引擎实现
- 自定义View
- HDU 1394 Minimum Inversion Number (BIT入门)
- iOS游戏IAP数据服务器验证
- Mac上的安卓相关工具
- 【暑假专题训练#数据结构】
- java-为什么配置环境变量
- 出现“adb不是内部或外部命令的解决办法
- poj3177Redundant Paths tarjan缩点
- poj 2528 Mayor's posters(线段树 离散化 区间更新 贴海报)
- C++拷贝构造函数(二)
- jquery判断checkbox是否选中及改变checkbox状态