这次遇到的问题主要有两点
1.税收那一块没有填好一些东西,这样会导致 在代码里面调用SDK 没有办法返回 预先创建好的商品类。
2.进行付款时候 将记录进行本地存储。服务端也做这样的处理。 (毕竟这个是涉及到钱,谨慎一点好)
假设 我选择的product_id : com.mytest.xixi
这个id 是在 itunesconnect 设置好
首先要 假如通知,通知是一对的
-(void)dealloc
{
//解除监听的通知
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
//假如监听的通知
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
//假如这里是选择了product_id = @"com.mytest.xixi";
selectProductID = @"com.mytest.xixi";
[self doIAPAction:selectProductID];
}
首先要判断是否能够可以使用IAP, 发起请求向苹果询问是否有哪些商品可售
- (void)doIAPAction:(NSString *)selectArg
{
if([SKPaymentQueue canMakePayments])
{
[self requestProductData:selectArg];
}
else
{
NSLog(@"不允许程序内付费");
}
}
//请求商品
- (void)requestProductData:(NSString *)selectArg
{
NSLog(@"-------------请求对应的产品信息----------------");
NSArray *product = [[NSArray alloc] initWithObjects:selectArg,
nil];
NSSet *nsset = [NSSet setWithArray:product];
self.request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];
self.request.delegate = self;
[self.request start];
}
有网络请求 那么肯定会有成功或者失败,下面这几个都是代理里面可以找到
//收到产品返回信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSLog(@"--------------收到产品反馈消息---------------------");
NSArray *product = response.products;
if([product count] == 0)
{
NSLog(@"--------------没有商品------------------");
return;
}
NSLog(@"productID:%@", response.invalidProductIdentifiers);
NSLog(@"产品付费数量:%ld",(long)[product count]);
SKProduct *p = nil;
for (SKProduct *pro in product)
{
NSLog(@"%@", [pro description]);
NSLog(@"%@", [pro localizedTitle]);
NSLog(@"%@", [pro localizedDescription]);
NSLog(@"%@", [pro price]);
NSLog(@"%@", [pro productIdentifier]);
if([pro.productIdentifier isEqualToString:selectProductID])
{
p = pro;
}
}
SKPayment *payment = [SKPayment paymentWithProduct:p];
NSLog(@"发送购买请求");
[[SKPaymentQueue defaultQueue] addPayment:payment];
}
//请求失败
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error
{
NSLog(@"------------------错误-----------------:%@", error);
}
- (void)requestDidFinish:(SKRequest *)request
{
NSLog(@"------------反馈信息结束-----------------");
}
//监听购买结果
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transaction
{
for(SKPaymentTransaction *tran in transaction)
{
switch (tran.transactionState)
{
case SKPaymentTransactionStatePurchased:
NSLog(@"交易完成");
[self completeTransaction:tran];
break;
case SKPaymentTransactionStatePurchasing:
NSLog(@"商品添加进列表");
break;
case SKPaymentTransactionStateRestored:
NSLog(@"已经购买过商品");
break;
case SKPaymentTransactionStateFailed:
NSLog(@"交易失败");
NSLog(@"%@",tran);
[self failedTransaction:tran];
break;
default:
break;
}
}
}
//交易结束
- (void)completeTransaction:(SKPaymentTransaction *)transaction
{
NSLog(@"交易结束");
// Your application should implement these two methods.
NSString * productIdentifier = transaction.payment.productIdentifier;
if ([productIdentifier length] > 0)
{
// 向自己的服务器验证购买凭证
[self verifyPruchase:transaction];
}
// Remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
- (void)failedTransaction:(SKPaymentTransaction *)transaction
{
HIDE_PROGRESS(self.view);
if(transaction.error.code != SKErrorPaymentCancelled)
{
NSLog(@"购买失败");
}
else
{
NSLog(@"用户取消交易");
}
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
}
#pragma mark 验证购买凭据
- (void)verifyPruchase:(SKPaymentTransaction *)transaction
{
// 验证凭据,获取到苹果返回的交易凭据
// appStoreReceiptURL iOS7.0增加的,购买交易完成后,会将凭据存放在该地址
NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];
// 从沙盒中获取到购买凭据
NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];
NSString *encodeStr = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSString *transId = transaction.transactionIdentifier;
NSString *productId = transaction.payment.productIdentifier;
if (!encodeStr)
{
return;
}
//下面开始描述处理的逻辑
/*
* 1.首先将这些数据(encodeStr,productId,transId,...)进行加密什么的 存储在本地数据库
* 2.然后将 这些数据 传到服务端 让服务端 跟apple 进行一次验证(也有人放在客户端代码里面进行验证),服务端接收到这些数据最好也是存储一下
* 3.服务端和apple验证成功之后返回告诉客户端通过之后,客户端这边就把本地数据库存储的相关数据给删掉,服务端也删。(两边都做处理保证一下,毕竟涉及到金钱)
* 4.这就完成一个正常的流程。(我自己个人认为)
*
* 3.1 也会出现这种情况 可能服务端和apple 验证的时候 时间太久了导致超时,那么在客户端要做点处理,可以选择在打开app的时候把数据库的存储的数据找出来重新进行一下验证,或者做一个定时器什么的 多久就扫一下数据库 是否有数据要重新验证。
*/
}