apple / app-store-server-library-node

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

APIException.apiError 4040010 is missing

nbapps opened this issue · comments

Status 4040010, which should indicate that TRANSACTION_ID_NOT_FOUND is not returned by the service when using the production environment with a Sandbox transaction ID.
The only response is

APIException {
   httpStatusCode: 401,
    apiError: null,
    errorMessage: null
}

After investigation, it seems it's an issue with the response.json() in the async makeRequest(path, method, queryParameters, body, validator) method

>  Response {
>    size: 0,
>    timeout: 0,
>    [Symbol(Body internals)]: {
>      body: PassThrough {
>        _readableState: [ReadableState],
>        _events: [Object: null prototype],
>        _eventsCount: 2,
>        _maxListeners: undefined,
>        _writableState: [WritableState],
>        allowHalfOpen: true,
>        [Symbol(kCapture)]: false,
>        [Symbol(kCallback)]: null
>      },
>      disturbed: false,
>      error: null
>    },
>    [Symbol(Response internals)]: {
>      url: 'https://api.storekit.itunes.apple.com/inApps/v1/transactions/MY_SANDBOX_TRANSACTION_ID?',
>      status: 401,
>      statusText: 'Unauthorized',
>      headers: Headers { [Symbol(map)]: [Object: null prototype] },
>      counter: 0
>    }
>  }

and error is just invalid-json, that's why the system create a new error throw new APIException(response.status); with only 401 status code and no other informations.

>  FetchError: invalid json response body at https://api.storekit.itunes.apple.com/inApps/v1/transactions/MY_SANDBOX_TRANSACTION_ID? reason: Unexpected end of JSON input
>      at functions/node_modules/node-fetch/lib/index.js:273:32
>      at processTicksAndRejections (node:internal/process/task_queues:96:5)
>      at async AppStoreServerAPIClient.makeRequest (/functions/node_modules/@apple/app-store-server-library/dist/index.js:125:34)
>      at async AppStoreServerAPIClient.getTransactionInfo (/functions/node_modules/@apple/app-store-server-library/dist/index.js:294:16)
>      at async Object.verifyTransaction (/functions/lib/AppStoreServer/AppStoreServer.js:63:29)
>      at async /functions/lib/index.js:200:33
>      at async /functions/node_modules/firebase-functions/lib/common/providers/https.js:458:26
>      at async runFunction (.nvm/versions/node/v17.4.0/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:506:9)
>      at async runHTTPS (.nvm/versions/node/v17.4.0/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:531:5)
>      at async .nvm/versions/node/v17.4.0/lib/node_modules/firebase-tools/lib/emulator/functionsEmulatorRuntime.js:690:21 {
>    type: 'invalid-json'
>  }

@nbapps That is expected, since a 401 response is not valid JSON, and so we fall back to just returning the status code. Does your app have a production release yet? Apps without a production release are not authorized to call any production endpoints, which may explain the 401

@alexanderjordanbaker Thanks for your precisions

No, this is a new application, I'm currently testing everything to do with transaction management on the server and I've noticed this problem.
The documentation clearly states to expect code 4040010 and doesn't mention 401 or any explanation about production release.

That's why I've created this issue

https://developer.apple.com/documentation/appstoreserverapi

If you don’t have environment information, follow these steps:
Call the endpoint using the production URL. If the call succeeds, the transaction identifier belongs to the production environment.
If you receive an error code 4040010 [TransactionIdNotFoundError](https://developer.apple.com/documentation/appstoreserverapi/transactionidnotfounderror), call the endpoint using the sandbox environment.
If the call succeeds, the transaction identifier belongs to the sandbox environment. If the call fails with the same error code, the transaction identifier isn’t present in either environment.

Nicolas

@nbapps That is true, although that only applies if you don't have environment information, which can always be passed from the app to the server along with the transaction id. Better yet, if you pass the entire JWS (https://developer.apple.com/documentation/storekit/verificationresult/3868429-jwsrepresentation) you can verify directly on the server without needing to call the App Store Server API.

If you have an request related to documentation or behavior of the underlying API, I recommend filing a ticket in Feedback Assistant (http://feedbackassistant.apple.com) which will be routed appropriately

@alexanderjordanbaker Thank you for this information!
I close the issue

Nicolas