Skip to content

Promotional campaigns

Apart from ad-related incomes, we as a business rely on users' proactivity to purchase Premium products. To boost their interest, we might send out the occasional promotional campaign. In the past years, we would send out Black Friday & Cyber Monday promotions, usually discounting the products by 50%. Announcing the discounts can be done directly via 2 media:

  • push notifications (mobile apps only)
  • emails
  • (and social media posts, of course)

Push notifications

Push notifications are generally more successful than emails, likely because they are more difficult to ignore and people use mobile phones much more frequently than desktop computers these days. Also, Settle Up is primarily a mobile app so users expect to deal with everything related to it on their phones.

Notifications are sent via Firebase Messaging > New campaign > Notifications. This opens a setting to configure the notification, where you can specify the texts and image in the notification, targeting, scheduling (send immediately or at a future time), key events for evaluation and advanced options. Localised variants can be quickly added by selecting Duplicate in the English notification's menu (three dots) and changing the copy and the target languages. For English notifications, the target language is set up by excluding other languages used in the campaign ("Languages is not in ES, CZ, DE, ...").

Target groups can be specified for User Segments by app platform, app version, user audiences, device languages, device country/region, first open time, last engagement time and user property (custom properties previously saved in Google Analytics). The FB Messaging also allows the use of Topics, but we have never tried that as there is no control over who receives these notifications.

Push notifications can be tested on a phone before sending out the final versions. Use the button Send test message in the notification configuration. To do that, an FCM token is needed:

  • Android: when you launch the easter egg (clicking several times on the app version in About), the device FCM token is copied to the clipboard.
  • iOS: in Firebase Authentication, find the logged-in user's email and copy their user ID. Go to Realtime Database and write path /pushRegistrations/<userid> and press Enter. Find the device's UUID. That is the token to use in testing.

The notification can open various target screens in the app. Currently, both platforms can open Premium screen by setting Custom data in Additional options as follows:

platform key value
Android actionLink settleup://premium
iOS screen_id plans

Moreover, Android can open an overlay screen which contains a little image, a paragraph of text and a button that then opens the Premium screen. The overlay assets need to be prepared via Admin beforehand.

Premium screen offer needs to be set up in Firebase database and in the Stores before running the campaign so that it reflects the discount offered in the notification.

Promotional emails

Although push notifications are more successful, campaign emails are not without meaning. Even if our users do not react to them by purchasing a Premium product, they are reminded of the app once again, especially about the web app. This is good for brand awareness.

Read more about the technical side of emailing

In the Cyber Monday 2025 campaign, we sent out over 800k emails informing users of the promotion. The target group was selected as users active between June 01, 2025 and Nov 30, 2025. It is vital to select only those with a potential to react to the message, i.e., active users, and consider the price of the campaign. Sending 10k emails costs $1.

Emails can be sent in any number of localisations — backend does this based on what locale the user has as long as the Elastic template has the language code suffix, e.g., cyber_monday_2025_cs. Elastic can export lists of contacts in several formats; our backend will use a csv file. Elastic tags contacts according to their activity and engagement (opening emails, clicking on links,...). Therefore, we can export lists of subscribed users, active, engaged, ...

Campaign setup

Before we run a campaign, we have to ask these questions:

  • What is the ultimate goal? It can be either gain short-term revenue boost, or achieve an increased recurrent income.
  • Who is our target group for this specific campaign?
    • Returning users such as couples and flatmates, or once-in-a-while users such as holiday goers?
    • In low seasons, it makes more sense to try to capture users who might be prone to purchasing Individual Premium (ideally Yearly subscription) because they're already active (at least sometimes) and probably have long-term groups going on.
    • In high seasons, we should try to "teach" users to repeatedly buy short-term Group Premiums for their weekend getaways with friends and holidays with family.
  • What should we offer?
    • Percentage discount (e.g. 50% off) or absolute discount (e.g. 20 dollars off)?
    • Subscription or one-time purchase?
    • For one or more periods in case of subscription; one-time discount for each purchase of Group Premium but it can be bought for multiple groups during the campaign.

