苹果内购德州扑克破解版内购,显示购买成功,就是没有...

“苹果商店”内购倒爷:层层揭秘,为什么会有那么便宜的游戏币_极客公园_【传送门】
本文转载自触乐网在一些游戏论坛和微博上,经常能看到有手游玩家疑问:“有人兜售游戏里的宝物或金币,比官方内购价便宜很多,他们是真是假?如果是真的,到底如何做到的?”在最近的几个月来,这种疑问呈现越来越多的趋势。触乐网记者就这一问题,在淘宝上试着以关键字“iOS 游戏充值”搜索了一番,得到回馈商品信息超过 5000 条。这些游戏代充服务大都集中在当前的热门手游作品诸如《我叫 MT》《神魔》《神雕侠侣》等游戏上,这些代充服务售价远低于官方内购价。以热门游戏《我叫 MT》为例,游戏中价格最高的内购“7770 符石”的官方价格为 648 元,而淘宝代充店的价格是 460 元----相当于以 7.1 折价格买到了内购。利用盗刷和黑卡低价代购 App 甚至 Gift Card,在网上早已有之。但如今在这些代购商家的店铺页面里,我们却都会看到相似的强调信息----正规充值,绝无黑卡,笔笔都有官方充值订单。在不使用黑卡或盗用信用卡帐号的前提下,商家依然能以低价进行内购代充,这意味着此举有利可图。经触乐网记者查询相关信息,发现此类代充业务销量巨大。仍以《我叫 MT》为例,某淘宝店铺 3 个月的交易量高达 989 次,而一家店铺主打的热门手游平均为 4 到 8 款。即便是非常保守地估计,一家店铺每天的利润也能达到 1000 元人民币以上。淘宝上提供此类服务的商家比比皆是,信誉最高者已达 5 蓝冠。与此同时,一条出现在国内苹果开发论坛 Cocoa China 的一条帖子引起了触乐网的注意,有国内 APP 开发者声称:他们的 APP 只在中国区上架,却在 iTunes 后台看到了很多用南非货币结算的内购。为此当事人还特意去南非 AppStore 进行搜索,却未发现自己公司的产品。开发者对此毫无头绪,但使用南非货币结算的内购却频繁发生。根据触乐网记者得到的消息,不只有一家手游公司注意到了这一现象,但多数都不知南非货币从何而来。两条线索交叉到一起,一个未被苹果重视的付费漏洞,以及一条快速成长的灰色产业链条,逐渐浮出水面。苹果与汇率首要的问题出在汇率上。App Store 有一套自己的汇率折算系统,该汇率系统相对于国际汇率体系而言是固定不变的。而最近一年因为诸多原因,部分国家(如南非)的货币对美元汇率波动巨大,从而导致以下现象:一款中国区售价 100 元人民币的游戏(或内购物品),如果用这些汇率波动国家货币进行支付,借助 App Store 汇率和实际汇率的差价折算后,实际仅需 70 元人民币。而部分头脑灵活的人正好发现了这合法且合理的“汇率漏洞”,并利用这一漏洞大量以低折扣销售热门游戏的内购物品,最终导致游戏运营商和开发者蒙受损失。以全球上架的《部落冲突》为例,“一大箱宝石”的售价,在中国、美国、南非的售价分别为 648 人民币、99.99 美元、799.99 兰特,如下图:以 2 月 28 日南非兰特(南非官方货币)对人民币的汇率 0.57 计算,同样的“一大箱宝石”,用兰特结算,只需要 455 人民币,比国服便宜了将近 200 块。根据触乐网记者得到的消息,一款月销售额超过 700 万元人民币的产品,每个月因这种合法倒卖而造成的损失约超过 100 万----一款不错的手游产品,每月的账面销售额为 700 万元,但可能真正到账的只有 550 万元,其余的 150 万元中约有 50 万元的黑卡耗损,而剩余的 100 万则被这些汇率倒卖者攫取。而目前各大手游企业还没有有效的方式来控制这一因 App Store 汇率问题而造成的直接经济损失。众所周知,App Store 为付费项目设置了超过 80 个价格等级,每个价格等级在不同国家 App Store 中的官方汇率差并非完全按实际汇率制定。苹果并不会频繁修正不同地区 App Store 的实际售价,因此,汇率倒卖者将两个因素综合评估后,在不同地区的 App Store 中大量使用急剧贬值的货币购买国内热门游戏或道具,则完全可以利用这一差价获取暴利。南非兰特正是这种货币。南非兰特风云史南非兰特是由南非储备银行发行的货币,于 1961 年 2 月正式发行。作为赤字庞大的经济体,南非兰特的货币走势相当脆弱。由于美联储在 2013 年底启动了宽松货币政策退出机制,使次贷危机以来经济结构转型较为缓慢的南非受到较大冲击并导致南非兰特不断贬值。过去这一年来,南非兰特汇率大幅下跌,而南非区 App Store 对应的价格仍保持在年初的高位。南非兰特汇率走势如图所示,去年 10 月时,南非兰特对人民币的汇率约为 0.61,此后继续不断震荡并持续下调,而若以 App Store 上的价格计算,南非兰特对人民币的汇率高达 0.75。实际上,虽然 2012 年苹果商店就开启了南非 iTunes 商店并支持兰特交易,但直到去年 10 月中旬,南非 App Store 才开放游戏类别的 APP 销售。这与淘宝卖家开始代充的频率完全一致。汇率的变化,以及苹果在这方面迟缓的响应,稍加注意的人都能觉察,也不乏有人想到利用汇率差价倒卖 App Store 商品,但实践起来则会遇到一个非常棘手的问题:无论是《神雕侠侣》《全民英雄》还是《我叫 MT》,都未曾在南非上架,而中国区的版本仅支持中国账号和人民币购买。那么内购倒爷又是如何用南非兰特结算压根不存在于南非 App Store 的游戏----的内购呢?实践----买一个不存在的游戏按照苹果 App Store 的规则,如果用户的账号为南非区,就只能使用南非区 App Store。且不说国内诸如《我叫 MT》、《神雕侠侣》在内的诸多游戏并未在南非上架,即便上架,内购倒爷也无法达到为国服玩家充值的目的----经触乐记者测试,如果先用国服 Apple ID 下载游戏,再换成南非 ID 进入游戏,价值 648 人民币的内购的确会换算成 799 南非兰特,但这时点击购买,会弹出“此程序非当前 ID 购买,请先购买程序”。换言之,你无法用一个账号去购买另一个账号名下的游戏内购。但如果始终用同一个账号呢?这时我们大致能猜到,淘宝商家应该采取了某种方式,使用南非账号买到了中国区的 APP,然后再用兰特结算。但这听起来不太可能实现----在不切换账号的前提下,如何购买一个在当前区域没有上架的游戏呢?随着调查的进一步深入,我们经过多次尝试,最终成功再现了“买一个压根没上架的游戏并购买内购”。原来这个过程不需要任何超出普通用户权限的操作,完全在苹果的规则下便能实现:以下是再现过程:1、你需要注册一个中国区的 Apple ID,这里一切如常,略过不表。2、使用这个 ID,下载你打算用南非兰特充值的游戏,登录游戏,这里我们的测试对象是腾讯的《全民英雄》。3、退出游戏,在 iOS 的设置选项,或在 PC 端的 iTunes 和 iCloud 里更改账号的所属地区。4、以 PC 端的 iCloud 为例,打开 iCloud 程序,登录你刚注册的国服 ID,你会看到以下界面:5、依次点击“管理”“查看账户”,你会看到如下界面:6、更改国家,选择南非,按规则填信息,成功如下,国家已变为南非:7、打开你的 iOS 设备,进入 App Store,会很快收到如下信息,说明该 Apple ID 只适用于在南非区购买商品,点击确认跳转到南非 App Store。8、打开上文提到的游戏《全民英雄》,角色、服务器等都保持原样,进入商店,发现内购仍以人民币显示。但这些都无关紧要,直接点击购买。我们可购买一个 6 元人民币的道具进行测试,按照当前的国际汇率,6 元人民币相当于 10.41 南非兰特,但实际成交价只有 7.99 兰特,相当于打了 7.6 折,如下图:注意:你无法使用 VISA 之类的信用卡直接支付,否则系统会报错,必须先使用南非的 Gift Card 为 Apple ID 充值,然后再购买内购。如下图,交易成功。至于前文提到的淘宝 648 块钱的内购只卖 460 多块,相当于 7.1 折。和上文的 7.6 折对比,看似成交价比直接汇率价都低。但需要注意的是,在中国价值 648 元的内购,到了南非只有 799 兰特,换算***民币是 455 元,就算内购倒爷只卖 460 元人民币也有足够获利空间。在上述再现的过程中,存在两个难点,导致这个漏洞被埋没了相当长的时间,成为一个商业秘密只流传于“内购倒爷”之间:1、“切换账号所属国家”是个较隐蔽的功能,且有诸多不便(比如你得用光所有余额),用户一般情愿重新申请一个账号。2、即使切换到南非,在使用信用卡支付的时候依然会报错。一般人即便尝试,到这一步也基本放弃,很少有人想到可以用 Gift Card 充值后再购买。如今,这个产业链的规模仍然在扩大,产业链的上下游正在逐渐完善。目前在淘宝输入“南非 Gift Card”,可以找到超过 213 件商品。在这些商品中,销量最高的是价值为 4500 兰特的 Gift Card。在排名前列的一家店铺中,按照当前汇率售价为 2600 人民币、实际价值 4500 兰特的南非区 Gift Card,在近 30 天内销量超过 500 张,历史总销量超过 2000 张。且大部分购买者均会一次购买 3 张甚至 20 张,其中不乏一些“XXX 工作室的”的买家,这个灰色产业无疑会吸引越来越多的投机者入驻。最后,触乐网关注此话题,并不是为了传播具体的投机方法,虽然我们知道一定会有无数用户去尝试----这无疑是一个短期的坏事,却是长远的好事。将阴暗敞开,阳光才会照下,苹果或许才会有所重视,进而优化他们的 App Store 付费规则吧。一波传奇巨星相继退役,科比、邓肯的离去,让如今的NBA赛场少了一份当年的滋味,当另...
科技界如今的趋势是朝着网络化服务化发展,然而那么些年过去了,苹果的云服务却依然没...
Apple在iOS生态上面临的主要问题是:大部分开发者无法持续性赚钱。
登陆更多市场之后,现在就看iPhone 7的后续供货能不能跟上了。
因为收购过来的话苹果就又多了难以和现有产品线整合的一项业务。
在Note 7爆炸后的一个月多里,三星电子不断举行内部会议,员工们也牺牲了自己的假期,...
眼下,美国联邦航空管理局(FAA)和消费品安全委员会正在就周三的事故进行调查。
虽然旧款 Nexus 设备也能够升级到 Android 7.1 Nougat 操作系统,但是新系统的一些特...
《粉碎之战(Smashing The Battle)》是由Studio HG制作发行的一款动作游戏,该作背景...
《动物方层树》这样的游戏名字一下子让人丈二和尚摸不着头脑,小编和不少玩家一样,根...
游戏在画面上虽然没有采用像素风格的设计,但是整体给人感觉还是非常复古的,颇有一种...
在上周四的App Store国服照例更新当中,网易上架了旗下全新的二次元动作手游《异次元...
《点点邪恶帝国》是一款非常典型的点击放置类游戏,简单的玩法和轻松的画风是它的闪光...
《那兔之大国梦》是《那年那兔那些事儿》改编的第二款手游,在经历第一款手游的“失败...
《小轮车冒险》(Pumped BMX)是独立游戏开发团队 Yeah Us! 手中的金字招牌,目前已经...
现在我们需要关心的是取消3.5毫米耳机接口之后,苹果如何创建新的用户体验。
看了这亮黑三件套之后,你是否也有为其它苹果产品染上亮黑色的冲动呢?
不过从价格上来看,似乎有点性价比略低,而且目前可供选择的配件少得可怜~
因为 iPhone 7 只有一个 Lightning 接口,因此充电线缆和 EarPods 很难同时使用。
看过用了 W1 芯片的 Beats Solo 评测之后更加期待 AirPods 了!
苹果在新款 iPhone 7 系列手机中取消了传统的 3.5mm 耳机插孔,但是仍有不少苹果粉丝...
虽然 iPhone 本身也可以通过应用进行录音,但是很多需要录音的时刻并不会等着我们打开...
相信随着智能家居渐渐走入更多人的家庭里,肯定会有更多设备支持HomeKit。
游戏内购钱扣去了,东西没收到,查不到购买记录怎么办?
注册时间 最后登录
在线时间89 小时 UID
主题帖子人气
白苹果, 积分 697, 距离下一级还需 803 积分
游戏内购钱扣去了,东西没收到,查不到购买记录怎么办?购买由于忘记关内购插件,钱扣去了东西没收到,在itunes在查不到购买记录,怎么办??
刚才打了苹果***说没有订单编号前退不了,还说等下也许订单编号会出来!!!!!!
注册时间 最后登录
在线时间89 小时 UID
主题帖子人气
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!一波传奇巨星相继退役,科比、邓肯的离去,让如今的NBA赛场少了一份当年的滋味,当另...
科技界如今的趋势是朝着网络化服务化发展,然而那么些年过去了,苹果的云服务却依然没...
Apple在iOS生态上面临的主要问题是:大部分开发者无法持续性赚钱。
登陆更多市场之后,现在就看iPhone 7的后续供货能不能跟上了。
因为收购过来的话苹果就又多了难以和现有产品线整合的一项业务。
在Note 7爆炸后的一个月多里,三星电子不断举行内部会议,员工们也牺牲了自己的假期,...
眼下,美国联邦航空管理局(FAA)和消费品安全委员会正在就周三的事故进行调查。
虽然旧款 Nexus 设备也能够升级到 Android 7.1 Nougat 操作系统,但是新系统的一些特...
《粉碎之战(Smashing The Battle)》是由Studio HG制作发行的一款动作游戏,该作背景...
《动物方层树》这样的游戏名字一下子让人丈二和尚摸不着头脑,小编和不少玩家一样,根...
游戏在画面上虽然没有采用像素风格的设计,但是整体给人感觉还是非常复古的,颇有一种...
在上周四的App Store国服照例更新当中,网易上架了旗下全新的二次元动作手游《异次元...
《点点邪恶帝国》是一款非常典型的点击放置类游戏,简单的玩法和轻松的画风是它的闪光...
《那兔之大国梦》是《那年那兔那些事儿》改编的第二款手游,在经历第一款手游的“失败...
《小轮车冒险》(Pumped BMX)是独立游戏开发团队 Yeah Us! 手中的金字招牌,目前已经...
现在我们需要关心的是取消3.5毫米耳机接口之后,苹果如何创建新的用户体验。
看了这亮黑三件套之后,你是否也有为其它苹果产品染上亮黑色的冲动呢?
不过从价格上来看,似乎有点性价比略低,而且目前可供选择的配件少得可怜~
因为 iPhone 7 只有一个 Lightning 接口,因此充电线缆和 EarPods 很难同时使用。
看过用了 W1 芯片的 Beats Solo 评测之后更加期待 AirPods 了!
苹果在新款 iPhone 7 系列手机中取消了传统的 3.5mm 耳机插孔,但是仍有不少苹果粉丝...
虽然 iPhone 本身也可以通过应用进行录音,但是很多需要录音的时刻并不会等着我们打开...
相信随着智能家居渐渐走入更多人的家庭里,肯定会有更多设备支持HomeKit。
****购买金币问题
注册时间 最后登录
在线时间25 小时 UID
主题帖子人气
小苹果, 积分 11, 距离下一级还需 39 积分
我在7月12日晚上,****上内购了18元的金币。到现在还没有到,并且扣了我的钱。现在我该找谁去要我的金币或钱
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
注册时间 最后登录
在线时间0 小时 UID
主题帖子人气
提示: 作者被禁止或删除 内容自动屏蔽
威锋旗下产品
Hi~我是威威!
沪公网安备 29号 | 沪ICP备号-1
新三板上市公司威锋科技(836555)
增值电信业务经营许可证:
Powered by Discuz!苹果id有钱为什么提示购买无法完成_百度知道iOS Apple内购及掉单问题 - 简书
下载简书移动应用
写了2216字,被10人关注,获得了14个喜欢
iOS Apple内购及掉单问题
在iOS开发中你是否遇到过购买虚拟物品的而无法使用第三方支付的问题,让不熟悉Apple内购的你不知所措,废话不多说,直接搞起。
第一部分:协议
第10步.png
CNAPS CODE 查询地址
第11步.jpg
第12步.jpg
第13步.png
第14步.png
第15步.jpg
第16步.jpg
第17步.png
第18步.png
协议Done,我们现在已经和Apple签订了协议,接下来该去上架商品了
第二部分:创建内购项目
Apple内购的价格是等级制的,无法自己随意定价,而且每比订单成交都要向苹果缴纳百分之30的抽成,坑爹吧!!
第三部分:App代码集成
介绍一下APP内购的步骤:
一般的内购分为两种,一种是我们app有自己的服务器,一种是本地的,像我们玩的闯关游戏需要购买关卡一般都是本地的,像那种联网手游,会员VIP的基本都是服务器的。
服务器模式:1.调用服务器接口创建一个商品的订单2.请求Apple的商品列表3.选取商品调用苹果支付4.支付成功(会返回凭证)5.把支付成功的返回凭证上传到APP服务器(带上订单的ID,有利于后台判断是哪个订单支付成功)6.APP服务器保存该凭证等数据并像苹果服务器发起凭证验证,验证成功则发送商品
本地模式:1.请求Apple的商品列表2.选取商品调用苹果支付3.支付成功(会返回凭证)4.把凭证与商品发送状态保存到一个本地的数据库5.app调用apple服务器的验证API6.验证成功发送商品并改变数据库的物品发送状态
最后一步了,是不是有些欣喜,最后在代码中实现
首先导入StoreKit.framework库
#import "ApplePayVC.h"
#import &StoreKit/StoreKit.h&
//在内购项目中创的商品单号,从itunesConnect里可以看到
#define ProductID_1 @"product1"
#define ProductID_2 @"product2"
#define ProductID_3 @"product3"
#define ProductID_4 @"product4"
#define ProductID_5 @"product5"
@interface ApplePayVC ()
NSString *buyProductId;
@implementation ApplePayVC
- (void)viewDidLoad {
[super viewDidLoad];
[[SKPaymentQueue defaultQueue] addTransactionObserver:self];
[self buyProduct:ProductID_1];
-(void)buyProduct:(NSString *)productId
buyProductId = productId;
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 = [[NSArray alloc] initWithObjects:buyProductId,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 = [SKPayment paymentWithProductIdentifier:buyProductId];
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];//解除***
我们已经完成了内购的付款操作了,至于如何给到用户商品就在
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions
这个代理方法里面就行操作
你以为这样就完成了么?那你就惨了,APP上线以后你就会发现各种掉单问题,那时你心中肯定有10000只草泥马在奔腾,接下来我们来看看如何避免掉单。
附:解决掉单篇
我们先来看看有哪些请况会发生掉单:
①. 在ApplePay付款成功后由于网络或各种原因没有返回Transaction(SKPaymentTransaction),从而不能得到凭证去Apple服务器验证订单的正确性。②.苹果服务器成功返回了Transaction,但是在APP在上传凭证给服务器时发生了网络或各种原因,造成了凭证的丢失,产生了掉单(用户付了款却没有得到相应的商品)
[SKPaymentQueue defaultQueue]这个队列里面存着所有的已支付,未支付的订单,而且需要手动移除,而APP每次启动的时候都会去判断这个队列里面是否为空,如果不为空的话会调用&SKPaymentTransactionObserver&代理的
- (void)paymentQueue:(SKPaymentQueue *)queue updatedTransactions:(NSArray *)transactions//交易结果
所以我们可以把AppDelegate设置成这个协议的代理并实现这个方法,当然我一般是会写一个遵循&SKPaymentTransactionObserver&的工具类单例,毕竟协议是一对一的,不管是哪里的支付回调,都只走这个类,统一处理。
上面我们说到每次APP启动时都会判断订单队列是否为空,而且队列需要手动移除,所以我们可以在确保商品已经成功发放到用户手中再做移除操作,这样就完美了。
移除代码如下:
[[SKPaymentQueue defaultQueue] finishTransaction: transaction];
iOS 7.0后 我们是用[[NSBundle mainBundle] appStoreReceiptURL]来获取凭证。
注:苹果官方内购验证文档
到这里可能有些童鞋会懵逼了,他会说我付款后怎么和订单关联上啊,完全没有区分的地方啊!解决办法如下:当我们创建苹果订单初始化SKPayment时我们应该使用SKMutablePayment,这个类里面有一个参数叫applicationUsername的成员变量,我们可以把后台服务器的订单号写到这里,在付款成功后返回的SKPaymentTransaction里面能拿到这个参数,然后就带着它去请求本地服务器.
我们把内购搭建好直接进行测试,会提示你购买失败对吧?内购测试我们要到iTunes connection 里去添加沙盒测试员
然后我们测试的时候换上这个appleId就能进行测试了
perfect!!!!!!哈哈,第一次写技术博客可能写得不好,猿媛们哪里不明白可以在下面提问!!!
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
? 6939人关注
开发者加入开发者讨论群!
? 2373人关注
搜集ios开发的精华内容,欢迎投稿分享
? 10人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:

参考资料

 

随机推荐