In App Purchase(Store Kit)详细说明(中文)----(Object-C)
大家去百度一下,下载这个文档来看看,这个就是苹果游戏内置付费接入SDK文档CSDN上面貌似也有的下载,我的就是百度来的,由于这个上文档什么的比较麻烦,就不啰嗦了。
1.下载In App Purchase(Store Kit)详细说明(中文),细读一遍
2.在上代码之前可以先了解下原理,有几篇文章比较好的
cocos2d-x + lua接入ios原生SDK实现方案:
http://www.cnblogs.com/flyFreeZn/p/4152881.html
教你快速高效的接入SDK---总体思路与架构:
(这篇是安卓的第三方SDK,我们用来了解原理,很有帮助,想了解安卓的也是很好的)
http://blog.csdn.net/chenjie19891104/article/details/42217281
Himi接入的例子:我参考了一些这篇,很不错!也详细讲解了IAP/StoreKit付费,沙盒(sandBox)测试,等
http://blog.csdn.net/xiaominghimi/article/details/6937097/
Himi的gamecenter接入的,(这篇有兴趣的可以看看),我们主要讨论store kit的。
3.我们来上代码吧!
我写了几个test(ThepayTest.h/ThepayTest.m)/(MyStoreObserver.h/MyStoreObserver.m)
// ThepayTest.h // HeroWar.gun // // Created by huale_mac on 15-4-1. // // #import <UIKit/UIKit.h> #import <StoreKit/StoreKit.h> #import "MyStoreObserver.h" //enum { // PID_100 , // PID_1980 , // PID_300 , // PID_60 , // PID_6480 , // PID_980 , // PID_3280 // //}buyCoinsTag; //枚举 //@class MyStoreObserver; static SKPayment * thePayment; @interface ThepayTest : UIViewController<SKPaymentTransactionObserver,SKProductsRequestDelegate> { int buyType; int _nfornum; } -(void)buy:(int)type goldnum:(int)nfornum; //判断支付是否开启 ,,,,,,??需要完善 -(bool)CanMakePay; -(void)requestProductData; //这里发送请求,获得商品的信息 -(void)productsRequest:(SKProductsRequest*)request //这个是响应delegate方法 didReceiveResponse:(SKProductsResponse *)response; //添加一个展示商品的界面 -(void)_viewGameStoreUi; //为支付队列注册一个观察者对象 ????应该在程序启动的时候就添加好观察者 -(void)_addObserverForStore; @end
// // ThepayTest.m // HeroWar // // Created by huale_mac on 15-4-1. // // #import "ThepayTest.h" #define productID_month_card @"xxx_m_card" //这里是在appstore上面注册的内购商品的id #define ProductID_60 @"xxx_new_60" #define ProductID_300 @"xxx_300" #define ProductID_980 @"xxx_new_980" #define ProductID_1980 @"xxx_1980" #define ProductID_3280 @"xxx_3280" #define ProductID_6480 @"xxx_6480" @implementation ThepayTest //为支付队列注册一个观察者对象 -------->MyStoreObserver.h里定义的类 -(void)_addObserverForStore { MyStoreObserver *observer = [[MyStoreObserver alloc]init]; [[SKPaymentQueue defaultQueue]addTransactionObserver:observer]; //监听购买结果 } //判断支付是否开启 ,,,,,,??需要完善 -(void)buy:(int)type goldnum:(int)nfornum { _nfornum = nfornum; buyType = type; NSLog(@"Link... gold is %d",type); if([SKPaymentQueue canMakePayments]) { //Display a sotre to the user...调出商店购买页面给用户 --需添加 [self requestProductData]; NSLog(@"允许程序内付费购买"); } else { //Warn the user that purchases are disabled. NSLog(@"支付未开启"); UIAlertView *alerView = [[UIAlertView alloc] initWithTitle:@"Alert" message:@"you can't purchase in app store" delegate:nil cancelButtonTitle:NSLocalizedString(@"Close", nil) otherButtonTitles: nil]; [alerView show]; [alerView release]; } } // -(bool)CanMakePay { return [SKPaymentQueue canMakePayments]; } //这里发送请求,获得商品的信息 -(void)requestProductData { // MyStoreObserver * Mytest = [[MyStoreObserver alloc]init]; NSLog(@"------请求对应的产品信息-------"); NSArray * product = nil; NSLog(@"--type--%d---- ",buyType ); switch (buyType) { case 6: product = [[NSArray alloc] initWithObjects:ProductID_60, nil]; break; case 30: if (_nfornum == 2) { product = [[NSArray alloc] initWithObjects:ProductID_300, nil]; break; }else if(_nfornum == 7){ product = [[NSArray alloc] initWithObjects:productID_month_card, nil]; break; } case 98: product = [[NSArray alloc] initWithObjects:ProductID_980, nil]; break; case 198: product = [[NSArray alloc] initWithObjects:ProductID_1980, nil]; break; case 328: product = [[NSArray alloc] initWithObjects:ProductID_3280, nil]; break; case 648: product = [[NSArray alloc] initWithObjects:ProductID_6480, nil]; break; // case 30: // product = [[NSArray alloc] initWithObjects:productID_month_card, nil]; // break; default: break; } //Apple ID:必填,此处为测试 1980游戏币 NSSet *nsset = [NSSet setWithArray : product]; SKProductsRequest *request = [[SKProductsRequest alloc]initWithProductIdentifiers:[NSSet setWithObject:nsset]]; setWithObjects:954212876] request.delegate = self; [request start]; [product release]; } //<SKProductsRequestDelegate>请求协议 //这个是响应delegate方法 -(void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSLog(@"----------收到产品反馈信息-----------"); NSArray *myProduct = response.products; NSLog(@"产品product ID:%@",response.invalidProductIdentifiers); NSLog(@"产品付费数量: %d", [myProduct count]); //生成商店的UI for (SKProduct *product in myProduct) { NSLog(@"product info"); NSLog(@"SKProduct 描述信息 %@",[product description]); NSLog(@"产品标题%@", product.localizedTitle); NSLog(@"产品描述信息:%@",product.localizedDescription); NSLog(@"价格:%@",product.price); NSLog(@"Product id:%@",product.productIdentifier); } //// //PID_100 , //PID_1980 , //PID_300 , //PID_60 , //PID_6480 , //PID_980 , //PID_3280 SKPayment *payment = nil; // SKMutablePayment * payment = nil; switch (buyType) { // case 10: // payment = [SKMutablePayment paymentWithProductIdentifier:ProductID_100]; // payment.quantity = 3; // break; //这里的SKMutablePayment用来可设置商品购买数量为3,就是一次购买3个,注释掉了,公司要求一次购买一个就够了 case 6: payment = [SKPayment paymentWithProductIdentifier:ProductID_60]; //支付$ break; case 30: if(_nfornum == 2) {//这是一个判断,因为传过来有两个相同30元价格的商品需要区分 payment = [SKPayment paymentWithProductIdentifier:ProductID_300]; //支付$ break; }else if(_nfornum == 7){ payment = [SKPayment paymentWithProductIdentifier:productID_month_card]; //支付$ break; } //如果没有需要同价格区分的完全可以去掉上面的代码,按下面的来就行 case 98: payment = [SKPayment paymentWithProductIdentifier:ProductID_980]; //支付$ break; case 198: payment = [SKPayment paymentWithProductIdentifier:ProductID_1980]; //支付$ break; case 328: payment = [SKPayment paymentWithProductIdentifier:ProductID_3280]; //支付$ break; case 648: payment = [SKPayment paymentWithProductIdentifier:ProductID_6480]; //支付$ break; default: break; } thePayment = payment; NSLog(@"--------发送购买请求----------"); [[SKPaymentQueue defaultQueue] addPayment:payment]; [request autorelease]; } //添加一个展示商品的界面 -(void)_viewGameStoreUi { //Show the gamestore UI ... } @end //这些代码都是可以完整复用的,稍微修改一下就行
// // MyStoreObserver.h // HeroWar.gun // // Created by huale_mac on 15-4-2. // // #import <UIKit/UIKit.h> #import "ThepayTest.h" @interface MyStoreObserver : UIViewController<SKPaymentTransactionObserver> // Sent when the transaction array has changed (additions or state changes). Client should check state of transactions and finish as appropriate. +(MyStoreObserver *) instance; -(void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions; -(void)completeTransaction:(SKPaymentTransaction *)transaction; -(void)restoreTransaction:(SKPaymentTransaction *)transaction; -(void)failedTransaction:(SKPaymentTransaction *)transacction; -(void)recordTransaction:(SKPaymentTransaction*)transaction; -(void)provideContent:(NSString*)product; @end
// // MyStoreObserver.m // HeroWar // // Created by huale_mac on 15-4-2. // // #import "MyStoreObserver.h" //用来检测所有完成的购买,并发送购买的商品 @implementation MyStoreObserver { } //单例模式 static MyStoreObserver *instance; +(MyStoreObserver *) instance { if(!instance) instance = [[MyStoreObserver alloc] init]; return instance; } //新交易产生时创建,交易跟新时调用,函数针对不同的交易返回状态,调用对应的处理函数 - (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions: (NSArray *)transactions { // // if (!setTure) { // return ; // // }else{ // setTure = false; // } int i = 0; NSLog(@"here.."); for (SKPaymentTransaction *transaction in transactions) { NSLog(@"@---输出购买次数---%d",i++); switch (transaction.transactionState) { case SKPaymentTransactionStatePurchased: //交易完成 [self completeTransaction:transaction]; NSLog(@"----交易完成-----"); NSLog(@"不允许程序内付费购买"); break; case SKPaymentTransactionStateRestored: [self restoreTransaction:transaction]; //已经购买过改商品 break; default: break; case SKPaymentTransactionStateFailed: [self failedTransaction:transaction]; //交易失败 NSLog(@"----交易失败-----"); break; // UIAlertView *alerView2 = [[UIAlertView alloc]initWithTitle:@"Alert" // message:@"购买失败,请重新购买" delegate:nil cancelButtonTitle:NSLocalizedString(@"Close", nil) otherButtonTitles:nil]; // [alerView2 show]; // [alerView2 release]; // } } } //交易成功调用的方法 -(void)completeTransaction:(SKPaymentTransaction *)transaction { NSString *product = transaction.payment.productIdentifier; // 你的程序需要实现下面方法 [self recordTransaction:transaction]; [self provideContent:product]; //将完成后的交易信息移出列队 [[SKPaymentQueue defaultQueue]finishTransaction:transaction]; } //请求恢复购买 -(void)restoreTransaction:(SKPaymentTransaction *)transaction { NSString *product = transaction.payment.productIdentifier; // if ([product length] > 0) { // // [self recordTransaction:transaction]; // [self provideContent:product]; // // } [self recordTransaction:transaction]; [self provideContent:product]; [[SKPaymentQueue defaultQueue]finishTransaction:transaction]; } //交易失败 -(void)failedTransaction:(SKPaymentTransaction *)transacction { if (transacction.error.code != SKErrorPaymentCancelled) { ///在这里显示除用户取消之外的错误信息 NSLog(@"交易已取消,交易失败"); UIAlertView *alerView2 = [[UIAlertView alloc]initWithTitle:@"Alert" message:@"购买失败,请重新购买" delegate:nil cancelButtonTitle:NSLocalizedString(@"Close", nil) otherButtonTitles:nil]; [alerView2 show]; [alerView2 release]; } [[SKPaymentQueue defaultQueue] finishTransaction:transacction]; } //recordTransaction.....provideContent -(void)recordTransaction:(SKPaymentTransaction*)transaction { NSLog(@"-----记录交易-------"); } -(void)provideContent:(NSString *)product { NSLog(@"-----下载-----"); } @end //最后这里的代码涉及到观察者模式的使用,不懂的可以百度一下