Проблемы с подтверждением получения покупки в AppStore - PullRequest
8 голосов
/ 09 марта 2011

Я знаю, что на эту тему было довольно много сообщений, но, похоже, ни одна из них не касается проблем, с которыми мы сталкиваемся. До сих пор я думаю, что у меня все настроено правильно, как указано в документации по хранилищу справочной библиотеки iOS 1002 *. Однако мы получаем 21002 «java.lang.NullPointerException» во время нашего POST-запроса к URL-адресу подтверждения AppStore, поэтому я должен что-то делать не так.

Некоторые проблемы, которые я заметил, могут быть причиной этого:

1) СКОРОСТЬ ПОЛУЧЕНИЯ

В документации указано, что наше приложение для iPhone должно передавать только квитанцию ​​на наш сервер для проверки, но не указывается, что именно является квитанцией. Сначала я подумал, что это может быть весь объект JSON ниже, но теперь мне интересно, является ли квитанция только полем «информация о покупке».

Encoded Receipt
ewoJInNpZ25hdHVyZSIgPSAiQWx1SFVsb0dxejZjOVNvSlFVejF0OThhemI2WjJCb2N3WVBhK2ZVYllmdUI5ZE5RQkViV2dTNXVIUUluakdSQ2RScVkxUHhQY2cvMk1kSVlONEN2anc0RkNuc0JqT0d2NGFqNjVBczQ2SERseGd4WjdlTElGUXcrcG9QVlpTZHlEWWF6NHBPaGxxNVBmVXNqdmlZNENYd3VaQzkrSTBHdk55bVZWNkhnR2FCRUFBQURWekNDQTFNd2dnSTdvQU1DQVFJQ0NHVVVrVTNaV0FTMU1BMEdDU3FHU0liM0RRRUJCUVVBTUg4eEN6QUpCZ05WQkFZVEFsVlRNUk13RVFZRFZRUUtEQXBCY0hCc1pTQkpibU11TVNZd0pBWURWUVFMREIxQmNIQnNaU0JEWlhKMGFXWnBZMkYwYVc5dUlFRjFkR2h2Y21sMGVURXpNREVHQTFVRUF3d3FRWEJ3YkdVZ2FWUjFibVZ6SUZOMGIzSmxJRU5sY25ScFptbGpZWFJwYjI0Z1FYVjBhRzl5YVhSNU1CNFhEVEE1TURZeE5USXlNRFUxTmxvWERURTBNRFl4TkRJeU1EVTFObG93WkRFak1DRUdBMVVFQXd3YVVIVnlZMmhoYzJWU1pXTmxhWEIwUTJWeWRHbG1hV05oZEdVeEd6QVpCZ05WQkFzTUVrRndjR3hsSUdsVWRXNWxjeUJUZEc5eVpURVRNQkVHQTFVRUNnd0tRWEJ3YkdVZ1NXNWpMakVMTUFrR0ExVUVCaE1DVlZNd2daOHdEUVlKS29aSWh2Y05BUUVCQlFBRGdZMEFNSUdKQW9HQkFNclJqRjJjdDRJclNkaVRDaGFJMGc4cHd2L2NtSHM4cC9Sd1YvcnQvOTFYS1ZoTmw0WElCaW1LalFRTmZnSHNEczZ5anUrK0RyS0pFN3VLc3BoTWRkS1lmRkU1ckdYc0FkQkVqQndSSXhleFRldngzSExFRkdBdDFtb0t4NTA5ZGh4dGlJZERnSnYyWWFWczQ5QjB1SnZOZHk2U01xTk5MSHNETHpEUzlvWkhBZ01CQUFHamNqQndNQXdHQTFVZEV3RUIvd1FDTUFBd0h3WURWUjBqQkJnd0ZvQVVOaDNvNHAyQzBnRVl0VEpyRHRkREM1RllRem93RGdZRFZSMFBBUUgvQkFRREFnZUFNQjBHQTFVZERnUVdCQlNwZzRQeUdVakZQaEpYQ0JUTXphTittVjhrOVRBUUJnb3Foa2lHOTJOa0JnVUJCQUlGQURBTkJna3Foa2lHOXcwQkFRVUZBQU9DQVFFQUVhU2JQanRtTjRDL0lCM1FFcEszMlJ4YWNDRFhkVlhBZVZSZVM1RmFaeGMrdDg4cFFQOTNCaUF4dmRXLzNlVFNNR1k1RmJlQVlMM2V0cVA1Z204d3JGb2pYMGlreVZSU3RRKy9BUTBLRWp0cUIwN2tMczlRVWU4Y3pSOFVHZmRNMUV1bVYvVWd2RGQ0TndOWXhMUU1nNFdUUWZna1FRVnk4R1had1ZIZ2JFL1VDNlk3MDUzcEdYQms1MU5QTTN3b3hoZDNnU1JMdlhqK2xvSHNTdGNURXFlOXBCRHBtRzUrc2s0dHcrR0szR01lRU41LytlMVFUOW5wL0tsMW5qK2FCdzdDMHhzeTBiRm5hQWQxY1NTNnhkb3J5L0NVdk02Z3RLc21uT09kcVRlc2JwMGJzOHNuNldxczBDOWRnY3hSSHVPTVoydG04bnBMVW03YXJnT1N6UT09IjsKCSJwdXJjaGFzZS1pbmZvIiA9ICJld29KSW1sMFpXMHRhV1FpSUQwZ0lqUXlORGMwTWpVeE1DSTdDZ2tpYjNKcFoybHVZV3d0ZEhKaGJuTmhZM1JwYjI0dGFXUWlJRDBnSWpFd01EQXdNREF3TURFMk1qUTRNVEFpT3dvSkluQjFjbU5vWVhObExXUmhkR1VpSUQwZ0lqSXdNVEV0TURNdE1EZ2dNREk2TkRRNk16Y2dSWFJqTDBkTlZDSTdDZ2tpY0hKdlpIVmpkQzFwWkNJZ1BTQWlZMjl0TG1OdmJYQmhibmt1UVhCd1RtRnRaUzR4TURBd01EQWlPd29KSW5SeVlXNXpZV04wYVc5dUxXbGtJaUE5SUNJeE1EQXdNREF3TURBeE5qSTBPREV3SWpzS0NTSnhkV0Z1ZEdsMGVTSWdQU0FpTVNJN0Nna2liM0pwWjJsdVlXd3RjSFZ5WTJoaGMyVXRaR0YwWlNJZ1BTQWlNakF4TVMwd015MHdPQ0F3TWpvME5Eb3pOeUJGZEdNdlIwMVVJanNLQ1NKaWFXUWlJRDBnSW1OdmJTNWpiMjF3WVc1NUxrRndjRTVoYldVaU93b0pJbUoyY25NaUlEMGdJakV1TUM0eElqc0tmUT09IjsKCSJwb2QiID0gIjEwMCI7Cgkic2lnbmluZy1zdGF0dXMiID0gIjAiOwp9

