Thank you for the responses. Based on the discussion, we've implemented the following:
Product default price: standard App Store price Promotion price override: "Not for Sale" (priceId: -2) — workaround to pass console validation requiring a price difference Purchase verification: server-to-server (S2S) VERIFY_PURCHASE, no explicit promotionId in the request Promotion gating: via GetEligiblePromotions() on the clientWe're observing that the purchased counter increments correctly after purchase, and the promotion does not reappear after app restart.
We believe the reason automatic attribution works without calling CachePurchasePayloadContext() is that we set Apple's appAccountToken (a UUID embedded in the StoreKit 2 signed transaction) to the brainCloud profileId before initiating the native IAP purchase. When brainCloud receives the JWS receipt during S2S VERIFY_PURCHASE, it can extract the appAccountToken, identify the user, look up their active promotions, and increment the counter automatically.
Two quick questions:
Is this understanding correct — does brainCloud use the appAccountToken in the StoreKit 2 JWS to perform automatic promotion attribution, making CachePurchasePayloadContext() unnecessary in this flow? When we extend this to Android (Google Play), there is no equivalent of appAccountToken in the receipt. What is the recommended approach to ensure promotion attribution works correctly in that case — should we call CachePurchasePayloadContext() before the purchase, or is there another mechanism?