server-side iap authentication error code 401

I created a project to validate in-app purchase receipts using c# but I always get error 401, you don't have permission, I followed the instructions exactly but still failed, I created a private key in Certificates, IDs & Profiles and download the .p8 file but it still doesn't work, I also created and tried another key in Users and Access > Integrations > App Store Connect API and also In-App Purchase but it still doesn't work. When I try to put the created token on jwt.io, I always get an Invalid Signature error

using Jose; using System; using System.Collections.Generic; using System.Net.Http.Headers; using System.Net.Http; using System.Security.Cryptography; using System.Threading.Tasks; using System.IO; using System.Net;

namespace CheckIAP { internal class Program

{
    static async Task Main(string[] args)
    {
        string jwtToken = GenerateAppStoreJwtToken();
        string transactionId = "110002159078***";
        Console.WriteLine(jwtToken);
        string url = $"https://api.storekit.itunes.apple.com/inApps/v2/history/{transactionId}";
        using (HttpClient client = new HttpClient())
        {

            client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", jwtToken);
            client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

HttpResponseMessage response = await client.GetAsync(url);

            if (response.IsSuccessStatusCode)
            {
                string responseData = await response.Content.ReadAsStringAsync();
                Console.WriteLine(responseData);
            }
            else
            {
                Console.WriteLine($"Error: {response.StatusCode}, {response.ReasonPhrase}");
                string responseData = await response.Content.ReadAsStringAsync();
                Console.WriteLine(responseData);
            }
        }
        Console.ReadLine();
    }
    public static string GenerateAppStoreJwtToken()
    {
        string teamId = "PZG479xxxx";
        string keyId = "JCXH26xxxx";
        string issuerId = "7aa0c9c2-***-***-***-xxxx";
        string bundleId = "com.***.***";
       
        const string API_KEY = "MIGTAgEAMBMGByqGSM....";
        var header = new Dictionary<string, object>()
        {
            { "alg", "ES256" },
            { "kid", keyId },
            { "typ", "JWT" }
        };

        var payload = new Dictionary<string, object>
        { 
            { "iss", issuerId },
            { "iat", DateTimeOffset.UtcNow.ToUnixTimeSeconds() },
            { "exp", DateTimeOffset.UtcNow.AddMinutes(15).ToUnixTimeSeconds() },
            { "aud", "appstoreconnect-v1" },
            { "sub", bundleId }
        };


        var key = CngKey.Import(Convert.FromBase64String(API_KEY),
                      CngKeyBlobFormat.Pkcs8PrivateBlob);

        return Jose.JWT.Encode(payload, key, JwsAlgorithm.ES256, header);

    }
}

}

Hello!

If jwt.io says the signature is invalid, there's probably something wrong with the signing code.

Also, the right key to use with App Store Server API is In-app purchase key. (App Store Connect API key is for App Store Connect API only.)

Using the correct key, please look into App Store Server Library, it simplifies the process a lot!

To learn more about App Store Server Library, see

I also tried with the in-app purchase key but still failed, still getting error code 401, above is my code, do you see where my code is wrong?

server-side iap authentication error code 401
 
 
Q