Decoded Receipt
{
    "signature" = "AluHUloGqz6c9SoJQUz1t98azb6Z2BocwYPa+fUbYfuB9dNQBEbWgS5uHQInjGRCdRqY1PxPcg/2MdIYN4Cvjw4FCnsBjOGv4aj65As46HDlxgxZ7eLIFQw+poPVZSdyDYaz4pOhlq5PfUsjviY4CXwuZC9+I0GvNymVV6HgGaBEAAADVzCCA1MwggI7oAMCAQICCGUUkU3ZWAS1MA0GCSqGSIb3DQEBBQUAMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQKDApBcHBsZSBJbmMuMSYwJAYDVQQLDB1BcHBsZSBDZXJ0aWZpY2F0aW9uIEF1dGhvcml0eTEzMDEGA1UEAwwqQXBwbGUgaVR1bmVzIFN0b3JlIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA5MDYxNTIyMDU1NloXDTE0MDYxNDIyMDU1NlowZDEjMCEGA1UEAwwaUHVyY2hhc2VSZWNlaXB0Q2VydGlmaWNhdGUxGzAZBgNVBAsMEkFwcGxlIGlUdW5lcyBTdG9yZTETMBEGA1UECgwKQXBwbGUgSW5jLjELMAkGA1UEBhMCVVMwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMrRjF2ct4IrSdiTChaI0g8pwv/cmHs8p/RwV/rt/91XKVhNl4XIBimKjQQNfgHsDs6yju++DrKJE7uKsphMddKYfFE5rGXsAdBEjBwRIxexTevx3HLEFGAt1moKx509dhxtiIdDgJv2YaVs49B0uJvNdy6SMqNNLHsDLzDS9oZHAgMBAAGjcjBwMAwGA1UdEwEB/wQCMAAwHwYDVR0jBBgwFoAUNh3o4p2C0gEYtTJrDtdDC5FYQzowDgYDVR0PAQH/BAQDAgeAMB0GA1UdDgQWBBSpg4PyGUjFPhJXCBTMzaN+mV8k9TAQBgoqhkiG92NkBgUBBAIFADANBgkqhkiG9w0BAQUFAAOCAQEAEaSbPjtmN4C/IB3QEpK32RxacCDXdVXAeVReS5FaZxc+t88pQP93BiAxvdW/3eTSMGY5FbeAYL3etqP5gm8wrFojX0ikyVRStQ+/AQ0KEjtqB07kLs9QUe8czR8UGfdM1EumV/UgvDd4NwNYxLQMg4WTQfgkQQVy8GXZwVHgbE/UC6Y7053pGXBk51NPM3woxhd3gSRLvXj+loHsStcTEqe9pBDpmG5+sk4tw+GK3GMeEN5/+e1QT9np/Kl1nj+aBw7C0xsy0bFnaAd1cSS6xdory/CUvM6gtKsmnOOdqTesbp0bs8sn6Wqs0C9dgcxRHuOMZ2tm8npLUm7argOSzQ==";
    "purchase-info" = "ewoJIml0ZW0taWQiID0gIjQyNDc0MjUxMCI7Cgkib3JpZ2luYWwtdHJhbnNhY3Rpb24taWQiID0gIjEwMDAwMDAwMDE2MjQ4MTAiOwoJInB1cmNoYXNlLWRhdGUiID0gIjIwMTEtMDMtMDggMDI6NDQ6MzcgRXRjL0dNVCI7CgkicHJvZHVjdC1pZCIgPSAiY29tLmNvbXBhbnkuQXBwTmFtZS4xMDAwMDAiOwoJInRyYW5zYWN0aW9uLWlkIiA9ICIxMDAwMDAwMDAxNjI0ODEwIjsKCSJxdWFudGl0eSIgPSAiMSI7Cgkib3JpZ2luYWwtcHVyY2hhc2UtZGF0ZSIgPSAiMjAxMS0wMy0wOCAwMjo0NDozNyBFdGMvR01UIjsKCSJiaWQiID0gImNvbS5jb21wYW55LkFwcE5hbWUiOwoJImJ2cnMiID0gIjEuMC4xIjsKfQ==";
    "pod" = "100";
    "signing-status" = "0";
}

