まず、投稿されたコードにいくつかのタイプミスがあります。これを試して。(免責事項:リファクタリングなどは読者の練習問題として残されています!)
- (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
注: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は、お気に入りのHTTPPOSTメカニズムです。(cURLは1つの可能な選択肢です。YMMV。PHP.netにはスクープがあります!)
私が少し心配していることの1つは、アプリからサーバーに(GET経由で)行くURLのペイロードの長さです。RFCごとに長さの問題があるかどうかを忘れています。多分それは大丈夫かもしれません、あるいは多分それはサーバー固有です。(読者:この部分についてのアドバイスを歓迎します!)
また、これを同期要求にすることには多少の不満があるかもしれません。非同期で投稿して、古いUIActivityIndicatorViewまたはその他のHUDを設定することをお勧めします。適切な例:そのinitWithData:encoding:呼び出しは私にとって非常に時間がかかります。数秒。これはiPhoneの世界(またはオンラインの他の場所)では小さな永遠です。ある種の不確定な進行状況インジケーターを表示することをお勧めします。