Anyone else having issues with sandbox receipt validations today? (Apr 6)

Hi,


We're finding that Apple's production servers are currently rejecting sandbox purchases with a 21002 error (malformed receipt data) instead of a 21007 error (receipt for test environment). This change is significant because Apple's recommendation is that you send all purchases to the production server first, and if you get the 21007, then redirect them to the sandbox server.


Anybody else having this issue? Anyone know if the recommended strategy has changed? Are we being dumb? 🙂


(PS - Yes, one of my devs has reported it - case number 1084158746).


Paul.

(PS - This was working yesterday!)

What receipt are you trying to verify?

Have you read the various issues described above?

/ - (NSData *)appStoreReceiptForPaymentTransaction:(SKPaymentTransaction *)transaction { NSData *receiptData = nil; / if (kiOS7) {

NSURL *receiptFileURL = [[NSBundle mainBundle] appStoreReceiptURL]; receiptData = [NSData dataWithContentsOfURL:receiptFileURL]; /

} else

{

receiptData = transaction.transactionReceipt; /

}

return receiptData;

}


I'm using following code to read the JSON receipt:


NSData *receipt = [self appStoreReceiptForPaymentTransaction:transaction];

NSError *error = nil;

NSDictionary *receiptDict = [receipt dictionaryFromPlistData:&error];

NSString *transactionPurchaseInfo = [receiptDict objectForKey:@"purchase-info"];

NSString *decodedPurchaseInfo = [NSString stringWithUTF8String:[[NSData dataFromBase64String:transactionPurchaseInfo] bytes]];

NSDictionary *purchaseInfoDict = [[decodedPurchaseInfo dataUsingEncoding:NSUTF8StringEncoding]

dictionar

yFromPlistData:&error];

NSString *transactionID = [purchaseInfoDict objectForKey:@"transaction-id"];

NSString *purchaseDateString = [purchaseInfoDict objectForKey:@"purchase-date"];

NSString *signature = [receiptDict objectForKey:@"signature"];

NSString *signatureDecoded = [NSString stringWithUTF8String:[[NSData dataFromBase64String:signature] bytes]]; / NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];

[dateFormat setDateFormat:@"yyyy-MM-dd HH:mm:ss z"];

NSDate *purchaseDate = [dateFormat dateFromString:[purchaseDateString stringByReplacingOccurrencesOfString:@"Etc/" withString:@""]];

NSLog(@"Raw receipt content: \n%@", [NSString stringWithUTF8String:[receipt bytes]]);

NSLog(@"Purchase Info: %@", purchaseInfoDict);

NSLog(@"Transaction ID: %@", transactionID);

NSLog(@"Purchase Date: %@", purchaseDate);

NSLog(@"Signature: %@", signatureDecoded);


The

dictionaryFromPlistData:
method returns proper
NSDictionary
object for data returned by
transactionReceipt
, but it returns
nil
using data returned using
appStoreReceiptURL
-- and consequetly I don't get valid receipt!


- (NSDictionary *)dictionaryFromPlistData:(NSError **)outError

{

NSError *error;

NSDictionary *dictionaryParsed = [NSPropertyListSerialization propertyListWithData:self options:NSPropertyListImmutable format:nil error:&error];

if (!dictionaryParsed)

{

if (error)

{

*outError = error;

} return nil;

}

return dictionaryParsed;

}

Is this issue happening in the sandbox or production environment? What is the status of the request when you send the base64 encoded applicationReceipt to the iTunes Validation server? I don't see in the code sample where the receipt is encoded, then sent to the validation server.


rich kubota - rkubota@apple.com

developer technical support CoreOS/Hardware/MFI

According to the last paragraph here:


https://developer.apple.com/library/content/releasenotes/General/ValidateAppStoreReceipt/Chapters/ValidateRemotely.html#//apple_ref/doc/uid/TP40010573-CH104-SW1