Stores & Stripe

  1. Create a descriptive campaign name. It's a good idea to include the year at the end of the string.
    • Join lowercased words with hyphens and without spaces like this: black-friday-2025. This will be the identifier across all platforms and analytics.
    • Warning: App Store only accepts alphanumeric characters, periods and underscores. Our iOS app translates underscores into hyphens that Firebase will accept.
  2. Decide where the campaign will run. Only mobile apps, or the web app as well? Only web app?

Android: Play Store

Monetise with Play > Products > Subscriptions > Settle Up Premium yearly > Add offer

Offers for Yearly subscription

  1. Select to which base plan the offer will be added
  2. Offer ID: put in our identifier
  3. It's possible to select only some countries
  4. Eligibility criteria
    • New customers acquisition: users who either never had this subscription, or never had any subscription
    • Upgrade: motivate users to move from monthly to yearly sub. Never tried this.
    • Developer determined: this means that Play Store will not check the eligibility for us and we can affect who will be able to enjoy the discount. We want to use this to send campaigns even to users who have had a subscription in the past but have churned and are now free users = win-back campaign. Users with an active subscription should not receive a notification (an Audience condition needs to be used in targeting).
  5. Phases: Add phase: 2 consecutive phases can be added.
    • Type
      • Free trial (duration from 1 day, week, month, year)
      • Single payment: pay up front for a specific period (duration from 1 day, week, month, year)
      • Discounted recurring payment: minimum is 2 billing periods
    • Price override
      • Fixed amount: exact price > Set all prices > select all > Set price
      • Percentage discount: e.g. 50% (put in the final %, not how many % it should discount from the regular price)
      • Absolute discount: e.g. $5
      • Type and price override can be combined in any way except for free trial, obviously
  6. Activate the offer. They can be activated and deactivated as needed, and the history is kept.

One-time products

  1. Select the product to which the offer will be added
  2. Offer ID: put in our identifier
  3. Offer type
    • Percentage
    • Absolute discount
  4. Start date and time: can only start today at the beginning of the next hour
  5. End date and time
    • Offer runs indefinitely
    • Offer ends at a specified date and time. For seasonal campaigns, it's a good idea to set the end date, perhaps a few hours after the campaign countdown (to allow late comers to still purchase it). An offer must be active for at least 24 hours.
  6. Purchase limit: we can limit how many offers a user can purchase (up to 50), but no need in our case.
  7. Click Set discount, select all regions, Set discount. Individual countries' prices can be edited at any time.
  8. Activate the offer. Offers can be (de)activated at any time, no need to delete them.

iOS: App Store

Subscriptions > Individual > Yearly Individual Renewable > View all Subscription Pricing (or click on the blue plus sign next to Subscription Prices)> Promotional Offers

