如何为测试苹果内购添加内购沙盒测试试帐号

输入关键字或相关内容进行搜索
IOS平台最新集成了苹果官方提供的应用内支付(In-App Purchase),新的插件是在plus.payment的基础上进行了扩展,但是在使用方法上与原有的支付API的使用流程稍有区别,下面对IAP插件的使用方法进行说明手机用户可以在“设置-&通用-&访问限制-&App 内购买项目”中关闭支付,如果用户关闭了IAP,开发者将获取不到ID为“appleiap”的支付通道。IAP支付对PaymentChannel对象进行了扩展添加了以下几个方法
requestOrder
向Appstore请求有效的商品详情
restoreComplateRequest 向Appstore发送请求获取已经购买商品(非消耗型项目和订阅项目)的支付信息,获取成功以后会返回一个的已购商品收据列表。下面对应用内支付的使用方法进行说明,文中API的参数及使用实例请参考购买商品接口使用方法\n
首先调用plus.payment.getChannels获取支付通道,IAP支付通道的ID为“appleiap”
调用ID为“appleiap”的PaymentChannel对象的requestOrder方法,像Appstore请求有效的商品详情。注意:IAP支付必须在调用payment.request方法之前,调用requestOrder方法,否则调用payment.request将会报错。
调用plus.payment.request方法发起支付请求,传入statement的参数为JSON对象,可以设置如下参数
productid String(必选)要支付的商品的标识(必须是调用requestOrder返回的有效的商品标识)
username String(可选)购买商品用户的用户名
String (可选)购买商品的数量,如果不填写默认为1
&meta charset=&utf-8& /&
&meta name=&viewport& content=&initial-scale=1.0, maximum-scale=1.0, user-scalable=no& /&
&title&Hello H5+&/title&
&script type=&text/javascript&&
var IAPOrders = ['io.dcloud.payTest1', 'io.dcloud.payTest2'];
function plusReady() {
// 获取支付通道
plus.payment.getChannels(function(channels) {
for (var i in channels) {
if (channel[i].id == 'appleiap') {
iapChannel = channel[i];
iapChannel.requestOrder(IAPOrders, function(event) {
for (var index in event) {
var OrderItem = event[index];
outLine(&Title:& + OrderItem.title + &Price:& + OrderItem.price + &Description:& + OrderItem.description + &ProductID:& + OrderItem.productid);
}, function(errormsg) {
outLine(&获取支付通道失败:& + errormsg.message);
}, function(e) {
outLine(&获取支付通道失败:& + e.message);
document.addEventListener('plusready', plusReady, false);
function pay(id) {
plus.payment.request(iapChannel, {
&productid&: id,
&username&: &appusername&,
&quantity&: 2
}, function(result) {
alert(JSON.stringify(result));
}, function(e) {
plus.nativeUI.alert(&更多错误信息请参考支付(Payment)规范文档:http://www.html5plus.org/#specification#/specification/Payment.html&, null, &支付失败:& + e.code);
\n恢复已购项目接口使用方法\n
首先调用plus.payment.getChannels获取支付通道,IAP支付通道的ID为“appleiap”
调用ID为“appleiap”的PaymentChannel对象的restoreComplateRequest方法
\n示例:&!DOCTYPE HTML&
&meta charset=&utf-8& /&
&meta name=&viewport& content=&initial-scale=1.0, maximum-scale=1.0, user-scalable=no& /&
&title&Hello H5+&/title&
&script type=&text/javascript&&
var IAPOrders = ['io.dcloud.payTest1', 'io.dcloud.payTest2'];
function plusReady() {
// 获取支付通道
plus.payment.getChannels(function(channels) {
for (var i in channels) {
if (channel[i].id == 'appleiap') {
iapChannel = channel[i];
iapChannel.requestOrder(IAPOrders, function(event) {
for (var index in event) {
var OrderItem = event[index];
outLine(&Title:& + OrderItem.title + &Price:& + OrderItem.price + &Description:& + OrderItem.description + &ProductID:& + OrderItem.productid);
}, function(errormsg) {
outLine(&获取支付通道失败:& + errormsg.message);
}, function(e) {
outLine(&获取支付通道失败:& + e.message);
document.addEventListener('plusready', plusReady, false);
function getPayedTrances() {
iapChannel.restoreComplateRequest({
&username&: &waipptt&
},function(trancs){
outLine(“获取已经购买项目成功:” + JSON.stringify(trancs));
}, function(errormsg){
outLine(&获取支付通道失败:& + errormsg.message);
你做好了苹果内购了吗?
我的目前也报这个错了,怎么解决啊,用的苹果沙盒测试账号支付完全没问题,换为正式账号就报这个错了。
检查一下itunes账号是否有测试的权限,或者商品为非消耗性商品重复购买了
payment_appleiap:-6
在文档中找不到这个报错
打印一下错误的message看下详细的错误信息
iap一直报-100.。。。怎么破@客服
你做好了吗
IAPOrders @ DCloud_SDK_骁骑 大神 这里面参数写什么
看你的支付涉及到什么东西,如果支付的商品时虚拟商品(类似:游戏币,视频等等),就必须用到苹果内支付(人家要收取提成的),如果是实物的话就可以不用苹果支付,微信或者支付宝都可以
谢谢亲,研究一下
支付申请的部分可以参考文档
/XimuYouzi/archive//5401749.html
请问有完整示例么?官方的html5+例子不能用,没明白原理,是跟微信一样需要在微信平台申请接口,然后客户服务器端写接口程序,app端按上面代码即可么?@大神
请问,您那边解决了么
苹果端有支付的话,必须用应用内支付接口么?客户需求是用微信支付,我提交了几个版本都没有通过审核,请问是这个原因么(说明里提到支付)
谁有具体的 苹果内购实例啊,苹果内购没法做出来,无法通过审核,开发苹果的APP就没有意义了啊
云端打包后测试,也还没有获取到appleiap 呢 代码也跟上边例子一样的
在manifest.json中的plus-&distribute-&plugins-&payment节点下添加“appleiap”相关的节点,并提交云端打包。
更多说明参考:
[http://ask./article/71](http://ask./article/71)
[http://ask./article/497](http://ask./article/497)
获取不到 appleiap 的channel呢?其他的都可以得到!
要回复文章请先或| 漏洞检测 |
| 隐藏捆绑 |
ios 应用内支付(In-App Purchase,沙盒测试,后台验证)
1.苹果iTunes Connect内购产品信息录入。 1)创建app内购买项目(Create New),选择类型: 1.消耗型项目 对于消耗型 App 内购买项目,用户每次下载时都必须进行购买。一次性服务通常属于消耗型项目,例如钓鱼App 中的鱼饵。 2.非消耗型项目 对于非消耗型 Ap
1.苹果iTunes Connect内购产品信息录入。
1)创建app内购买项目(Create New),选择类型:
1.消耗型项目
对于消耗型 App 内购买项目,用户每次下载时都必须进行购买。一次性服务通常属于消耗型项目,例如钓鱼App 中的鱼饵。
2.非消耗型项目
对于非消耗型 App 内购买项目,用户仅需要购买一次。不会过期或随使用而减少的服务通常为非消耗型项目,例如游戏App 的新跑道。
3.自动续订订阅
通过自动续订订阅,用户可以购买指定时间期限内的更新和动态内容。除非用户取消选择,否则订阅(例如杂志订阅等)会自动续订。
4.免费订阅
通过免费订阅,开发者可以将免费订阅内容放入&报刊杂志&。用户注册免费订阅后,该订阅内容将会出现在与该用户Apple ID 关联的所有设备上。请注意,免费订阅不会过期,并且仅在支持报刊杂志功能的 App 中提供。
5.非续订订阅
非续订订阅允许有时限性的营销服务。对于 App 内购买项目中的限时访问内容,就需使用非续订订阅。例如,导航App 中语音导航功能的一周订阅,或者年度订阅已存档的视频或音频的在线目录。
一定要根据自己的情况选择正确,不然会被App Store审核团队拒绝。内的虚拟币要采用消耗型的,有固定时限的会员选择自动续订订阅。也可以只选择虚拟币充值自己购买的情况解决会员问题。
2)生成共享密钥
共享密钥是在您联系我们的服务器获取 App 内购买项目收据时使用的唯一代码。没有共享密钥,您将无法在沙箱技术模式下自动续订 App 内购买项目。另外,共享密钥不能在 App Store 使用。
注:无论与哪个 App 相关联,您的所有自动续订订阅都将使用同一共享密钥。
此共享密钥用于服务器验证用户购买项目的凭证,生成新密要服务器也立即改变验证密钥。共享密钥在验证自动续订订阅类型项目的时候必须需要。
3)内购项目的状态
A) Pending Developer Approval & Your in apppurchase has been created but has not been tested in a sandbox environment andapproved by you.
B) Approved By Developer & Your in apppurchase has been tested in a sandbox environment and has been approved by you.
C) Waiting For Review & You have submittedyour in app purchase to be reviewed by Apple.
D) In Review & Your in app purchase iscurrently being reviewed by Apple no edits can be made.
E) Developer Action Required & In app purchasedetail changes that you submitted have been rejected. You are required to takeaction to edit the detail information or cancel the request to change thedetail information before this in app purchase can be reviewed again.(内购项目详情界面会提示那个地方出现了问题,稍微修改一下再次提交就行了)
F) Ready for Sale & Apple has approved your inapp purchase to go live on the App Store with its associated application. Thein app purchase must be cleared for sale in iTunes Connect to be Ready forSale.
G) Rejected & Apple has rejected your in apppurchase during the review process. If you have not already been contacted byApple with more information about your rejection, you may inquire through theContact Us section of iTunes Connect. A rejected in app purchase cannot bereinstated. You must create a new in app purchase if you still wish for it tobe sold.
H) Developer Removed from Sale & You havemarked your in app purchase as not cleared for sale in iTunes Connect.
2.app端程序代码编写(代码仅供参考)
#pragma mark - 以单利的形式展开
+(sObject*)Shares
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
if (_purchase == nil) {
_purchase = [[super alloc]init];
[[SKPaymentQueue defaultQueue]addTransactionObserver:_purchase];
+(id)allocWithZone:(struct _NSZone *)zone
static dispatch_once_t onceT
dispatch_once(&onceToken, ^{
if (_purchase == nil) {
_purchase = [[super allocWithZone:zone]init];
+(id)alloc
#pragma mark -钻石会员
_alter = [[UIAlertView alloc]initWithTitle:@游客模式购买仅限当前设备使用所购买的权限,推荐您登录购买 message:nil delegate:self cancelButtonTitle:@取消 otherButtonTitles:@登陆购买(推荐),@游客模式购买 ,nil];
//游客购买很重要,会被AppStore审核团队拒绝。
#pragma mark -开始支付,根据录入内购项目的产品id去AppStore请求产品信息。
if ([SKPaymentQueue canMakePayments]) {
NSSet * set = [NSSet setWithArray:@[ProductID]];
SKProductsRequest * request = [[SKProductsRequest alloc] initWithProductIdentifiers:set];
request.delegate =
[request start];
NSLog(@无权限购买);
#pragma mark -SKProductsRequestDelegate 获取appstroe产品信息
- (void)productsRequest:(SKProductsRequest *)requestdidReceiveResponse:(SKProductsResponse *)response {
self.mySelfView.userInteractionEnabled = NO;
[AFTools showHUD:@获取产品信息 atView:self.mySelfView];
NSLog(@-----------收到产品反馈信息--------------);
NSArray *myProduct = response.
if (myProduct.count == 0) {
[AFTools alertWithTitle:@购买失败 message:@无法获取产品信息];
NSLog(@无法获取产品信息,购买失败。);
NSLog(@产品products==%@,myProduct);
NSLog(@产品id==%@,response.invalidProductIdentifiers);
NSLog(@产品数量==========%lu,(unsigned long)myProduct.count);
for(SKProduct *product in myProduct){
// SKMutablePayment
NSLog(@SKProduct描述信息%@, [product description]);
NSLog(@产品标题 %@ , product.localizedTitle);
NSLog(@产品描述信息: %@ , product.localizedDescription);
NSLog(@价格: %@ , product.price);
NSLog(@Product id: %@ , product.productIdentifier);
SKMutablePayment *MpayMent = [SKMutablePayment paymentWithProduct:product];
NSLog(@===%@,MpayMent.requestData);
if ([[SKPaymentQueue defaultQueue]respondsToSelector:@selector(addPayment:)]){
[[SKPaymentQueue defaultQueue] addPayment:MpayMent];
#pragmamark-SKPaymentTransactionObserver支付结果
- (void)paymentQueue:(SKPaymentQueue *)queueupdatedTransactions:(NSArray *)transactions
for (SKPaymentTransaction *transaction in transactions)
switch (transaction.transactionState)
case SKPaymentTransactionStatePurchased://交易完成
NSLog(@交易完成transactionIdentifier= %@, transaction.transactionIdentifier);
[self completeTransaction:transaction];
case SKPaymentTransactionStateFailed://交易失败
[self failedTransaction:transaction];
NSLog(@交易失败);
case SKPaymentTransactionStateRestored://已经购买过该商品
[self restoreTransaction:transaction];
NSLog(@已买过商品);
case SKPaymentTransactionStatePurchasing://商品添加进列表
NSLog(@商品添加进列表);
- (void)paymentQueue:(SKPaymentQueue *)queueremovedTransactions:(NSArray *)transactions
NSLog(@---------------移除-------------);
- (void)paymentQueue:(SKPaymentQueue *)queuerestoreCompletedTransactionsFailedWithError:(NSError *)error
NSLog(@---------------重复支付失败-------------);
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@-------------------支付完成--------------------);
[self commitSeversSucceeWithTransaction:transaction];
-(void)restoreTransaction: (SKPaymentTransaction *)transaction
NSLog(@----------------重复支付-----------------);
[self commitSeversSucceeWithTransaction:transaction];
- (void)commitSeversSucceeWithTransaction:(SKPaymentTransaction *)transaction
NSString * productIdentifier = transaction.payment.productI
NSString *transactionReceiptString=
//系统IOS7.0以上获取支付验证凭证的方式应该改变,切验证返回的数据结构也不一样了。
if(IOSSystemVersion&=7.0)
NSURLRequest*appstoreRequest = [NSURLRequest requestWithURL:[[NSBundle mainBundle]appStoreReceiptURL]];
NSError *error =
NSData * receiptData = [NSURLConnection sendSynchronousRequest:appstoreRequestreturningResponse:nil error:&error];
transactionReceiptString = [receiptDatabase64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed];
NSData * receiptData = transaction.transactionR
transactionReceiptString = [receiptDatabase64EncodedString];
// 向自己的服务器验证购买凭证
- (void)failedTransaction:(SKPaymentTransaction *)transaction {
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
最好在客户端上键一个数据库,跟踪订单的状态,防止用户订单在某个环节出现问题时无法寻找到订单进行二次处理。
去AppStore请求数据时有时候会出现错误,你可以iTunes connect里的connect us去给他们写邮件反馈问题。但是大部分时间你等等就能解决了,对就是什么也不做等着。也许那一天他就好了。
3.后台服务器验证
IOS 内支付有两种模式:
1) 内置模式
2) 服务器模式
内置模式的流程可以简单的总结为以下几步:
1) app从app store 获取产品信息
2) 用户选择需要购买的产品
3) app发送支付请求到app store
4) app store 处理支付请求,并返回transaction信息
5) app将购买的内容展示给用户
服务器模式的主要流程如下所示:
1) app从服务器获取产品标识列表
2) app从app store 获取产品信息
3) 用户选择需要购买的产品
4) app 发送 支付请求到app store
5) app store 处理支付请求,返回transaction信息
6) app 将transaction receipt 发送到服务器
7) 服务器收到收据后发送到app stroe验证收据的有效性
8) app store 返回收据的验证结果
9) 根据app store 返回的结果决定用户是否购买成功
(责任编辑:幽灵学院)
------分隔线----------------------------
据外媒报道,台湾版新iPhone 6是金色机身(大陆版也是金色)...
春季发布会除了不知道会不会开的苹果新品之外,最让人瞩目的...
意法半导体晶圆厂发生火灾!拖累iPhone 8...
日经:iPhone 8曲面屏只具备视觉效果,没有实际功能...
黎丹_学雷锋格言_iphone7桌面全部靠下...
我们知道许多人不服老,却没料到也有手机不服老。说起来,iP...
工作日:9:00-21:00
周 六:9:00-18:00
&&扫一扫关注幽灵学院【iOS】苹果IAP(内购)中沙盒账号使用注意事项 - 简书
【iOS】苹果IAP(内购)中沙盒账号使用注意事项
沙盒账号的正确使用方式
沙盒账号使用的注意事项
进行了更新
1.沙盒账号是什么
iOS应用里面用到了苹果应用内付费(IAP)功能,在项目上线前一定要进行功能测试。测试肯定是需要的,何况这个跟money有关。。。开发完成了之后,如何进行测试呢?难道我测试个内购功能要自己掏钱?就算是公司掏钱,但是苹果要吃掉3成的啊,想想如果是99刀的商品,点下购买的时候心里都有点发慌。。。苹果当然没这么坑了,测试内购,苹果提供了沙盒账号(也叫沙箱账号)的方式。这个沙箱账号其实是虚拟的AppleID,在开发者账号后台的iTune Connect上配置了之后就能使用沙盒账号测试内购,有了沙盒账号,就能体验一把土豪的感觉了,游戏钻石什么的随便充,反正不用我的钱。
注意:你可以把沙盒账号看做是一个虚拟的AppleID,这个AppleID只有进行内购测试的功能。
2.沙盒账号使用的前提
内购的商品ID,价格等相关信息已经录入到开发者后台了(不然那你买什么)
开发者后台已经创建好沙盒测试账号了(下面我们会将如何创建)
你要有一部真机(iPhone或iPad都行,别用模拟器就好。而且不能是越狱机)
bundleID别搞错了,开发者账号、证书、bundleID要一致
如果你是第一次在这个开发者账号上集成内购功能,请先将iTune Connect上的税务协议都填写好,否则内购时会发现商品ID无效。税务协议的问题不少童鞋遇到了,可以参考这篇文章
3.沙盒账号创建
登录苹果开发者后台--iTunes Connect--用户和职能--沙箱测试技术员,在这个界面你可以看到当前账号已经创建好的沙盒账号。
沙箱测试技术员管理界面
点击“+”进行创建
创建沙盒账号
新创建的沙盒账号
如图,我创建一个沙盒账号。具体信息:
名字为test1
AppleID为(也就是上面填的电子邮件)
App Store地区为中国
电子邮件不能是别人已经注册过AppleID的邮箱
电子邮箱可以是一个不存在电子邮箱(只要符合格式,随便写)
App Store 地区不要乱选。虽然随便哪个地区都可以用来测试(还没上线之前app并没有地区之分),但是在沙盒测试的时候,弹出的购买提示框会根据当前AppleID(沙盒账号)的地区显示语言的。
4.沙盒账号使用流程
1.在iPhone上安装测试包(必须是adhoc签名证书或者develop签名证书打的包,不能是从App Store上下载的)
2.退出iPhone的App Store账号(因为我们需要使用沙盒账号登录)。
操作方法一:打开App Store应用首页滑到最下方--选中AppleID--注销
操作方法二:设置--iTunes Store与App Store--选中AppleID--注销
这里只需要退出账号,退出之后,不需要在这里登录沙盒账号,因为你压根就登录不了。之前已经说过了,沙盒账号是一个假的AppleID账号,不能直接登录的。如果强行登陆,会出现以下报错提示:
使用沙盒账号直接登录报错提示
3.在测试包里面购买商品,系统会让你进行登录,这里我们点击“使用现有的AppleID”就可以输入刚才创建好的沙盒测试账号进行登录了。
点击购买商品后出现登录窗口
输入沙盒账号密码进行登录
4.输入账号之后,有可能会出现如下提示,点击确定之后会跳转到App Store,导致这次购买失败。没关系,我们再次回到测试包,然后购买商品就好
跳转到App Store跳转店面的提示
出现提示的原因:因为AppleID是分地区的。之前我们创建沙盒账号的时候就看到了,需要选择地区。App Store也是分地区的,对应的AppleID只能在App Store对应的地区进行下载和购买东西。我们刚才创建的这个账号的地区是中国,所以只能在中国店面登录。由于我之前的登录的账号越南的,所以此时AppStore店面是越南店面。所以我们这次登录,系统会跳转到AppStore应用将店面切换到中国。另外,App Store应用切换地区的时候,会报【Your request produced an error】。这个不需要管。
5.点击购买商品之后,成功的话会出现相应提示。
商品内容和价格展示窗口
备注:我们在iTunes Connect上创建商品了之后,除了需要填商品ID,商品名称,商品描述,价格等之外,还要上传一张图片,图片就是上面这个界面。
购买成功提示
沙盒账号注意事项
BudleID,证书,商品ID等内容一致,才能进行接下来的储值测试(BundleID都不对,还玩什么)
测试设备需要使用不越狱的真机(越狱机不能进行沙盒储值,模拟器也不能进行沙盒储值)
沙盒账号是不能直接在App Store进行登录的,只能在点击了购买商品之后,在弹出的登录框进行登录。
真实的AppleID不能在adhoc证书和develop证书打出来的包进行沙盒储值测试,所以在沙盒测试之前,需要退出真实的AppleID账号
从App Store上面下载的包不能使用沙盒账号进行储值
关于证书的问题:1.使用develop签名证书和adhoc签名证书打的ipa包,我把他们叫做测试包,测试包只能使用沙盒账号进行储值,不能使用真实的AppleID进行储值2.从App Store应用下载的包,我把他们叫做线上包,线上包只能使用真实的AppleID进行储值,不能使用沙盒账号进行储值
另外唠叨一下:楼主平常上传包的时候是打包了ipa包之后,使用Xcode里面的Application Loader应用上传应用的。虽然很多人上传包使用的是appstore的签名证书,但是,其实使用adhoc的证书打包的ipa包也是可以正常上传并且送审上线的。我平常就是用adhoc的证书打包成ipa包,给测试妹子测试,测试完直接用这个包上传送审了。嘿嘿。
一些经验总结,不当之处敬请指正。写作不易,喜欢请点个赞=^_^=
最怕你碌碌无为,还安慰自己平凡可贵。iOS开发内购全套图文教程 - 简书
iOS开发内购全套图文教程
2015年最全的内购图文教程,首先是填各种资料,最后是代码,废话不多说,直接上图
如对你有帮助,请不要吝惜打赏和喜欢,谢谢!
======================第一部分协议===============
第一步.png
第二步.jpg
第三步.jpg
第四步.png
第五步.png
第六步.png
第七步.jpg
第八步.jpg
第九步.jpg
第十步.png
CNAPS CODE 查询地址
十一步.jpg
十二步.jpg
十三步.png
十四步.png
十五步.jpg
十七步.jpg
十八步.jpg
十九步.png
十九步(1).png
十九步(2).png
没显示的都是可以不填的,主要是打钩
title 和最后面的Self
二十步.png
=============第二部分创建内购项目============
===========第三部分贴加内购项目测试账号==========
创建测试账号.png
沙盒测试员.png
账号信息.png
=============第四部分主要实现代码==========
首先导入StoreKit.framework库
#import &StoreKit/StoreKit.h&
IAP0p20=20,
IAP9p1000,
IAP24p6000,
}buyCoinsT
@interface RechargeVC : UIViewController &SKPaymentTransactionObserver,SKProductsRequestDelegate &
- (void) requestProUpgradeProductD
-(void)RequestProductD
-(void)buy:(int)
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)
-(void) PurchasedTransaction: (SKPaymentTransaction *)
- (void) completeTransaction: (SKPaymentTransaction *)
- (void) failedTransaction: (SKPaymentTransaction *)
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)
- (void) restoreTransaction: (SKPaymentTransaction *)
-(void)provideContent:(NSString *)
-(void)recordTransaction:(NSString *)
#import "RechargeVC.h"
//在内购项目中创的商品单号
#define ProductID_IAP0p20 @"Nada.JPYF01"//20
#define ProductID_IAP1p100 @"Nada.JPYF02" //100
#define ProductID_IAP4p600 @"Nada.JPYF03" //600
#define ProductID_IAP9p1000 @"Nada.JPYF04" //1000
#define ProductID_IAP24p6000 @"Nada.JPYF05" //6000
@interface RechargeVC ()
@implementation RechargeVC
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[self buy:IAP0p20];
-(void)buy:(int)type
if ([SKPaymentQueue canMakePayments]) {
[self RequestProductData];
NSLog(@"允许程序内付费购买");
NSLog(@"不允许程序内付费购买");
UIAlertView *alerView =
[[UIAlertView alloc] initWithTitle:@"提示"
message:@"您的手机没有打开程序内付费购买"
delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
[alerView show];
-(void)RequestProductData
NSLog(@"---------请求对应的产品信息------------");
NSArray *product =
switch (buyType) {
case IAP0p20:
product=[[NSArray alloc] initWithObjects:ProductID_IAP0p20,nil];
case IAP1p100:
product=[[NSArray alloc] initWithObjects:ProductID_IAP1p100,nil];
case IAP4p600:
product=[[NSArray alloc] initWithObjects:ProductID_IAP4p600,nil];
case IAP9p1000:
product=[[NSArray alloc] initWithObjects:ProductID_IAP9p1000,nil];
case IAP24p6000:
product=[[NSArray alloc] initWithObjects:ProductID_IAP24p6000,nil];
NSSet *nsset = [NSSet setWithArray:product];
SKProductsRequest *request=[[SKProductsRequest alloc] initWithProductIdentifiers: nsset];
request.delegate=
[request start];
//&SKProductsRequestDelegate& 请求协议
//收到的产品信息
- (void)productsRequest:(SKProductsRequest *)request didReceiveResponse:(SKProductsResponse *)response{
NSLog(@"-----------收到产品反馈信息--------------");
NSArray *myProduct = response.
NSLog(@"产品Product ID:%@",response.invalidProductIdentifiers);
NSLog(@"产品付费数量: %d", (int)[myProduct count]);
// populate UI
for(SKProduct *product in myProduct){
NSLog(@"product info");
NSLog(@"SKProduct 描述信息%@", [product description]);
NSLog(@"产品标题 %@" , product.localizedTitle);
NSLog(@"产品描述信息: %@" , product.localizedDescription);
NSLog(@"价格: %@" , product.price);
NSLog(@"Product id: %@" , product.productIdentifier);
SKPayment *payment =
switch (buyType) {
case IAP0p20:
= [SKPayment paymentWithProductIdentifier:ProductID_IAP0p20];
case IAP1p100:
= [SKPayment paymentWithProductIdentifier:ProductID_IAP1p100];
case IAP4p600:
= [SKPayment paymentWithProductIdentifier:ProductID_IAP4p600];
case IAP9p1000:
= [SKPayment paymentWithProductIdentifier:ProductID_IAP9p1000];
//支付1048
case IAP24p6000:
= [SKPayment paymentWithProductIdentifier:ProductID_IAP24p6000];
//支付5898
NSLog(@"---------发送购买请求------------");
[[SKPaymentQueue defaultQueue] addPayment:payment];
- (void)requestProUpgradeProductData
NSLog(@"------请求升级数据---------");
NSSet *productIdentifiers = [NSSet setWithObject:@"com.productid"];
SKProductsRequest* productsRequest = [[SKProductsRequest alloc] initWithProductIdentifiers:productIdentifiers];
productsRequest.delegate =
[productsRequest start];
//弹出错误信息
- (void)request:(SKRequest *)request didFailWithError:(NSError *)error{
NSLog(@"-------弹出错误信息----------");
UIAlertView *alerView =
[[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Alert",NULL) message:[error localizedDescription]
delegate:nil cancelButtonTitle:NSLocalizedString(@"Close",nil) otherButtonTitles:nil];
[alerView show];
-(void) requestDidFinish:(SKRequest *)request
NSLog(@"----------反馈信息结束--------------");
-(void) PurchasedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"-----PurchasedTransaction----");
NSArray *transactions =[[NSArray alloc] initWithObjects:transaction, nil];
[self paymentQueue:[SKPaymentQueue defaultQueue] updatedTransactions:transactions];
//&SKPaymentTransactionObserver& 千万不要忘记绑定,代码如下:
//----监听购买结果
//[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易结果
NSLog(@"-----paymentQueue--------");
for (SKPaymentTransaction *transaction in transactions)
switch (transaction.transactionState)
case SKPaymentTransactionStatePurchased:{//交易完成
[self completeTransaction:transaction];
NSLog(@"-----交易完成 --------");
UIAlertView *alerView =
[[UIAlertView alloc] initWithTitle:@""
message:@"购买成功"
delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
[alerView show];
case SKPaymentTransactionStateFailed://交易失败
{ [self failedTransaction:transaction];
NSLog(@"-----交易失败 --------");
UIAlertView *alerView2 =
[[UIAlertView alloc] initWithTitle:@"提示"
message:@"购买失败,请重新尝试购买"
delegate:nil cancelButtonTitle:NSLocalizedString(@"关闭",nil) otherButtonTitles:nil];
[alerView2 show];
case SKPaymentTransactionStateRestored://已经购买过该商品
[self restoreTransaction:transaction];
NSLog(@"-----已经购买过该商品 --------");
case SKPaymentTransactionStatePurchasing:
//商品添加进列表
NSLog(@"-----商品添加进列表 --------");
- (void) completeTransaction: (SKPaymentTransaction *)transaction
NSLog(@"-----completeTransaction--------");
// Your application should implement these two methods.
NSString *product = transaction.payment.productI
if ([product length] & 0) {
NSArray *tt = [product componentsSeparatedByString:@"."];
NSString *bookid = [tt lastObject];
if ([bookid length] & 0) {
[self recordTransaction:bookid];
[self provideContent:bookid];
// Remove the transaction from the payment queue.
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
//记录交易
-(void)recordTransaction:(NSString *)product{
NSLog(@"-----记录交易--------");
//处理下载内容
-(void)provideContent:(NSString *)product{
NSLog(@"-----下载--------");
- (void) failedTransaction: (SKPaymentTransaction *)transaction{
NSLog(@"失败");
if (transaction.error.code != SKErrorPaymentCancelled)
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
-(void) paymentQueueRestoreCompletedTransactionsFinished: (SKPaymentTransaction *)transaction{
- (void) restoreTransaction: (SKPaymentTransaction *)transaction
NSLog(@" 交易恢复处理");
-(void) paymentQueue:(SKPaymentQueue *) paymentQueue restoreCompletedTransactionsFailedWithError:(NSError *)error{
NSLog(@"-------paymentQueue----");
#pragma mark connection delegate
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
NSLog(@"%@",
[[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]);
- (void)connectionDidFinishLoading:(NSURLConnection *)connection{
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
switch([(NSHTTPURLResponse *)response statusCode]) {
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
NSLog(@"test");
-(void)dealloc
[[SKPaymentQueue defaultQueue] removeTransactionObserver:self];//解除监听
内购项目不再是单独提交审核了,只要app提交审核内购项目自然跟着改变状态,不消耗物品请不要选择 托管那一项,不然会出现问题
技术交流群:(免费)
.8/人付费 手机QQ才能加哦?)
如对你有帮助,请不要吝惜你的star和喜欢哦!
好文推荐:
原文在:版权归(C)Bison所有 如需转载请保留原文超链接地址!否则后果自负!
iOS开发工程师
http://blog.alll...

我要回帖

更多关于 添加沙盒测试账号 的文章

 

随机推荐