<SKPaymentTransactionObserver,SKRequestDelegate,SKProductsRequestDelegate>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{    //添加一个交易队列观察者

[[SKPaymentQueue defaultQueue] addTransactionObserver:self];

}

- (void)paymentQueue:(SKPaymentQueue *)queue restoreCompletedTransactionsFailedWithError:(NSError *)error {

NSLog(@"%@",error);

}

/// Called when all restorable transactions have been processed by the payment queue.

- (void)paymentQueueRestoreCompletedTransactionsFinished:(SKPaymentQueue *)queue {

NSLog(@"%@",queue.transactions);

if (queue.transactions.count==0)

{

[YJProgressHUD showMessage:@"您还没购买过会员!"];

}

else

{

for (SKPaymentTransaction *transaction in queue.transactions)

{

NSLog(@"%@",transaction.originalTransaction.transactionIdentifier);//不会改变的订单号

}

通过这个订单号去向后台请求会员状态

}

}

//监听购买结果

- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray<SKPaymentTransaction *> *)transactions API_AVAILABLE(ios(3.0), macos(10.7), watchos(6.2))

{

for (SKPaymentTransaction *tran in transactions) {

[Singleton ShareDatabase].hgtran = tran;//一会儿需要删除的购买凭证

// 如果小票状态是购买完成

if (SKPaymentTransactionStatePurchased == tran.transactionState) {

// 订阅特殊处理

if (tran.originalTransaction) {

// 如果是自动续费的订单,originalTransaction会有内容

NSLog(@"自动续费的订单,originalTransaction = %@",tran.originalTransaction);

} else {

// 普通购买,以及第一次购买自动订阅

NSLog(@"普通购买,以及第一次购买自动订阅");

}

[[SKPaymentQueue defaultQueue] finishTransaction:tran];

[self verifyPruchase:tran isServerflag:NO];

} else if (SKPaymentTransactionStatePurchasing == tran.transactionState) {

NSLog(@"商品添加进列表");

} else if (SKPaymentTransactionStateRestored == tran.transactionState) {

NSLog(@"已经购买过商品");

[YJProgressHUD hideHUD];

[[SKPaymentQueue defaultQueue] finishTransaction:tran];

} else if (SKPaymentTransactionStateFailed == tran.transactionState) {

NSLog(@"交易失败");

[YJProgressHUD hideHUD];

[[SKPaymentQueue defaultQueue] finishTransaction:tran];

}

}

}

测试验证地址:https://sandbox.itunes.apple.com/verifyReceipt

//正式验证地址:https://buy.itunes.apple.com/verifyReceipt

- (void)verifyPruchase:(SKPaymentTransaction *)tran isServerflag:(BOOL)flag

{// 发送给苹果服务器/自己服务器认证:

NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];

// 从沙盒中获取到购买凭据

NSData *receiptData = [NSData dataWithContentsOfURL:receiptURL];

// 发送网络POST请求,对购买凭据进行验证

NSString *serverString = @"https://buy.itunes.apple.com/verifyReceipt";

if (flag) {

serverString = @"https://sandbox.itunes.apple.com/verifyReceipt";

}

NSURL *storeURL = [NSURL URLWithString:serverString];

NSMutableURLRequest *urlRequest =

[NSMutableURLRequest requestWithURL:storeURL cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:10.0f];

urlRequest.HTTPMethod = @"POST";

NSDictionary *requestContents = @{

@"receipt-data":[receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed],

@"password":@""//自己的内购配置

};

NSData *payloadData = [NSJSONSerialization dataWithJSONObject:requestContents

options:0

error:nil];

urlRequest.HTTPBody = payloadData;

// 提交验证请求,并获得官方的验证JSON结果 iOS9后更改了另外的一个方法

NSData *resultData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];

// 官方验证结果为空

if (resultData == nil) {

NSLog(@"验证失败");

return;

}

NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:resultData options:NSJSONReadingAllowFragments error:nil];