2) Недействительный JSON

Данные кодируются в base64, и после декодирования предполагается, что они предоставляют информацию в допустимом объекте JSON, но из того, что я вижу, объекты определенно не являются допустимым JSON. Apple, кажется, использует "=", где ":" должно быть и ";" где "," должно быть:

{
    "item-id" = "424742510";
    "original-transaction-id" = "1000000001624810";
    "purchase-date" = "2011-03-08 02:44:37 Etc/GMT";
    "product-id" = "com.company.AppName.100000";
    "transaction-id" = "1000000001624810";
    "quantity" = "1";
    "original-purchase-date" = "2011-03-08 02:44:37 Etc/GMT";
    "bid" = "com.company.AppName";
    "bvrs" = "1.0.1";
}

Мне интересно, может ли одна из причин, почему мы получаем ошибку, заключается в том, что квитанция, которую они предоставляют, не является допустимой JSON, поэтому, когда мы публикуем данные для проверки, сервер их отклоняет. Должны ли мы все декодировать, исправить объект на допустимый JSON, перекодировать его, а затем отправить его в Apple для проверки?

Я надеюсь, что кто-то еще, у кого есть эта работа, может направить меня в правильном направлении на два вопроса выше или, что еще лучше, предоставить правильный вызов CURL, который получит действительный ответ, который полностью решит мои проблемы.

Заранее спасибо за помощь!

Ответы [ 3 ]

10 голосов
/ 09 марта 2011

Если я правильно прочитал документацию, вы на неправильном пути.Квитанция, которую вы отправляете для проверки, является порцией данных, возвращаемых свойством transactionReceipt.Вы не должны заботиться о том, что он декодирует, или если он вообще что-то декодирует.Вы просто кодируете его с помощью base64, помещаете его в объект json в качестве значения для ключа «квитанции-данные» и отправляете этот объект json в Apple.

Когда вы получаете ответ от Apple, что - это то, что должно содержать данные квитанции в формате json.

4 голосов
/ 06 октября 2011

Для всех, кто в будущем получит ошибку 21002.Потребовалось несколько часов, чтобы понять, что происходит не так.Как правило, это означает, что строка в кодировке Base 64 в JSON, отправляемом на серверы Apple, неверна.Это, вероятно, означает, что вы не используете кодировку Base-64 или что ваша процедура кодирования содержит ошибки.Вот шаги, которые вы должны использовать:

1) Base-64 кодирует все NSData, которые вы получаете от свойстваactionReceipt вашего объекта SKPaymentTransaction, в объект NSString.Вы можете использовать метод ниже.

2) Вставьте это в строку JSON.В коде target-C это будет:

NSString* json = [NSString stringWithFormat:@"{ 'receipt-data' : '%@' }", base64String];

3) HTTP POST, что

4) Вы получите обратно строку JSON - извлеките значение для «status».Если оно равно 0, ваш чек был подтвержден - в противном случае это непроверенная покупка.

Ниже приведен код, который я использую для преобразования NSData в строку в кодировке Base-64:

@interface NSData (Base64Encoding)

- (NSString*)base64Encode;

@end

@implementation NSData (Base64Encoding)

- (NSString*)base64Encode
{
    static char table [] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

    NSInteger length = [self length];
    NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
    uint8_t* input = (uint8_t*)[self bytes];
    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];
}

@end

Чтобы использовать это просто сделайте что-то вроде:

NSString* base64string = [transaction.transactionReceipt base64Encode];
2 голосов
/ 09 марта 2011

Это похоже на Список свойств ASCII - Вы должны иметь возможность использовать класс NSPropertyListSerialization для его декодирования.

EDIT

Какой класс у декодированного объекта? Это также похоже на то, что вы получаете, когда вы сбрасываете NSDictionary с помощью NSLog ()

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...