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
//最后这里的代码涉及到观察者模式的使用,不懂的可以百度一下