- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我发现 iOS7 收据的 base64 编码存在一些非常奇怪的问题。
目前(Xcode5/iOS7)有两种获取应用内购买收据的方法:
[SKPaymentTransaction transactionReceipt]
appStoreReceiptURL
的所有收据的 bundle My App 使用信用系统销售基于网站的服务,这使得服务器收据验证成为必要。该应用程序还出售可下载的扩展程序。所以是消耗品和非消耗品的混合物。非消耗品是从 Apple 下载的,因此无需验证。消耗品是用于在网站上购买服务的积分包。
当 iOS7 和 XCode5 启动时,我更新了我的应用程序,但遇到位于 appStoreReceiptURL 的新捆绑收据。使用新样式,将所有收据捆绑在一起,我的服务器从 Apple 的 verifyReceipt 沙箱中返回此错误
[status] => 21002
[exception] => java.lang.IllegalArgumentException
在看到 stackoverflow 上的帖子说其他人也遇到过同样的问题并且当时的意见是这是一个错误或尚未添加的功能后,我放弃了。但是,我一直看到使用旧的已弃用方法的问题,这迫使我重新尝试。经过大量的调试和搜索,我终于找出了一些问题所在 - 并使其正常工作,但以一种非常丑陋的方式,我没有信心接受它。
我原以为 NSData(纯字节缓冲区)编码输出不会有太大差异。这是我看到的奇怪部分。
原始弃用的单张收据可以 base64 编码为 64 个字符行,末尾有\r\n 或没有。苹果验证服务器不关心。无论哪种方式都很开心。
对于新的收据包,除非完成两件事,否则它将无法工作。首先base64编码不能有换行符。我注意到 Apple 已将其自己的 base64 编码器添加到 iOS7 中。这就是我用来获取适用于两种收据类型的编码输出的方法。
NSString *receiptDataString = [transactionReceipt base64EncodedStringWithOptions:0];
需要做的第二件事是从服务器上收到的编码收据包中搜索并替换所有空格字符。即
$receiptdata = str_replace(' ', '+', $receiptdata);
我碰巧注意到这是我的服务器收到的收据之间的差异。为什么我不知道?我正在使用 AFNetworking-1.3.2 的 JSONRequestOperationWithRequest
NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
for (NSString *key in parameters) {
[pairs addObject:[NSString stringWithFormat:@"%@=%@", key, [parameters objectForKey:key]]];
}
postData = [[pairs componentsJoinedByString:@"&"] dataUsingEncoding:NSUTF8StringEncoding];
request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://myserver.com/index.php"]];
[request setHTTPMethod:@"POST"];
[request setValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded charset=utf-8" forHTTPHeaderField:@"Content-Type"];
[request setHTTPBody:postData];
operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request
Chris Prince 在他对 this question 的回复中声称它与 AFNetworking 2 一起工作
为什么这两个 NSData 收据会导致像我看到的那样的编码/解码问题?我已经尽可能详细和清楚地在这里帮助其他人,因为我看到很多人在这里对 Apple 推出的这种新收据方法感到同样的痛苦。
最佳答案
答案原来是由于
stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding
不转义所有特殊字符,如 :/?#[]@!$&'()*+,;= 等。Apple 提供的新收据经过 base64 编码后,包含需要转义但未被上述 iOS lib 转义编码器转义的字符。环顾四周,我在这里找到了一个效果很好的。请参阅下面的工作代码。 (服务器现在不需要解析收据代码,可以直接从 $_POST 中使用它)
// Lifted from:
// http://stackoverflow.com/questions/2159341/nsstring-method-to-percent-escape-for-url
//
- (NSString *)urlEncodeValue:(NSString *)str {
NSString *result = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)str, NULL, CFSTR(":/?#[]@!$&’()*+,;="), kCFStringEncodingUTF8));
return result;
}
// Encode and pair basic parameters
NSMutableArray *pairs = [[NSMutableArray alloc] initWithCapacity:0];
NSString *part;
for (NSString *key in parameters) {
NSString *encodedValue = [[parameters objectForKey:key] stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *encodedKey = [key stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
[pairs addObject:part];
[pairs addObject:[NSString stringWithFormat:@"%@=%@", key, [parameters objectForKey:key]]];
}
// Receipt encoded and paired separately
receiptDataString = [self urlEncodeValue:receiptDataString];
part = [NSString stringWithFormat: @"receipt=%@", receiptDataString];
[pairs addObject:part];
// Post data.
postData = [[pairs componentsJoinedByString:@"&"] dataUsingEncoding:NSUTF8StringEncoding];
关于objective-c - iOS7 应用内购买回执服务器验证的 Base64 编码怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20869828/
关闭。这个问题是opinion-based .它目前不接受答案。 想改善这个问题吗?更新问题,以便可以通过 editing this post 用事实和引文回答问题. 6年前关闭。 Improve t
我们有一个专有的销售系统,我们已经使用了一段时间了。最近我们添加了“购买”方面,以便我们可以比较匹配产品的平均购买/销售价格以及查看库存状况。 在 MySQL 中,我有 2 个表:tblPurchas
在查看 Paypal 文档以寻找针对这种情况的解决方案后,我一头雾水。我想要的是一种让购物车订阅(定期付款)和购买商品的方法。有没有一种方法可以解决这个问题,或者我是否必须做一些自定义的事情(如果我使
我想知道是否可以使用youtube api获取可购买或可租借的电影列表。当我转到youtube网站并登录到Google帐户时,我可以看到要购买的电影及其价格。 我想在我的应用程序(http://www
我使用 JavaScript 购买 SDK 和 Node.js。 const fetch = require('node-fetch'); const shopify = require('shopi
我购买了三个不同期限的不同订阅。我已经配置了测试账户,我可以进行测试购买。对于这些购买,谷歌不向我收费,但它们看起来非常像真实的。购买成功后,应用内结算会向我发送一些有关我的购买的数据,例如 pack
我目前正在实现应用内购买,并且刚刚阅读了一些帖子,说需要恢复购买按钮,否则苹果将拒绝应用。 我不想在我的 UI 设计中添加第二个按钮。 所以我的问题是... 有没有办法检查用户之前是否进行过应用内购买
我的应用中有多个项目。我有两个设备。如果我在这些设备中的第一个上购买商品,然后尝试在另一个设备上购买相同的商品,我不能。(Google play intent 显示消息 - 商品已拥有!然后它崩溃了.
有没有办法检测何时通过应用商店为您的应用进行了购买? 检测应用内购买似乎很容易(即我们的服务器可以收到通知),但是对于直接购买有没有办法做到这一点? 如果没有,是否有一些用户的唯一标识符(例如购买时通
就目前而言,这个问题不适合我们的问答形式。我们希望答案得到事实、引用或专业知识的支持,但这个问题可能会引起辩论、争论、投票或扩展讨论。如果您觉得这个问题可以改进并可能重新打开,visit the he
我计划在用户使用该应用程序成功扫描二维码时为应用内购买提供折扣。我知道无法为现有商品提供折扣。我打算以折扣价添加另一件商品。有没有人以前有过使用这种方法的经验? 提前致谢 最佳答案 没有办法直接这样做
我很好奇其他商店在基础应用程序框架方面做了什么?我将应用程序框架视为能够提供额外或扩展的功能以提高基于它构建的应用程序的质量。 有各种开箱即用的框架,例如 Spring(或 Spring.NET)等。
我们正在开发一款使用非续订订阅 IAP 模型的应用。在沙盒中测试订阅购买流程时,我们看到弹出两 strip 有“购买”按钮的消息。 显示第一条消息和产品信息:“您想以 xx.xx 美元购买一个订阅吗?
我的老板购买了 Microsoft 365,它包含三种产品。他现在要求我设计一个管理系统,比如员工自助服务门户。我特此寻求有关从哪里开始或使用哪种产品的建议,因为我对此很陌生。 我尝试了一些研究,发现
我的老板购买了 Microsoft 365,它包含三种产品。他现在要求我设计一个管理系统,比如员工自助服务门户。我特此寻求有关从哪里开始或使用哪种产品的建议,因为我对此很陌生。 我尝试了一些研究,发现
我刚刚了解了IAP Cracker的存在,并试图找出在我的应用中验证IAP购买的最佳方法。 我无法确定的是IAP Cracker是否可以处理“消耗性”商品。如果没有,我没有什么可担心的。 这是维护/验
我正在编写一个允许应用内购买的简单应用。我已经使用 SKU 代码 android.test.purchased 进行了测试,一切正常。 我进入我的 google play 控制台,创建了一个应用程序,
我即将启动一个应用程序,该应用程序将包含多个“应用程序内购买”。 我想做的是有一种方法可以提供少量免费的“应用内购买”来选择评论家等人。 在 apple 框架内有没有办法做到这一点,如果没有,我可以采
所以我在这个网站上工作,用户可以在该网站上发布他们的商品,其他用户可以将一些商品添加到他们的购物车并在线购买。 我考虑的流程是这样的: 商家发布商品及其信用卡/ Paypal 信息。 买家将(来自不同
我对这个主题进行了广泛的研究,但我的知识仍然很模糊。我正在寻找一个简单站点的基本 DV,但我看到每个在线 SSL 都具有三个级别, Root->Intermidiate (充当 Root 的代理)和我
我是一名优秀的程序员,十分优秀!