我在应用程序购买中玩了几天,直到我尝试在应用程序商店验证收据之前一切正常,因为我一直在找回无效状态。
我将收据数据传递到我的PHP服务器,然后从那里转发到应用商店,一旦收到有效的响应,我打算将收据数据添加到我的数据库中。
商店工具包编程指南和类引用对于这个特定领域并没有什么用,因为它们并没有真正给您提供任何示例,我确实找到了一篇有用的文章,对我有所帮助,但是仍然有些错误。
基本上,我想知道是否有人在进行收据验证工作,是否愿意在我无处可去的情况下共享他们的代码。
谢谢
首先,发布的代码中有一些错别字。尝试这个。(免责声明:重构等人留给读者练习!)
- (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 消息的类上创建以下Internal方法:
@interface YourStoreClass (Internal) - (BOOL)verifyReceipt:(SKPaymentTransaction *)transaction; - (NSString *)encode:(const uint8_t *)input length:(NSInteger)length; @end
注意:您 可以 使用 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- 是您最喜欢的HTTP发布机制。( cURL 是一种可能的选择。YMMV。PHP.net对此有好处!)
我有点担心的一件事是从应用程序到服务器(通过GET)的URL中有效负载的长度。我忘了每个RFC是否存在长度问题。可能还可以,或者特定于服务器。(读者:欢迎您提出建议!)
使这个同步请求也可能有些懈怠。您可能要异步发布它,并放上 UIActivityIndicatorView 或其他HUD。例子: initWithData:encoding: 调用对我来说耗时很长。几秒钟,这在iPhone领域(或与此有关的其他任何地方)是永恒的。建议显示某种不确定的进度指示器。