IOS 自动订阅以及恢复购买
<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 自动订阅以及恢复购买相关推荐
- iOS自动订阅商品(Auto-Renewable Subscriptions)相关处理
来源:http://blog.csdn.net/xyxjn/article/details/17412453 由于网上有关自动订阅的信息较少,自己姑且整理一下目前接触到的信息,希望能够对一些朋友有所帮 ...
- ios自动订阅服务器,任何(早期)iOS自动续订订阅体验
我让它在沙盒中运行,几乎上线了...... 应该使用服务器来验证收据 . 在服务器上,您可以使用收据数据记录设备udid,因为收据始终是新生成的,并且它可以在多个设备上运行,因为收据总是新生成的 . ...
- iOS 自动订阅开发
一.代码逻辑 关于iOS 订阅.自动订阅 本身功能开发很简单.跟正常的购买没什么大的差异.唯一需要特殊处理(自动订阅)的是, 在APP启动时候要增加侦听: [[SKPaymentQueue defau ...
- ios自动订阅服务器,iOS IAP - 自动续期订阅
自动续期订阅是苹果推出的一项苹果内购服务,当用户在App Store订阅了某项服务后,App Store会在订阅时间快到期之前,自动扣费并帮用户续订该服务. 自动续期订阅的优势 创建自动续期订阅 1. ...
- iOS 自动续期订阅 恢复购买
恢复购买 内购有4种:消耗型项目,非消耗型,自动续期订阅,非续期订阅. 其中"非消耗型"和"自动续期订阅"需要提供恢复购买的功能,例如创建一个恢复按钮,不然审核 ...
- iOS In-App Purchase 内购之 什么是恢复购买记录
Users restore transactions to maintain access to content they've already purchased. For example, whe ...
- IOS 内购IAP 自动订阅收据验证文档服务端翻译
将收据数据发送到App Store: 提交此JSON对象作为HTTP POST请求的有效负载. 中文文档:https://help.apple.com/app-store-connect/#/dev7 ...
- iOS 自动续期订阅,订阅升级降级、订阅时间、退收费处理
自动续期订阅群组设置概述 设置自动续期订阅与设置其他 App 内购买项目类型不同.每个自动续期订阅产品需创建为订阅群组的一部分并为其分配等级.您对订阅群组的设置将决 定顾客如何订阅您的内容或服务.如何 ...
- iOS内购测试自动订阅型产品
最近产品需要涉及到订阅型的内购创建,上一次使用自动订阅内购还是好几年的事情了,很多内容大都忘得差不多了,加上苹果设计的内购又增加了一些新功能和改变,不得不重新来审视下自动订阅型内购,而官方又没有中文文 ...
最新文章
- centos格式化优盘命令_centos 磁盘分区、格式化及挂载
- micro850通讯协议msg_micro850通讯协议msg_半导体semi通讯的协议SECS/GEM
- jmeter中没有sampler_jmeter(七)-BeanShell常用内置变量和场景
- 【NGN学习笔记】5 IMS技术
- hiho一下 第六十四周	Right-click Context Menu
- 关于Mac下mysql8.0的启动
- iOS第三方开源库的吐槽和备忘
- php下载安装教程,PHP下载安装教程
- 【建议收藏】货币交易信息爬取+筛选(Python附源码)
- rtc校准算法_CRC校验算法的实例解析
- Adafruit GFX Library字体规范
- 王家林百万大数据人才之路
- Android系统开机画面修改
- 琼瑶称于正抄袭,心力交瘁已病倒
- Angular + PrimeNG 安装配置
- GStreamer开发介绍
- VMware虚拟机/Hyper-V在(校园网/PPPoe拨号上网)环境无法上网解决方案
- 如何在TIA 博途 WinCC中组态WinCC Runtime Advanced 和 S7 控制器的PROFINET通信连接?
- 测试种类大汇总(45类)
- SoftRendererRenderPipeline(从迷你光栅化软渲染器的实现看渲染流水线)
热门文章
- 你的收藏夹里,有哪些神奇有趣的小网站?
- python实现视频压缩
- 加州大学圣地亚哥计算机硕士申请,美国加州大学圣地亚哥分校计算机工程硕士.pdf...
- 数据仓库1-数仓的意义
- 3.css3深入,高级选择器浮动布局,html5/css3基础开始(推荐收藏)
- knex mysql 操作_手把手教你用express + mysql + knex 做个 todoList
- 关于电脑注册表regedit自定义管理右键菜单选项实例(删除增加)
- python的取整和取余_python中取整运算符
- 【2021 第五届“达观杯” 基于大规模预训练模型的风险事件标签识别】1 初赛Rank12的总结与分析
- 微信小程序:喝酒娱乐小游戏助力神器