Wednesday, August 22, 2012

App rejected because Apple uses sandbox account when testing

I encountered this about 2 weeks ago when my newsstand app was rejected by Apple because "in-app purchases weren't working". I was quite shocked at the time because I have tested everything rigorously and it was definitely working for me during my own testing. So after further investigation inspecting the server logs, I see the following errors:

 INFO | Apple's response: {"status":21007}

The receipt status code of 21007 means "This receipt is a sandbox receipt, but it was sent to the production service for verification." You can see the complete list of auto-renewable verification status codes here. So it seems that when reviewing apps, apple could be using a sandbox iTunes account to purchase stuff in prod! This was something that I definitely did not expect and cater for in my production server code.

I wasn't 100% convinced about this but further research confirms this: "Always verify your receipt first with the production URL; proceed to verify with the sandbox URL if you receive a 21007 status code. Following this approach ensures that you do not have to switch between URLs while your application is being tested or reviewed in the sandbox or is live in the App Store.". You can see the full article here (faq #16).

That pretty much confirmed it. I was still quite bewildered that after 5 app approvals this is the first time that I have encountered this issue. I guess it depends on your luck what kind of tester you get when your app is being reviewed. Long story cut short the changes I made to my server code looks something like this:

public static Receipt GetReceipt(string receiptData)
{
    const int SandboxReceiptSentToProd = 21007;
    var receipt = GetReceipt(urlProduction, receiptData);

    // GOTCHA: During apple approval, apple could be using a sandbox itunes account to purchase stuff in prod!
    // We have to check if receipt comes back with status 21007, that means the tester had used a sanbox account and
    // that we have to post the receipt to sandbox url instead of production
    if (receipt.Status == SandboxReceiptSentToProd)
    {
        // send receipt to sandbox now
        receipt = GetReceipt(urlSandbox, receiptData);
    }

    return receipt;
}

I'm still not happy that I need to have a sandbox reference in my production code, but you just have to follow by Apple's rules. Hope this helps someone else!

3 comments:

  1. Ya... thats true. Even my app rejected because of the same reason. It totally depends upon the tester I guess i.e., whether he will use sandbox or production account for testing.

    ReplyDelete
  2. I like your post about "App rejected because Apple uses sandbox account when testing" very nice post. It is very help full.I do appreciate about this post & this blog ... :)
    Application Testing

    ReplyDelete
  3. Good to know - even if I don't like the solution either, it helps avoiding typical mistakes when forgetting to comment/uncomment test code.

    ReplyDelete