apple/app-store-server-library-java

Requirements from app reviewer. Get transaction info first production env, then sandbox.

nemezmaksim opened this issue · 3 comments

lib version

<dependency>
    <groupId>com.apple.itunes.storekit</groupId>
    <artifactId>app-store-server-library</artifactId>
    <version>1.0.0</version>
</dependency>

We submitted the application and was rejected. The reviewer wrote the following comment:

When validating receipts on your server, your server needs to be able to handle a production-signed app getting its receipts from Apple’s test environment. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code “Sandbox receipt used in production,” you should validate against the test environment instead.

To meet the conditions of the reviewer, we initialize for each environment client and data verifier:

 AppStoreServerAPIClient sandboxClient =
                new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, Environment.SANDBOX);
SignedDataVerifier sandboxDataVerifier = new SignedDataVerifier(rootCAs, bundleId, appAppleId, Environment.SANDBOX, false);
               
 AppStoreServerAPIClient prodClient =
                new AppStoreServerAPIClient(encodedKey, keyId, issuerId, bundleId, Environment.PRODUCTION);
SignedDataVerifier prodDataVerifier = new SignedDataVerifier(rootCAs, bundleId, appAppleId, Environment.PRODUCTION, false);

                

and implemented the following logic

       try {
            getAllSubscriptionStatuses(prodClient, prodDataVerifier, originalTransactionId, subscriptionGroupId)
        } catch (e: APIException) {
            getAllSubscriptionStatuses(
                sandboxClient,
                sandboxDataVerifier,
                originalTransactionId,
                subscriptionGroupId
            )
                

I have a couple of questions:

  1. If this is a requirement from Apple, maybe this logic should be in your library? So that your customers don't think about it.
  2. The recommended approach is for your production server to always validate receipts against the production App Store first. If validation fails with the error code “Sandbox receipt used in production,” you should validate against the test environment instead.

In this case the library returns

{
  “errorCode” : 4040010,
  “errorMessage” : “Transaction id not found.”
}

This error matches enum constant com.apple.itunes.storekit.client.APIError#TRANSACTION_ID_NOT_FOUND
It's ok?

@dvcer

Hello @nemezmaksim, that requirement generally applies for the use of receipts with the deprecated Verify Receipt endpoint, however with StoreKit 2, you already have access to the environment of the transaction in https://developer.apple.com/documentation/storekit/transaction/3963920-environment, which can be passed along with the signed data. This removes the need to do the two-call methodology.

@nemezmaksim Did the above comment resolve your issue?

Please reopen or file a new issue for any further questions