Unauthorized for Advanced Commerce API Purchase

Hi!

My product SKU has been approved for Advanced Commerce API. I successfully receive a purchase pop-up with the correct information.

However, I am still having issues with completing the purchase. I always receive Unauthorize error when I confirm the purchase (subscription in my case; see the screenshot). I am using the node.js server library to sign the request. I made sure that the account is a valid account enabled for Sandbox.

Logs unfortunately don't indicate any further detail.

Thanks for your advice! We've been stuck on this for a while now and would appreciate your help.

Marek

Please submit a Feedback Assistant request. Select “Developer Tools & Resources” as your topic and then “Advanced Commerce API” from the problem area menu.

Please include your signed request data and system diagnose logs in the Feedback Assistant ticket.

After you have submitted your request, please feel free to share the Feedback Assistant request number in this thread.

Submitted a Feedback Assistant request.

FB18759909 (Receiving Unauthorized for Advanced Commerce API Purchase)

Thank you for submitting the Feedback Assistant request. Could you please also attach the code that you are using to generate the signature to the Feedback Assistant request.

Can you please validate and ensure signature payload contains payload fields below and not any other additional fields.

{
  "iss": "57246542-96fe-1a63e053-0824d011072a",
  "iat": 1741043663,
  "aud": "advanced-commerce-api",
  "bid": "com.example.testbundleid",
  "nonce": "df2b8374-95a1-425b-a6a5-77a4d7648333",
  "request": "<base64-encoded request data>"
}

Yes, the signature payload matches.

This is the JWT

And this is the decoded payload from the JWT:

{
  "request": "eyJvcGVyYXRpb24iOiJDUkVBVEVfU1VCU0NSSVBUSU9OIiwidmVyc2lvbiI6IjEiLCJyZXF1ZXN0SW5mbyI6eyJhcHBBY2NvdW50VG9rZW4iOiIwMTk3NTU0Ni1hYTAyLTc4NzgtYTY2OS00MGIxMmJkMzk0YzkiLCJyZXF1ZXN0UmVmZXJlbmNlSWQiOiIwODMyNzAyNi01MzM2LTQ4MTYtYWEzOS1iN2U0MDhkNWQwYTYifSwiY3VycmVuY3kiOiJDWksiLCJ0YXhDb2RlIjoiQzAwMy0wMC0xIiwiZGVzY3JpcHRvcnMiOnsiZGlzcGxheU5hbWUiOiJHaWdhY2hhZCIsImRlc2NyaXB0aW9uIjoiQWNjZXNzIHRvIEdpZ2FjaGFkJ3MgZXhjbHVzaXZlIGNvbnRlbnQifSwicGVyaW9kIjoiUDFNIiwic3RvcmVmcm9udCI6IkNaRSIsIml0ZW1zIjpbeyJTS1UiOiJjcmVhdG9yX3N1YnNjcmlwdGlvbl8yMDAwMF8xbV8wdzAiLCJkaXNwbGF5TmFtZSI6IkNyZWF0b3IgU3Vic2NyaXB0aW9uIiwiZGVzY3JpcHRpb24iOiJBY2Nlc3MgdG8gY3JlYXRvcidzIGV4Y2x1c2l2ZSBjb250ZW50IiwicHJpY2UiOjIwMDAwfV19",
  "bid": "app.tradeforge.tradeforge.staging",
  "nonce": "8fcc0e15-844b-4cce-bfa4-31f8f4fa3c89",
  "iat": 1752396360,
  "aud": "advanced-commerce-api",
  "iss": "4f338416-010e-40ae-8e30-88d034bd5f40"
}

This is the code I am using:

import {AdvancedCommerceInAppSignatureCreator, Environment} from "@apple/app-store-server-library"
import {readFileSync} from "fs"


const issuerId = "<REDACTED>"
const keyId = "<REDACTED>"
const bundleId = "app.tradeforge.tradeforge.staging"
const filePath = ".secret/SubscriptionKey_<KEY_ID>.p8"
const encodedKey = readFileSync(filePath, "utf8")
const environment = Environment.SANDBOX // TODO: Unused, is this correct? AdvancedCommerceInAppSignatureCreator does allow to pass environment.

const signatureCreator = new AdvancedCommerceInAppSignatureCreator(encodedKey, keyId, issuerId, bundleId)
const signature = signatureCreator.createSignature({
    operation: "CREATE_SUBSCRIPTION",
    version: "1",
    requestInfo:
        {
            appAccountToken: "01975546-aa02-7878-a669-40b12bd394c9",
            requestReferenceId: "08327026-5336-4816-aa39-b7e408d5d0a6"
        },
    currency: "CZK",
    taxCode: "C003-00-1",
    descriptors:
        {
            displayName: "Gigachad",
            description: "Access to Gigachad's exclusive content"
        },
    period: "P1M",
    storefront: "CZE",
    items:
        [{
            SKU: "creator_subscription_20000_1m_0w0",
            displayName: "Creator Subscription",
            description: "Access to creator's exclusive content",
            price: 20000
        }]
})
console.log(signature)
Unauthorized for Advanced Commerce API Purchase
 
 
Q