If the receipt being validated is for the latest renewal, the value for

latest_receipt
is the same as
receipt-data
(in the request) and the value for
latest_receipt_info
is the same as
receipt
.


But my

latest_receipt
and
receipt-data NEVER match, not even for the first subscription. The status returns null meaning the receipt is verified from apple server but the receipt I pass in the request is different from the one returned in response.


Is the documentation old/wrong, or I am doing something wrong? 3 days I am trying to figure this out but have not found any posts anywhere. Thanks for your hlep.

This only works for old iOS6 style receipts (transaction.transactionReceipt) and those receipts are now deprecated. The system sometimes (but not always) returns these fields for the newer receipts.

Then if latest_receipt and latest_receipt_info are for old IOS6 style receipts, how do I get the subscription renewal information back from the Apple response. I am posting my receipt request and response here, if I ignore the latest_receipt and latest_receipt_info fields I am left only with the receipt->in_app field and that is not returning any renewal information, it only has the initial transaction. The status is always 0, because the receipt is a valid receipt although it might be expired. The only field that has renewal info is latest_receipt_info array which seems to be for IOS6 style receipts and sometimes there, sometimes not.


Could you please help me understand how I should interpret the response for renewable subscription types. I looked at every single post/article and didn't find clearly how to do this for IOS7 style receipts. Thanks.



Request receipt sent for validation:

Array

(

[id] => psautorenewsubscription

[alias] => psautorenewsubscription

[type] => paid subscription

[state] => approved

[title] => 1 Month Package

[description] => Starter Package

[price] => $19.99

[currency] => USD

[loaded] => 1

[canPurchase] =>

[owned] => 1

[downloading] =>

[downloaded] =>

[transaction] => stdClass Object

(

[type] => ios-appstore

[id] => 1000000238538313

[appStoreReceipt] => MIIT+AYJ.............

[transactionReceipt] => woJInNpZ...............

)

[valid] => 1

[transactions] => Array

(

[0] => 1000000238538313

)

)



Response from Apple server


Object

