Проверьте получение для в покупке Приложения

Если можно принять решение использовать базу данных, я рекомендую использовать PostgreSQL и нечеткие функции сопоставления строк .

, Если можно использовать Ruby, я предлагаю изучить amatch библиотека .

40
задан bitek 1 February 2013 в 13:21
поделиться

2 ответа

Во-первых, в опубликованном коде есть несколько опечаток. Попробуй это. (Отказ от ответственности: рефакторинг и др. Оставлен в качестве упражнения для читателей!)

- (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 - ваш любимый механизм HTTP-сообщений. ( cURL - один из возможных вариантов. YMMV. У PHP.net есть сенсация!)

Одна вещь, которая меня немного обеспокоила, - это длина полезной нагрузки в URL, идущей от приложения к серверу ( через GET). Я забываю, есть ли там проблема с длиной в RFC. Может быть, это нормально, а может, это зависит от сервера. (Читатели: Совет приветствую в этой части!)

Также могут возникнуть некоторые возражения против того, чтобы сделать это синхронным запросом. Вы можете разместить его асинхронно и установить старый UIActivityIndicatorView или какой-нибудь другой HUD. Показательный пример: вызов initWithData: encoding: занимает у меня очень много времени. Несколько секунд, а это небольшая вечность для iPhone (или где-то еще в Интернете, если на то пошло).

70
ответ дан 27 November 2019 в 01:30
поделиться

Просто чтобы снова открыть это и добавить мои 2 цента в обмен на поиск информации в этих формах.

Я только что установил IAP-сервис в своем приложении и обнаружил ту же ошибку 21002. Я обнаружил, что 21002 происходит, когда сообщение на вашем PHP-сервере пусто (таким образом, HTTP-запрос в магазин приложений пуст) или неправильно отформатирован. Чтобы заставить наши работать, на стороне iPhone мы устанавливаем данные публикации в NSString как закодированные в base64, а затем отправляем их на наш сервер в виде HTTP-запроса.

Затем на нашем сервере мы вставили его в массив и обработали json. Примерно так:

$receipt = json_encode(array("receipt-data"=>$_POST['receipt-data']));

Вы заметите, что это то же самое, что и выше, за исключением того, что мы используем POST вместо GET. На самом деле личные предпочтения.

Затем мы использовали CURL, чтобы отправить его в песочницу, и использовали json_decode в ответе.

0
ответ дан 27 November 2019 в 01:30
поделиться