OneShot

All packsApp Store MachinerySolve

storekit 2 appaccounttoken missing join user

Without appAccountToken, nothing reliably joins a transaction to a user

Apple's transaction and notification streams have no user id field of their own -- appAccountToken is the only stable join key, and it has to be set at purchase time.

3 of 3 runs passedOne decision inside App Store Machinery (swiftui-storekit2-node).

What goes wrong

A StoreKit 2 transaction or App Store Server Notification carries a product id, an original transaction id, and various dates -- but nothing that identifies which of the app's own users made the purchase, unless the app explicitly attached one. A server trying to grant entitlements based on a bare product id, with no reliable link back to a specific account, either has to guess (risky) or can't correctly attribute purchases across devices and reinstalls at all.

Why agents get it wrong

Product.purchase() works and returns a valid transaction without appAccountToken ever being set -- the purchase flow itself gives no error or warning that anything is missing, because from StoreKit's perspective the purchase is complete and correct. The gap only becomes visible later, server-side, when there's a transaction to process and nothing in it says whose account it belongs to.

What App Store Machinery pre-decides

Decision 4 makes appAccountToken mandatory on every Product.purchase() call: a stable UUID per user account, stored server-side, passed via .appAccountToken(userUUID) at purchase time. It comes back inside every signed transaction and every notification from then on, which the architecture states plainly is "the only reliable join between Apple's transaction stream and your user table" -- set once, at the one moment it can be attached, or it's unrecoverable later.

Source: ARCHITECTURE.md decision 4

Coming soon — $129Full receipt and details for App Store Machinery

Related problems