应用内购买收据验证

13

我想在我的应用程序中验证交易收据,

这是我的代码,

- (void)recordTransaction:(SKPaymentTransaction *)transaction {

    NSData *receiptData = [NSData dataWithData:transaction.transactionReceipt];

    NSString *encodedString = [Base64 encode:receiptData];

     NSURL *url = [NSURL URLWithString:@"https://sandbox.itunes.apple.com/verifyReceipt"];

    ASIFormDataRequest *request = [[ASIFormDataRequest alloc] initWithURL:url];

    [request setPostValue:encodedString forKey:@"receipt-data"];

    [request setRequestMethod:@"POST"];

    [request setDelegate:self];

    [request startAsynchronous];

}

我的输出结果是:

{"status":21002, "exception":"java.lang.NullPointerException"}

有人能帮我正确地进行收据验证吗?

4个回答

27

以下翻译供有需要的人参考。我注意到苹果公司已经更新了应用内购买指南,其中包含了一些状态码,这些状态码是针对自动续订订阅购买的,但似乎也适用于此处。

  • 21000 应用商店无法读取您提供的 JSON 对象。
  • 21002 receipt-data 属性中的数据格式不正确。
  • 21003 无法验证收据。
  • 21004 您提供的共享密钥与帐户文件中的共享密钥不匹配。
  • 21005 收据服务器目前不可用。
  • 21006 此收据有效,但订阅已过期。当将此状态代码返回到您的服务器时,收据数据也会被解码并作为响应的一部分返回。
  • 21007 这是一个沙盒收据,但却被发送到生产服务进行验证。
  • 21008 这是一个生产收据,但却被发送到沙盒服务进行验证。

重要提示:这里的非零状态码仅适用于恢复有关自动续订订阅的信息。在测试其他类型产品的响应时,请不要使用这些状态码。(真的吗?)

希望这能成为一个参考。我遇到了21007的问题。

状态码列表在苹果公司的网站上:https://developer.apple.com/library/ios/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html


这些状态的来源可以链接吗?谢谢。 - Stunner

10

尝试了多次后,我决定从服务器端进行收据验证。实际上这是推荐的方式。

以下是我的代码:

-(void)recordTransaction:(SKPaymentTransaction *)transaction {   

NSString* receiptString = [[[NSString alloc] initWithData:transaction.transactionReceipt encoding:NSUTF8StringEncoding] autorelease];

// POST this string to your server

// I used ASIFormDataRequest 

}

// server side 

$url = 'https://sandbox.itunes.apple.com/verifyReceipt';

// encode the receipt data received from application

$purchase_encoded = base64_encode( $purchase_receipt );

//Create JSON

    $encodedData = json_encode( Array( 
        'receipt-data' => $purchase_encoded 
    ) );


// POST data

    //Open a Connection using POST method, as it is required to use POST method.
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $encodedData);
    $encodedResponse = curl_exec($ch);
    curl_close($ch);


  //Decode response data using json_decode method to get an object.

      $response = json_decode( $encodedResponse );


// check response

if ($response->{'status'} != 0)

    // Invalid receipt

else

   // valid reciept
我找到了一些帮助, http://gamesfromwithin.com/in-app-purchases-part-3

文档中没有说明transactionReceipt可以解释为UTF-8编码的字符串。 - user102008

4

如果您没有发出请求,那么您的响应将为 null!这是因为您尚未发出请求。

您可以添加一个 [request startSynchronous] 调用(这通常是一个不好的想法,您应该始终异步运行网络调用),或者更好的方法是重写代码以支持异步网络调用,并使用 [request startAsynchronous]

如果需要更多信息,建议查看 ASI 文档: http://allseeing-i.com/ASIHTTPRequest/How-to-use


1
如果Objective-C代码没有执行请求,为什么会出现Java错误? - chilitechno.com
2
自从我发布了这个答案以后,问题已经被编辑过了。最初没有startAsynchronous调用,也没有Java错误。现在添加了这个调用,但还是有其他问题。 - lxt

-2
从以下参考中我了解到,您的应用程序需要使用单独的服务器来“验证商店收据”。我认为,对于收据验证,我们需要使用来自静态IP的请求。
谢谢, 参考

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接