Automated Promotions with no discount — "Not for Sale" workaround and purchase count tracking
-
Hi BrainCloud team,
We're implementing Automated Promotions to gate specific products behind user segments and time windows — but without any price discount. The goal is simply to make a product available (at its regular App Store price) for a limited time to eligible users, not to offer it at a reduced price.
The console constraint we ran into:
When setting up a Cash Product in an Automated Promotion, the dashboard enforces that the promotional price must differ from the default price. Since we don't intend to offer a discount, we can't configure a valid second price tier.
Our current workaround:
We set the promotional price to "Not for Sale" (priceId: -2). This lets us pass validation and receive the itemId in the GetEligiblePromotions response, which we use to look up the product. The actual purchase goes through the App Store at the product's standard list price — our client ignores the priceId and referencePrice entirely.
Our question:
With this "Not for Sale" workaround, does the Promotion's purchased counter increment correctly when a successful IAP purchase is verified via verifyPurchase?
We're relying on purchased >= maxPurchases to prevent the promotion from re-appearing after a user has already bought the product. If the counter doesn't increment in this setup, we need to handle purchase tracking ourselves.
Feature request:
Is there a plan to support promotions that sell products at their default/list price without requiring a discounted price tier? For use cases like timed exclusives or segment-gated access (rather than sales), this would remove the need for workarounds.
Thanks in advance!
-
If your promotion is for a cash product and the promotional product is set to
Not for Sale, you need to complete the flow by callingverifyPurchasein brainCloud with thepurchasePayloadfrom the store.As long as that payload contains the
promotionIdyou received fromGetEligiblePromotions, the promotion will be correctly attributed and the server-side flow will reach the counter increment logic.Also make sure you set
maxPurchaseson the promotion configuration page so the system knows when to stop returning that promotion for the user.As for your feature request to allow promotions without requiring a discount, I will forward this to our team for review.
-
Hi - I'm probably missing the subtleties of your use case.
But in your scenario, what folks would normally do is:
- Set the product as NOT FOR SALE by default.
- Then have Promotion set it as AVAILABLE at the STANDARD price point.
Is there a reason that you don't set the product as NOT FOR SALE initially?
-
Thank you for the responses. I'd like to clarify my situation and ask more specific follow-up questions.
My current setup:
- Product default price: Standard price (normally available for purchase)
- Promotion price override: Not for Sale (priceId: -2)
- Reason: The console requires the promotion price to differ from the default price, so this is used as a workaround to pass validation
- Actual purchase price: Provided directly by Apple App Store / Google Play
In other words, I'm using promotions not to change the price, but to control access for specific user segments and track purchase counts.
Question 1: Is using "Not for Sale" as a promotion price override a supported pattern?
With the setup described above — where the promotion price override is set to Not for Sale (priceId: -2) — does BrainCloud's purchase counter and maxPurchases limit work correctly? Is this a supported use case?
Question 2: How exactly should promotionId be passed during purchase?
JasonL mentioned:
"As long as that payload contains the promotionId you received from GetEligiblePromotions, the promotion will be correctly attributed and the server-side flow will reach the counter increment logic."
However, in a standard IAP flow:
- Call GetEligiblePromotions → receive promotionId
- User completes payment on Apple App Store / Google Play → store returns a receipt (binary/base64 data generated by Apple/Google)
- Call AppStoreVerifyPurchase (or equivalent) with that receipt
The receipt from step 2 is generated by Apple/Google — I cannot inject custom fields like promotionId into it.
So my question is: in which parameter and in what format should promotionId be passed in the verifyPurchase call? A concrete example of the API call with promotionId correctly included would be extremely helpful.
Summary:
- Question
- Is setting the promotion price override to Not for Sale (priceId: -2) a supported pattern, and will the purchase counter work correctly?
- In the verifyPurchase API call, which parameter carries the promotionId, and in what format?