2011-03-09 14 views
8

Sé que ha habido bastantes publicaciones al respecto, pero ninguna parece resolver los problemas que nos encontramos. Hasta ahora creo que tengo todo configurado correctamente como se especifica en el iOS Reference Library Verifying Store Receipts documentation. Sin embargo, estamos recibiendo una "java.lang.NullPointerException" 21002 durante nuestra solicitud POST a la URL de verificación de la tienda de aplicaciones, así que debo estar haciendo algo mal.AppStore en la aplicación Problemas de verificación de recibo de compra

Algunas cuestiones me he dado cuenta de que podría ser la causa de esto:

1) RECIBO ambigüedad

La documentación indica que nuestro iPhone App debe estar pasando simplemente el recibo a nuestro servidor de verificación, pero no lo hace indique exactamente qué es el recibo. Al principio pensé que podría ser el objeto completo de JSON a continuación, pero ahora me pregunto si el recibo es solo el campo "información de compra".

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) VÁLIDA JSON

Los datos son codificados en base 64 y una vez decodificado se supone para proporcionar la información en un objeto JSON válida pero de lo que estoy viendo los objetos no son definitately JSON válida. Apple parece estar usando "=" donde ":" debería ser y ";" donde "" debería ser:

{ 
    "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"; 
} 

Me pregunto si una razón por la que estamos recibiendo un error podría deberse a que el recibo que están ofreciendo no es válida JSON así que cuando nos fijamos los datos para la verificación del el servidor lo está rechazando. ¿Deberíamos decodificar todo, arreglar el objeto para que sea JSON válido, volver a codificarlo y luego enviarlo a Apple para su verificación?

Espero que alguien más que tiene este trabajo puede señalarme en la dirección correcta en las dos preguntas anteriores o mejor aún proporcionar la llamada CURL correcta que recibe una respuesta válida que resolvería por completo mis problemas.

Gracias de antemano por su ayuda!

Respuesta

10

Si leo la documentación correctamente, estás en la pista incorrecta. El recibo que envía para la verificación es el fragmento de datos devuelto por la propiedad transactionReceipt. No debería importarle a qué decodifica, o si decodifica nada en absoluto. Basta con codificar 6464, ponerlo en un objeto JSON como el valor de una clave "datos de recibo" y publicar ese objeto JSON en Apple.

Cuando recibe la respuesta de Apple, que se supone que contiene los datos del recibo en formato json.

+0

Eso es lo que intenté hacer primero, pero no puedo obtener una respuesta válida de Apple cuando lo hago, así que empecé a profundizar un poco más. ¿Alguna idea de por qué Apple devolvería un error en ese caso? ¿Hay algún problema que podamos estar pasando por alto? –

+0

parece que fue un problema con el módulo LWP :: UserAgent Perl. Yo era capaz de conseguir que funcione a través de CURL en su lugar. Gracias por ayudarme a mantenerme enfocado en el problema. –

2

Parece un ASCII Property List - Debería poder usar la clase NSPropertyListSerialization para decodificarlo.

EDITAR

¿Cuál es la clase del objeto decodificada? Eso también se parece a lo que obtienes cuando vuelcas un NSDictionary usando NSLog()

+0

por lo estás diciendo que deberíamos decodificar el ASCII Lista de propiedades y luego codificarlo en JSON? He intentado hacerlo de forma manual y parece ser que sigue recibiendo un error en la verificación. ¿Alguna otra idea? Si puedo encontrar una manera de obtener una respuesta válida usando CURL entonces debemos estar todo listo. –

+0

Revise mi edición, creo que los datos que está obteniendo podrían ser de una llamada NSLog(). Si desea JSON, debe convertir NSDictionary en JSON – Dre

4

Para cualquier persona en el futuro que obtenga el error 21002. Tardó algunas horas para descubrir qué estaba pasando mal. Por lo general, significa que la cadena codificada en base 64 dentro del JSON que envía a los servidores de Apple es incorrecta. Esto probablemente significa que no está codificando Base-64 o que su rutina de codificación tiene errores.Estos son los pasos que debe seguir:

1) Base-64 codifica todos los NSData que recibe de la propiedad transactionReceipt de su objeto SKPaymentTransaction en un objeto NSString. Puedes usar el método a continuación.

2) Inserte que en una cadena JSON. En el código Objective-C sería:

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

3) HTTP POST que se

4) obtendrá una cadena JSON - extraer el valor de 'status'. Si es 0 el recibo ha sido confirmada - de lo contrario, es una compra sin verificar.

A continuación se muestra el código que utilizo para convertir el NSData a una cadena de base 64 codificado:

@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 

Para usarlo simplemente hacer algo como:

NSString* base64string = [transaction.transactionReceipt base64Encode]; 
Cuestiones relacionadas