Promotional offers for Yearly subscription

  1. Create a Promotional Offer
    • Promotional Offer Reference Name: Human name of the campaign
    • Promotional Offer Identifier: put in our identifier with underscores. It can only ever be used once and will disappear after the offer ends — so no history is kept in App Store.
  2. Type of Promotional Offer
    • Pay as you go: option to select only 1 year
    • Pay up front: 1 month, 2/3/6 months, 1 year
      • honestly don't know what the difference is even after reading the documentation
    • (Free — used for trials in Introductory Offers tab; probably won't use for campaigns)
    • Price: choose from dropdown
    • info shows how much the user will pay for the first year
  3. Promotional Offer Prices
    • Here, individual countries' prices can be adjusted.
  4. Confirm
    • There is no start date or end date.
    • The offer's price can be edited at any time.

Offers for Group Premium

  1. Create a new one-time product
    • Type: Consumable
    • Reference Name: Human name of the campaigned product
      • e.g. Group Premium for 1 year – St. Patrick's Day 2026
    • Product ID: string consisting of the offered product's normal Product ID, dot, our identifier with underscores
      • e.g. group_premium_366.st_patricks_day_2026
      • The Product ID can only ever be used once, even if it is deleted later. ("A unique alphanumeric ID that is used for reporting. After you use a Product ID for one product, it can’t be used again, even if the product is deleted.")
    • Set the discounted price to it
  2. Delete it after the campaign ends

web: Stripe

Product catalog > Coupons > Create coupon

  1. Name: A human name. This will appear on the customers' receipts.
  2. ID: put in our identifier
  3. Type: Percentage off or Fixed amount off
  4. Check Apply to specific products and select Settle Up Group Premium with duration or Settle Up for subscriptions
  5. Duration: Once, Multiple months, Forever
    • For subscriptions, select for example 24 months if you want to give users a discount for Yearly sub for 2 years.
    • For Group Premium, select Once.
  6. Redemption limits: never used, we control the end date ourselves.
  7. Codes
    • Use customer-facing coupon codes: only when creating a coupon for a customer with a problem, such as when they did not manage to purchase in time or Stripe rejects their card etc. It's good idea to limit it to a specific customer — search by email.
    • For campaigns, do not use this option.
  8. Go back to Products > select product that will be promoted > click on its price under Pricing
    • Edit metadata
      • key: offerId
      • value: put in our identifier

Firebase

Firebase will contain all specific information on the campaign: end date, colours, button texts, ... There is no way to control the start date — stores don't have any setting like that.

Realtime database

Offers

Offers will contain a node with our identifier. Find the technical details and current structure in Database overview.

The same structure is on Sandbox Firebase, so test there first!

AB test

Remote config

Parameter called premium_offer_show_end_date can be used to AB test campaign results. The parameter slightly changes the design of the offer: when true, the bottom stripe shows end date of the campaign, while when false, it shows the same countdown as the upper stripe. The reason for testing is to see whether people react better to fixed date or to a FOMO-like dynamic countdown.

Admin tool

Live Admin tool

Sandbox Admin tool

The Admin tool for creating offers in Firebase is self-explanatory with immediate visual result. Any save/edit/create change pushes directly to Firebase. Test on Sandbox first before releasing the campaign on Live!

If you want to edit the offer's ID, clone the offer and insert the new name, then delete the old offer.

Emails

  1. Prepare html templates for all planned localisations. Check that the subject and from fields are in the correct language. Make sure that the names of the templates are correct — our identifier with underscores + underscore + language code, e.g. cyber_monday_2025_de. Send test emails, check links, set up preview text like this:

    </head>
    <div style="display:none;">PREVIEW TEXT HERE — </div>
    
  2. Top up the account balance in Elastic email. 10k emails cost $1.

  3. Export relevant contacts in csv and send the file to Bezy with instructions on when to send which templates.

Push notifications

First, prepare copy in Campaigns list.

Then, go to Firebase: Messaging > New campaign > Notifications (or duplicate an old notification)

  1. Notification title: enter main text, which is seen even if the notification is collapsed, but make sure the discount is always seen (put it early in the copy)
  2. Notification text: subtitle
  3. Image is optional; the notification will show the app logo automatically.
  4. Test on your phone. Find your FCM token as described above.
  5. Target
    • User segment: App == select platform
    • Languages > Is not in > for English, select languages for which we localise (i.e. cs, es, de, ...)
    • User audience(s) > Does not include all of > Premium subscribers (so that we don't send this to paying customers)
  6. Scheduling: immediately or at a later time. It's a good idea to publish them one by one, waiting for one on your own phone to see if it works properly.
  7. Key events: select observed metric. We are interested in premium_purchase_success. Optionally, enter Analytics label.
  8. Additional options (not optional!)
    • Android: put updates in Android Notification Channel and actionLink : settleup://premium in Custom data as key:value pair.
    • iOS: put screen_id : plans in Custom data as key:value pair. Apple badge: Disabled.
    • Identical localisations can be created within one notification, but make sure to test it properly on both platforms! Otherwise create them separately. Results can be filtered by platform later.
    • They can be set up to expire within several days. Default is 4 weeks, but that's unnecessary. The expiration should correspond with the end of the campaign.
  9. Review and publish

After the campaign, copy the results in the spreadsheet and interpret its success.