iOS-OC-内购In-App Purchases
2016-07-07 09:33
375 查看
![](http://upload-images.jianshu.io/upload_images/1121129-5d583a24f04239b9.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
公司项目要做会员功能,支付方式我采用的是内购In-App Purchases。说实话,我真的不想用苹果的内购功能,不说苹果要收百分之三十的手续费,就说它那么多的坑,我是真的不想往里面跳啊,但公司担心用支付宝、微信支付等方式苹果不让上架,做个开关的话又怕突然下架、甚至封掉开发者帐号。所以,这个坑我就只有跳了, 俗话说:我不入地狱,谁入地狱???!!!
话不多说,开始!
itunes connect里面的就不说了,我只说程序里面的代码部分。
首先要导入StoreKit.framework。引用 #import
{ BOOL startBuyAppleProduct; }
添加监听,这个最好写在- (void)viewDidLoad { }中。
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
当点某一个按钮的时候先去检测用户是否打开手机内购功能,如果打开了就执行requestProductData:方法请求商品数据,否则提示用户。ProductID是在itunes connect中设置的产品ID。
- (void)performPayFunctionOnIos { if([SKPaymentQueue canMakePayments]){ [self requestProductData:ProductID]; }else{ UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"提示" message:@"您的手机没有打开内购功能" preferredStyle:UIAlertControllerStyleAlert]; UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"确定" style:UIAlertActionStyleCancel handler:nil]; [alert addAction:cancel]; [self presentViewController:alert animated:YES completion:nil]; } }
添加产品ID,设置代理并发起请求。请求是从的苹果的服务器请求产品的数据.
- (void)requestProductData:(NSString*)productString{ startBuyAppleProduct = YES; //这里把它设为YES,表明是你发起的请求。 NSArray*product = [[NSArray alloc] initWithObjects:productString,nil]; NSSet*nsset = [NSSet setWithArray:product]; SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset]; request.delegate=self; [request start]; }
添加代理方法
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response { NSArray*product = response.products; if([product count] ==0){ NSLog(@"没有商品"); return; } SKProduct *p = nil; for (SKProduct *pro in product) { if ([pro.productIdentifier isEqualToString:ProductID]) { p = pro; } } SKPayment *payment = [SKPayment paymentWithProduct:p]; [[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: // 这里要用最开始就定义的BOOL值startBuyAppleProduct来判断下是否是你本次发起的内购, 不是就跳过验证。 不知道为什么每次进这个控制器,它就会走这个监听方法,不在其它的case里判断是因为其它的并没有做什么逻辑处理。 if (startBuyAppleProduct) { [self verifyFinishedTransaction:tran]; } [self restoreTransaction:tran]; NSLog(@"交易完成"); break; case SKPaymentTransactionStatePurchasing: NSLog(@"商品添加进列表"); break; case SKPaymentTransactionStateRestored: NSLog(@"已经购买过商品"); [self restoreTransaction:tran]; break; case SKPaymentTransactionStateFailed: NSLog(@"交易失败"); [self restoreTransaction:tran]; break; default: NSLog(@"other"); [self restoreTransaction:tran]; break; } } }
- (void)restoreTransaction:(SKPaymentTransaction *)transaction { // 取消订单,或者说是恢复订单 [[SKPaymentQueue defaultQueue] finishTransaction: transaction]; // 每次都要把startBuyAppleProduct设置为NO,不然购买成功就不会验证 startBuyAppleProduct = NO; }
// 验证 - (void)verifyFinishedTransaction:(SKPaymentTransaction *)transaction { if (transaction.transactionState == SKPaymentTransactionStatePurchased) { NSString * productIdentifier = transaction.payment.productIdentifier; NSLog(@"%@",transaction.transactionIdentifier); NSString *receipt = [[NSData dataWithContentsOfURL:[[NSBundle mainBundle] appStoreReceiptURL] ] base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithCarriageReturn]; if ([productIdentifier length] > 0) { // 向自己的服务器验证购买凭证,用post的方式把receipt传给服务器就可以了。 } } }
因为苹果审核的时候是用的测试服务器, 但我们又不知道它的审核什么时间通过,所以最好先验证苹果的测试服务器,如果返回的是21007,再向正式的服务器发起验证。
测试服务器验证链接
https://sandbox.itunes.apple.com/verifyReceipt
正式服务器验证链接
https://buy.itunes.apple.com/verifyReceipt
验证返回的数据其中status为0,也就是”status”:0时就是验证成功了。这个要记住!记住!记住!并不是非零即真!这里零才是真!!!
7. 最后就是移除监听。
-(void)dealloc{ [[SKPaymentQueue defaultQueue] removeTransactionObserver:self]; }
看嘛,这就弄完了, 应该没有什么问题,我们就假如没有问题。������
希望能给各位一点帮助。
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 苹果与Siri的七年之痒:“宫斗”戏码不断上演
- 央视新闻报道XcodeGhost事件
- Ruby on Rails在Ping ++ 平台实现支付
- 原生JS仿苹果任务栏菜单,放大效果的菜单
- 微信小程序-详解微信登陆、微信支付、模板消息
- 微信公众号支付(一)如何获取用户openId
- 基于Java代码实现支付充值的通用流程
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用开发中AFNetworking库的常用HTTP操作方法小结
- iOS应用中UISearchDisplayController搜索效果的用法
- iOS App开发中的UISegmentedControl分段组件用法总结