if (dict != nil) {

NSLog(@"%@",dict);

NSString *status = [NSString stringWithFormat:@"%@",dict[@"status"]];

if (status && [status isEqualToString:@"21007"]) {

[self verifyPruchase:[Singleton ShareDatabase].hgtran isServerflag:YES];

}

else if (status && [status isEqualToString:@"0"])

{

[Singleton ShareDatabase].TransactionID = StringFormat(@"%@",[[[dict valueForKey:@"latest_receipt_info"] objectAtIndex:0] valueForKey:@"original_transaction_id"]);

[Singleton ShareDatabase].tokenStr = [Singleton ShareDatabase].TransactionID;

[[NSUserDefaults standardUserDefaults]setValue:[Singleton ShareDatabase].tokenStr forKey:@"TokenStr"];

[[NSUserDefaults standardUserDefaults]synchronize];

[Singleton ShareDatabase].receipt = [receiptData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];

NSString *typeStr = @"";

if(flag == YES){

typeStr = @"0";//沙盒

}

else{

typeStr = @"1";//正式

}

去请求后台,改变会员状态,成功后记得销毁凭证

[[SKPaymentQueue defaultQueue] finishTransaction:[Singleton ShareDatabase].hgtran];

}

}

}

购买方法

NSString *PRODUCTID = @"";//自己内购配置

//判断是否可进行支付

if ([SKPaymentQueue canMakePayments]) {

[YJProgressHUD showLoading:@"加载中..."];

[self requestProductData:PRODUCTID];

} else {

NSLog(@"不允许程序内付费");

}

- (void)requestProductData:(NSString *)type {

//根据商品ID查找商品信息

NSArray *product = [[NSArray alloc] initWithObjects:type, nil];

NSSet *nsset = [NSSet setWithArray:product];

//创建SKProductsRequest对象,用想要出售的商品的标识来初始化, 然后附加上对应的委托对象。

//该请求的响应包含了可用商品的本地化信息。

SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];

request.delegate = self;

[request start];

}

- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response API_AVAILABLE(ios(3.0), macos(10.7), watchos(6.2))

{

//接收商品信息

NSArray *product = response.products;

if ([product count] == 0) {

NSLog(@"--------------没有商品------------------");

return;

}

NSLog(@"productID:%@", response.invalidProductIdentifiers);

NSLog(@"产品付费数量:%lu",(unsigned long)[product count]);

// SKProduct对象包含了在App Store上注册的商品的本地化信息。

SKProduct *storeProduct = nil;

for (SKProduct *pro in product) {

NSLog(@"%@", [pro description]);

NSLog(@"%@", [pro localizedTitle]);

NSLog(@"%@", [pro localizedDescription]);

NSLog(@"%@", [pro price]);

NSLog(@"%@", [pro productIdentifier]);

storeProduct = pro;

}

SKPayment *payment = [SKPayment paymentWithProduct:storeProduct];

//发送内购请求

[[SKPaymentQueue defaultQueue] addPayment:payment];

}

- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {

NSLog(@"------------------购买失败-----------------:%@", error);

}

- (void)requestDidFinish:(SKRequest *)request {

NSLog(@"------------购买完成-----------------");

}

恢复购买方法

[[SKPaymentQueue defaultQueue] restoreCompletedTransactions];

