我已经玩了几天的应用内购买,在我try 用应用store 验证收据之前,一切都很正常,因为我一直在恢复无效状态.

我将收据数据传递到我的PHP服务器,然后从那里转发到应用store ,一旦得到有效响应,我打算将收据数据添加到我的数据库中.

store 工具包编程指南和类引用对于这个特定的领域来说并没有什么用处,因为它们并没有给你任何类型的例子,我确实找到了一个有用的article,这对我有点帮助,但仍然有一些问题.

基本上,我想知道是否有人谁有收据验证工作愿意分享他们的代码,因为我一无所获.

谢谢

推荐答案

首先,发布的代码中有一些拼写错误.试试这个.(免责声明:重构等是留给读者的练习!)

- (BOOL)verifyReceipt:(SKPaymentTransaction *)transaction {
    NSString *jsonObjectString = [self encode:(uint8_t *)transaction.transactionReceipt.bytes length:transaction.transactionReceipt.length];      
    NSString *completeString = [NSString stringWithFormat:@"http://url-for-your-php?receipt=%@", jsonObjectString];               
    NSURL *urlForValidation = [NSURL URLWithString:completeString];       
    NSMutableURLRequest *validationRequest = [[NSMutableURLRequest alloc] initWithURL:urlForValidation];              
    [validationRequest setHTTPMethod:@"GET"];         
    NSData *responseData = [NSURLConnection sendSynchronousRequest:validationRequest returningResponse:nil error:nil];  
    [validationRequest release];
    NSString *responseString = [[NSString alloc] initWithData:responseData encoding: NSUTF8StringEncoding];
    NSInteger response = [responseString integerValue];
    [responseString release];
    return (response == 0);
}

- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length {
    static char table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    NSMutableData *data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t *output = (uint8_t *)data.mutableBytes;

    for (NSInteger i = 0; i < length; i += 3) {
        NSInteger value = 0;
        for (NSInteger j = i; j < (i + 3); j++) {
            value <<= 8;

            if (j < length) {
                value |= (0xFF & input[j]);
            }
        }

        NSInteger index = (i / 3) * 4;
        output[index + 0] =                    table[(value >> 18) & 0x3F];
        output[index + 1] =                    table[(value >> 12) & 0x3F];
        output[index + 2] = (i + 1) < length ? table[(value >> 6)  & 0x3F] : '=';
        output[index + 3] = (i + 2) < length ? table[(value >> 0)  & 0x3F] : '=';
    }

    return [[[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding] autorelease];
}

您可以在处理SKPaymentTransactionObserver条消息的类上创建以下内部方法:

@interface YourStoreClass (Internal)
- (BOOL)verifyReceipt:(SKPaymentTransaction *)transaction;
- (NSString *)encode:(const uint8_t *)input length:(NSInteger)length;
@end

注意:您could使用libcrypto之类的值来处理base64编码,但在应用程序批准时,您会看到导出限制和额外的步骤.但我离题了...

然后,无论您打算在远程服务器上开始记录事务,都要用您的事务拨打verifyReceipt:,并确保它返回正数.

同时,在你的服务器上,这里有一些超级精简的PHP来处理事情:

$receipt = json_encode(array("receipt-data" => $_GET["receipt"]));
// NOTE: use "buy" vs "sandbox" in production.
$url = "https://sandbox.itunes.apple.com/verifyReceipt";
$response_json = call-your-http-post-here($url, $receipt);
$response = json_decode($response_json);

// Save the data here!

echo $response->status;

其中call-your-http-post-here是您最喜欢的HTTP post机制.(cURL是一个可能的 Select .YMMV.PHP.net有独家新闻!)

有一件事让我有点担心,那就是URL中从应用程序到服务器的有效负载长度(通过GET).我忘了根据RFC是否有长度问题.也许没关系,或者可能是特定于服务器的.(读者:欢迎提供这方面的建议!)

在提出同步请求时,也可能会有一些犹豫.你可能想异步发布它,然后安装ol'UIActivityIndicatorView或其他HUD.举个例子:initWithData:encoding:电话对我来说花了很长时间.几秒钟,这在iPhone领域(或其他任何在线领域)是一个小小的永恒.显示某种不确定的进度指标可能是可取的.

Objective-c相关问答推荐

目标 C:什么是(id)发件人?

将 NSMutableAttributedString 转换为 NSString

如何检测 iPhone 5c 的 colored颜色 ?

Objective-C:在字符串中查找数字

如何更改图像中的特定 colored颜色 ?

检测 NSString 的语言

当前时间是 HH:MM:SS am/pm 格式吗?

NSView 的边界与框架

dispatch_semaphore_dispose 上的 EXC_BAD_INSTRUCTION(代码=EXC_I386_INVOP,子代码=0x0)

Select 时如何更改 UITableViewCell 的 colored颜色 ?

在 ios8 中没有调用 didRegisterForRemoteNotificationsWithDeviceToken,但是 didRegister...Settings 是

了解 performSegueWithIdentifier

强制iphone应用程序以编程方式重新启动?

从 iPhone 设备查找当前国家

如何将 NSOperationQueue 与 NSURLSession 一起使用?

Xcode 7 警告:目标文件是为比链接更新的 iOS 版本构建的

允许用户从 UILabel 中 Select 文本进行复制

UITableView 在半透明的导航栏下

公开只读但具有私有设置器的 Objective-C 属性

UITableViewCell中的文本居中对齐问题