One token, a whole subscription lifecycle
A subscription is not one event. It is a first purchase, then a series of renewals, sometimes a refund, sometimes a cancellation. To pay an affiliate fairly you have to tie all of those events back to the same referral and keep a running commission state, not just credit the first charge.
The key that makes this possible is the StoreKit 2 appAccountToken. It is a UUID your app sets on the purchase, and Apple echoes it back in the signed transaction and in every App Store Server Notification about that subscription. Because the same token rides every renewal notification, each renewal resolves to the same affiliate without any new client action.
The event to commission map
App Store Server Notifications v2 arrive as signed JWS messages with a notificationType. Attribloom verifies each one against Apple's certificate chain, reads the appAccountToken, finds the affiliate, and moves the commission state accordingly.
- First paid transaction: confirm the conversion and accrue commission on the real transaction value, excluding trials.
- Renewal: accrue again against the same affiliate, because the token is carried on the renewal notification.
- Refund: reverse the commission for that transaction through a clawback.
- Cancellation: stop future accrual. A cancellation is not a refund, so it does not reverse commission already earned on paid periods.
Why renewals need a hold, not just a credit
A renewal can still be refunded after it is charged. Attribloom matures each commission for 30 days before it becomes payable, so a refund that lands inside that window reverses cleanly before any money settles. If a refund arrives after payout, the amount is recorded against the affiliate's future balance.
All of this posts to a double-entry ledger in integer minor units, so a duplicate notification cannot double-pay and a reversal is always a balanced entry. Apple re-delivers notifications and Attribloom deduplicates by notification identifier, which is what makes the renewal stream safe to replay.