iOS 应用内购买(In-App Purchase)之开发
iOS 应用内购买(In-App Purchase)之协议、税务和银行业务
使用IAP之前,需要签订协议,查看上面的链接。
IAP开发
添加App内购项目
登录 iTunes Connect ,选择我的app,点击要使用IAP的应用。
添加app内购买项目,这里有几种类型可选,根据你的产品选择需要的类型,比如Q币是消耗类型,QQ会员是非续订订阅等等。
虚拟货币/充值模式引入
之所以要引入虚拟货币或充值,有两个重要的原因:
1. 每一个商品都需要在 ITunes Connect 中创建一个对应的内购项目,而内购项目还需要提交审核,考虑到商品后期增删改,这是一个坑。
2. 苹果的内购项目的定价是固定的,参看这里,在列表中选择一个作为售价,这样就不一定契合我们实际商品定价,也不方便我们对商品改价促销之类。
引入充值或虚拟货币则可以解决这个问题
以虚拟货币(金币)为例,流程大致如下:
应用内购商品提供 100金币,200金币,500金币,1000金币4中类型的付费购买。
用户付费购买对应的商品(金币),用户账户里增加对应的金币数量,用户再使用金币购买应用内的实际商品(比如A课程,耗费288金币)
这样一来,ITunes Connect 中的内购项目只需要创建一次,而实际商品(课程)也可以按需增删改。
IPA购买流程
1. IOS客户端发起购买请求,购买指定产品ID对应的商品。
2. 支付成功/失败/取消后,苹果服务器返回支付结果,支付成功返回 receipt 。
3. IOS客户端获取到 receipt 后,提交到应用服务器(我们自己的服务器)验证。
4. 应用服务器将验证结果发给客户端。
IOS代码部分
// 这里产品id就是上面添加的内购项目产品id
static NSString *productID = @"100RMB";
</pre><p></p><pre code_snippet_id="1612284" snippet_file_name="blog_20160316_1_6013313" name="code" class="objc">#import <StoreKit/StoreKit.h>
@interface TestViewControler() <SKPaymentTransactionObserver, SKProductsRequestDelegate>
....- (void)viewDidLoad {// 添加购买监听[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
}- (void)didReceiveMemoryWarning {[super didReceiveMemoryWarning];
}- (void) dealloc {// 移除监听[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];
}....#pragma mark - 苹果 IAP 支付// 开始 IAP 流程
- (void) startIAPPay {// 检测是否允许内购if([SKPaymentQueue canMakePayments]){[self.navigationController.view makeToastActivity:CSToastPositionCenter];self.navigationController.view.userInteractionEnabled = NO;[btnBottom setTitle:NSLocalizedString(@"请稍等...", nil) forState:UIControlStateNormal];btnBottom.userInteractionEnabled = NO;NSSet *nsset = [NSSet setWithArray:@[productID]];// 请求商品SKProductsRequest *request = [[SKProductsRequest alloc] initWithProductIdentifiers:nsset];request.delegate = self;[request start];}else{[[[UIAlertView alloc]initWithTitle:nil message:NSLocalizedString(@"用户禁止应用内付费购买", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"确定", nil) otherButtonTitles:nil, nil] show];}
}//收到产品返回信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{if(response.products.count == 0){ // 无法获取产品信息,购买失败[self.navigationController.view hideToastActivity];self.navigationController.view.userInteractionEnabled = YES;[[[UIAlertView alloc]initWithTitle:nil message:NSLocalizedString(@"无法获取产品信息,请重试", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"确定", nil) otherButtonTitles:nil, nil] show];return;}SKMutablePayment *payment = [SKMutablePayment paymentWithProduct:response.products[0]];payment.quantity = (NSInteger)_coursesDetailInfo.price;//购买次数=价钱if (payment.quantity == 0) {payment.quantity = 1;}payment.applicationUsername = [NSString stringWithFormat:@"%ld", self.orderId];[[SKPaymentQueue defaultQueue] addPayment:payment];
}//请求失败
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error {NSLog(@"商品信息请求错误:%@", error); [self.navigationController.view hideToastActivity];self.navigationController.view.userInteractionEnabled = YES;[btnBottom setTitle:NSLocalizedString(@"立即支付", nil) forState:UIControlStateNormal];btnBottom.userInteractionEnabled = YES;[[[UIAlertView alloc]initWithTitle:nil message:NSLocalizedString(@"无法获取产品信息,请重试", nil) delegate:nil cancelButtonTitle:NSLocalizedString(@"确定", nil) otherButtonTitles:nil, nil] show];}- (void)requestDidFinish:(SKRequest *)request {
// [self.navigationController.view hideToastActivity];
// self.navigationController.view.userInteractionEnabled = YES;
}//监听购买结果
- (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(@"已经购买过商品");[self restoreTransaction:tran];break;case SKPaymentTransactionStateFailed:NSLog(@"交易失败");[self failedTransaction:tran];break;default:break;}}
}// 交易完成
- (void)completeTransaction:(SKPaymentTransaction *)transaction{NSLog(@"交易完成,走验证通道");NSLog(@"transaction=%@", transaction);NSString *productIdentifier = transaction.payment.productIdentifier;NSLog(@"productIdentifier=%@", productIdentifier);NSURL *receiptURL = [[NSBundle mainBundle] appStoreReceiptURL];NSData *receipt = [NSData dataWithContentsOfURL:receiptURL];NSString *strReceipt = [receipt base64EncodedStringWithOptions:0];NSLog(@"strReceipt=%@", strReceipt);NSString *orderId = transaction.payment.applicationUsername;NSLog(@"orderId=%@", orderId);if ([productIdentifier length] > 0) {// 向自己的服务器验证购买凭证}// Remove the transaction from the payment queue.[[SKPaymentQueue defaultQueue] finishTransaction: transaction];[self.navigationController.view hideToastActivity];self.navigationController.view.userInteractionEnabled = YES;[self payCompleted];}// 交易失败
- (void)failedTransaction:(SKPaymentTransaction *)transaction {[[SKPaymentQueue defaultQueue] finishTransaction:transaction];[self.navigationController.view hideToastActivity];self.navigationController.view.userInteractionEnabled = YES;[btnBottom setTitle:NSLocalizedString(@"立即支付", nil) forState:UIControlStateNormal];btnBottom.userInteractionEnabled = YES;}// 已经购买过该商品
- (void)restoreTransaction:(SKPaymentTransaction *)transaction {// 对于已购商品,处理恢复购买的逻辑[[SKPaymentQueue defaultQueue] finishTransaction: transaction];[self.navigationController.view hideToastActivity];self.navigationController.view.userInteractionEnabled = YES;[btnBottom setTitle:NSLocalizedString(@"立即支付", nil) forState:UIControlStateNormal];btnBottom.userInteractionEnabled = YES;
}
服务器验证
验证方法查看这里
测试服务器地址:https://sandbox.itunes.apple.com/verifyReceipt
正式服务器地址:https://buy.itunes.apple.com/verifyReceipt
验证时先向正式环境发起,如果返回码是 21007,说明是测试购买,再转向测试环境验证。
测试购买
进入 ITunes Connect 》用户和职能 》添加 沙箱技术测试员,然后就可以用这个测试账号发起购买了。
其它
记得开启 Capabilities > In-App Purchase
iOS 应用内购买(In-App Purchase)之开发相关推荐
- iOS 上 App 内购买(in-app purchase)的误消费可以退款吗?
iOS 上 App 内购买(in-app purchase)的误消费可以退款吗?修改 周二晚按照@任轶 的答案做了,把购物清单的四个订单号列在内容里,当晚收到了苹果公司自动回复,周三受到苹果公司团队中 ...
- IOS应用内购买App开发完整流程
2019独角兽企业重金招聘Python工程师标准>>> 看了一些网上教程,基本上是老版本的了.我针对自己遇到的一些问题,结合官方文档把IAP(In-App Purchase)过程梳理 ...
- iOS 应用内购买基础教程 swift篇
应用内购买基础教程 原文地址http://www.raywenderlich.com/105365/in-app-purchases-tutorial-getting-started 更新日志:本教程 ...
- iOS应用内购买(In App Purchase)总结
先附上几篇文章: 1.In App Purchases: A Full Walkthrough 这篇文章里说的都很详尽了,代码什么的基本可以照搬. 2.Store Kit Guide(In App P ...
- ios 应用内支付(In-App Purchase,沙盒测试,后台验证)
1.苹果iTunes Connect内购产品信息录入. 1)创建app内购买项目(Create New),选择类型: 1.消耗型项目 对于消耗型 App 内购买项目,用户每次下载时都必须进行购买.一次 ...
- ios 应用内购买 php,ios 应用内购买(cordova项目)
1.xcode配置开启支付功能 Capabilities-> 注册Merchant Ids(商用id): 在Identifiers下,选择Merchant IDs 在右上角点击"+&q ...
- iOS应用内置付费详尽攻略
我最近正在制作的一个程序里面,我就决定先把程序免费(其中只包含一个故事),然后把更多的故事放在in-app purchase里面.在这篇教程里面,你将会学到如何使用程序内置付费来解琐本地程序里面的内容 ...
- iOS开发之内购完全笔记(您已购买此 App 内购买项目。此项目将免费恢复。)
1.内购流程 1.在 AppStore 中创建相应的物品,创建内购沙盒测试账号 2.客户端从后台获取相应的物品 ID (当然也可以再客户端写死,但后期扩展性就受限制了) 3.依据相应的物品 ID 请求 ...
- Apple Pay 和 苹果内购买
在做开发的之前先说清楚 Apple Pay 和苹果内购不是一个东西,大家得区分开; Apple Pay –> 是类似于支付宝支付和微信支付的,用于购买实物的一种支付方式;日常会用到的场景是买个电 ...
最新文章
- 一天掌握AI核心技术,上手应用,开发者该划哪些重点?
- 告诉你,Spring Boot 真是个牛逼货!
- 在Bash脚本中,如果发生某种情况,如何退出整个脚本?
- Android - Intentservice源码解析
- hyperopt中文文档:Interfacing-With-Other-Languages(在其他语言中使用hyperopt)
- win10任务栏和开始菜单_如何将网站固定到Windows 10任务栏或开始菜单
- Spring Boot官方文档笔记
- 海康大华网络摄像机搜索工具
- 管螺纹如何标注_【专业知识】一次搞全所有螺纹常识,很基础
- 1-9 requests模块之爬取4k高清壁纸(xpath解析)
- 盗版xp成功验证成正版,享受正版增值服务!(转)
- OneNote使用技巧 - 5.快速设置首行缩进
- 力扣刷题 DAY_87 贪心
- VMware安装macOS High Sierra 10.13苹果系统并设置共享文件夹详细教程(图文)
- 淘宝开源深度学习端侧推理引擎 MNN
- mysql中的浮点数和定点数
- Android_(传感器)指南针
- mendeley引用参考文献不显示_手把手教你一步搞定引用参考文献,超级强大且使用的文献管理器...
- 用python编程计算器
- 6大B2C购物系统比较 1