IOS 自动订阅以及恢复购买相关推荐

  1. iOS自动订阅商品(Auto-Renewable Subscriptions)相关处理

    来源:http://blog.csdn.net/xyxjn/article/details/17412453 由于网上有关自动订阅的信息较少,自己姑且整理一下目前接触到的信息,希望能够对一些朋友有所帮 ...

  2. ios自动订阅服务器,任何(早期)iOS自动续订订阅体验

    我让它在沙盒中运行,几乎上线了...... 应该使用服务器来验证收据 . 在服务器上,您可以使用收据数据记录设备udid,因为收据始终是新生成的,并且它可以在多个设备上运行,因为收据总是新生成的 . ...

  3. iOS 自动订阅开发

    一.代码逻辑 关于iOS 订阅.自动订阅 本身功能开发很简单.跟正常的购买没什么大的差异.唯一需要特殊处理(自动订阅)的是, 在APP启动时候要增加侦听: [[SKPaymentQueue defau ...

  4. ios自动订阅服务器,iOS IAP - 自动续期订阅

    自动续期订阅是苹果推出的一项苹果内购服务,当用户在App Store订阅了某项服务后,App Store会在订阅时间快到期之前,自动扣费并帮用户续订该服务. 自动续期订阅的优势 创建自动续期订阅 1. ...

  5. iOS 自动续期订阅 恢复购买

    恢复购买 内购有4种:消耗型项目,非消耗型,自动续期订阅,非续期订阅. 其中"非消耗型"和"自动续期订阅"需要提供恢复购买的功能,例如创建一个恢复按钮,不然审核 ...

  6. iOS In-App Purchase 内购之 什么是恢复购买记录

    Users restore transactions to maintain access to content they've already purchased. For example, whe ...

  7. IOS 内购IAP 自动订阅收据验证文档服务端翻译

    将收据数据发送到App Store: 提交此JSON对象作为HTTP POST请求的有效负载. 中文文档:https://help.apple.com/app-store-connect/#/dev7 ...

  8. iOS 自动续期订阅,订阅升级降级、订阅时间、退收费处理

    自动续期订阅群组设置概述 设置自动续期订阅与设置其他 App 内购买项目类型不同.每个自动续期订阅产品需创建为订阅群组的一部分并为其分配等级.您对订阅群组的设置将决 定顾客如何订阅您的内容或服务.如何 ...

  9. iOS内购测试自动订阅型产品

    最近产品需要涉及到订阅型的内购创建,上一次使用自动订阅内购还是好几年的事情了,很多内容大都忘得差不多了,加上苹果设计的内购又增加了一些新功能和改变,不得不重新来审视下自动订阅型内购,而官方又没有中文文 ...

最新文章

  1. centos格式化优盘命令_centos 磁盘分区、格式化及挂载
  2. micro850通讯协议msg_micro850通讯协议msg_半导体semi通讯的协议SECS/GEM
  3. jmeter中没有sampler_jmeter(七)-BeanShell常用内置变量和场景
  4. 【NGN学习笔记】5 IMS技术
  5. hiho一下 第六十四周 Right-click Context Menu
  6. 关于Mac下mysql8.0的启动
  7. iOS第三方开源库的吐槽和备忘
  8. php下载安装教程,PHP下载安装教程
  9. 【建议收藏】货币交易信息爬取+筛选(Python附源码)
  10. rtc校准算法_CRC校验算法的实例解析
  11. Adafruit GFX Library字体规范
  12. 王家林百万大数据人才之路
  13. Android系统开机画面修改
  14. 琼瑶称于正抄袭,心力交瘁已病倒
  15. Angular + PrimeNG 安装配置
  16. GStreamer开发介绍
  17. VMware虚拟机/Hyper-V在(校园网/PPPoe拨号上网)环境无法上网解决方案
  18. 如何在TIA 博途 WinCC中组态WinCC Runtime Advanced 和 S7 控制器的PROFINET通信连接?
  19. 测试种类大汇总(45类)
  20. SoftRendererRenderPipeline(从迷你光栅化软渲染器的实现看渲染流水线)

热门文章

  1. 你的收藏夹里,有哪些神奇有趣的小网站?
  2. python实现视频压缩
  3. 加州大学圣地亚哥计算机硕士申请,美国加州大学圣地亚哥分校计算机工程硕士.pdf...
  4. 数据仓库1-数仓的意义
  5. 3.css3深入,高级选择器浮动布局,html5/css3基础开始(推荐收藏)
  6. knex mysql 操作_手把手教你用express + mysql + knex 做个 todoList
  7. 关于电脑注册表regedit自定义管理右键菜单选项实例(删除增加)
  8. python的取整和取余_python中取整运算符
  9. 【2021 第五届“达观杯” 基于大规模预训练模型的风险事件标签识别】1 初赛Rank12的总结与分析
  10. 微信小程序:喝酒娱乐小游戏助力神器