2011-03-09 57 views
8

我知道這裏有不少文章,但似乎沒有解決我們遇到的問題。到目前爲止,我認爲我已按照iOS Reference Library Verifying Store Receipts documentation中的說明正確設置了所有設置。但是,在我們向AppStore驗證URL發送POST請求期間,我們正在收到21002「java.lang.NullPointerException」,所以我必須做錯了什麼。AppStore應用內購買收據驗證問題

有些問題我已經注意到,可能會引起這樣的:

1)RECEIPT歧義

該文件指出,我們的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對象但是從我所看到的物體definitately不是有效的JSON。 Apple似乎在使用「=」,其中「:」應該是「and」;「其中「」應該是:

{ 
    "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電話接收有效的答覆,這將完全解決我的問題。

在此先感謝您的幫助!

回答

10

如果我正確地閱讀了文檔,那麼你就錯了。您發送的用於驗證的收據是由transactionReceipt屬性返回的大塊數據。你不應該關心它解碼到什麼,或者如果解碼到任何東西。您只需對它進行64位編碼,將其作爲關鍵字「receipt-data」的值放入一個json對象中,然後將該json對象發佈到Apple。

當你得到蘋果的迴應,是應該包含json格式的收據數據。

+0

這就是我想要做的,但我不能當我這樣做時,得到Apple的有效答覆,所以我開始深入研究它。任何想法爲什麼蘋果會在這種情況下返回一個錯誤?是否有任何我們可能忽略的陷阱? – 2011-03-09 02:22:26

+0

似乎這是LWP :: UserAgent Perl模塊的問題。我能夠通過CURL代替它。感謝您幫助我專注於問題。 – 2011-03-09 18:53:29

2

看起來像是ASCII Property List - 您應該可以使用NSPropertyListSerialization類對其進行解碼。

編輯

什麼是類解碼對象的?這看起來像當你使用NSLog轉儲NSDictionary時得到的東西()

+0

所以你說我們應該解碼ASCII屬性列表,然後將其編碼爲JSON?我嘗試手動執行此操作,似乎仍然在驗證時收到錯誤。任何其他想法?如果我能找到一種使用CURL獲得有效響應的方法,那麼我們應該全部設置。 – 2011-03-09 01:06:17

+0

檢查我的編輯,我認爲你得到的數據可能來自NSLog()調用 - 如果你想要JSON,你必須把NSDictionary轉換成JSON – Dre 2011-03-09 01:08:40

4

對於將來獲得21002錯誤的其他人。花了幾個小時才知道出了什麼問題。這通常意味着您發送給Apple服務器的JSON中的base 64編碼字符串不正確。這可能意味着你不是Base-64編碼,或者你的編碼例程有問題。這些是您應該使用的步驟:

1)Base-64將您從SKPaymentTransaction對象的transactionReceipt屬性收到的所有NSData編碼爲NSString對象。您可以使用下面的方法。

2)將其插入到JSON字符串中。在Objective-C代碼,這將是:

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

3)HTTP POST是

4)你會得到一個JSON字符串返回 - 提取 '狀態' 的值。如果它是0,您的收據已被確認 - 否則它是未經驗證的購買。

下面是我用NSData的轉換爲base-64編碼字符串代碼:

@interface NSData (Base64Encoding) 

- (NSString*)base64Encode; 

@end 

@implementation NSData (Base64Encoding) 

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

    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];