(

[status] => 0

[environment] => Sandbox

[receipt] => stdClass Object

(

[receipt_type] => ProductionSandbox

[adam_id] => 0

[app_item_id] => 0

[bundle_id] => com.xxxxxxxxxxxxx

[application_version] => 1.0.0

[download_id] => 0

[version_external_identifier] => 0

[receipt_creation_date] => 2016-09-23 04:40:30 Etc/GMT

[receipt_creation_date_ms] => 1474605630000

[receipt_creation_date_pst] => 2016-09-22 21:40:30 America/Los_Angeles

[request_date] => 2016-09-27 04:53:20 Etc/GMT

[request_date_ms] => 1474952000407

[request_date_pst] => 2016-09-26 21:53:20 America/Los_Angeles

[original_purchase_date] => 2013-08-01 07:00:00 Etc/GMT

[original_purchase_date_ms] => 1375340400000

[original_purchase_date_pst] => 2013-08-01 00:00:00 America/Los_Angeles

[original_application_version] => 1.0

[in_app] => Array

(

[0] => stdClass Object

(

[quantity] => 1

[product_id] => psautorenewsubscription

[transaction_id] => 1000000237945300

[original_transaction_id] => 1000000237945300

[purchase_date] => 2016-09-23 04:40:18 Etc/GMT

[purchase_date_ms] => 1474605618000

[purchase_date_pst] => 2016-09-22 21:40:18 America/Los_Angeles

[original_purchase_date] => 2016-09-23 04:40:30 Etc/GMT

[original_purchase_date_ms] => 1474605630000

[original_purchase_date_pst] => 2016-09-22 21:40:30 America/Los_Angeles

[expires_date] => 2016-09-23 04:45:18 Etc/GMT

[expires_date_ms] => 1474605918000

[expires_date_pst] => 2016-09-22 21:45:18 America/Los_Angeles

[web_order_line_item_id] => 1000000033293412

[is_trial_period] => false

)

)

)

[latest_receipt_info] => Array

(

[0] => stdClass Object

(

[quantity] => 1

[product_id] => psautorenewsubscription

[transaction_id] => 1000000237945300

[original_transaction_id] => 1000000237945300

[purchase_date] => 2016-09-23 04:40:18 Etc/GMT

[purchase_date_ms] => 1474605618000

[purchase_date_pst] => 2016-09-22 21:40:18 America/Los_Angeles

[original_purchase_date] => 2016-09-23 04:40:30 Etc/GMT

[original_purchase_date_ms] => 1474605630000

[original_purchase_date_pst] => 2016-09-22 21:40:30 America/Los_Angeles

[expires_date] => 2016-09-23 04:45:18 Etc/GMT

[expires_date_ms] => 1474605918000

[expires_date_pst] => 2016-09-22 21:45:18 America/Los_Angeles

[web_order_line_item_id] => 1000000033293412

[is_trial_period] => false

)

[1] => stdClass Object

(

[quantity] => 1

[product_id] => psautorenewsubscription

[transaction_id] => 1000000237945774

[original_transaction_id] => 1000000237945300

[purchase_date] => 2016-09-23 04:45:35 Etc/GMT

[purchase_date_ms] => 1474605935000

[purchase_date_pst] => 2016-09-22 21:45:35 America/Los_Angeles

[original_purchase_date] => 2016-09-23 04:45:35 Etc/GMT

[original_purchase_date_ms] => 1474605935000

[original_purchase_date_pst] => 2016-09-22 21:45:35 America/Los_Angeles

[expires_date] => 2016-09-23 04:50:35 Etc/GMT

[expires_date_ms] => 1474606235000

[expires_date_pst] => 2016-09-22 21:50:35 America/Los_Angeles

[web_order_line_item_id] => 1000000033293413

[is_trial_period] => false

)

.................................

.................................

[10] => stdClass Object

(

[quantity] => 1

[product_id] => psautorenewsubscription

[transaction_id] => 1000000238537623

[original_transaction_id] => 1000000237945300

[purchase_date] => 2016-09-27 04:48:41 Etc/GMT

[purchase_date_ms] => 1474951721000

[purchase_date_pst] => 2016-09-26 21:48:41 America/Los_Angeles

[original_purchase_date] => 2016-09-27 04:48:09 Etc/GMT

[original_purchase_date_ms] => 1474951689000

[original_purchase_date_pst] => 2016-09-26 21:48:09 America/Los_Angeles

[expires_date] => 2016-09-27 04:53:41 Etc/GMT

[expires_date_ms] => 1474952021000

[expires_date_pst] => 2016-09-26 21:53:41 America/Los_Angeles

[web_order_line_item_id] => 1000000033314615

[is_trial_period] => false

)

[11] => stdClass Object

(

[quantity] => 1

[product_id] => psautorenewsubscription

[transaction_id] => 1000000238538313

[original_transaction_id] => 1000000237945300

[purchase_date] => 2016-09-27 04:53:41 Etc/GMT

[purchase_date_ms] => 1474952021000

[purchase_date_pst] => 2016-09-26 21:53:41 America/Los_Angeles

[original_purchase_date] => 2016-09-27 04:53:05 Etc/GMT

[original_purchase_date_ms] => 1474951985000

[original_purchase_date_pst] => 2016-09-26 21:53:05 America/Los_Angeles

[expires_date] => 2016-09-27 04:58:41 Etc/GMT

[expires_date_ms] => 1474952321000

[expires_date_pst] => 2016-09-26 21:58:41 America/Los_Angeles

[web_order_line_item_id] => 1000000033314636

[is_trial_period] => false

)

)

[latest_receipt] => MIIkKQYJK................................

)

Anyone else having issues with sandbox receipt validations today? (Apr 6)
 
 
Q