Implementation of Special Offers for a Mobile Game

Special offers in a mobile game lose purchases when the delivery mechanics break on validations and timers. We design and implement server-side offer delivery turnkey: from modes and validations to rollback and compatibility with existing payments. You get managed mechanics that reduce lost purchases and speed up offer launches.

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Our competencies:

Frequently Asked Questions

Latest works

  • Development of a mobile application for FEEDME
    Development of a mobile application for FEEDME
    971
  • Development of a mobile application for XOOMER
    Development of a mobile application for XOOMER
    869
  • Development of a mobile application for RHL
    Development of a mobile application for RHL
    1289
  • Development of a mobile application for ZIPPY
    Development of a mobile application for ZIPPY
    1143
  • Development of a mobile application for Affhome
    Development of a mobile application for Affhome
    1076
  • Development of a mobile application for the FLAVORS company
    Development of a mobile application for the FLAVORS company
    677

Promotional offers in a mobile game: where the mechanics break

Offer mechanics are a chain of four links: the server decides who gets shown an offer and when, the client renders it at the right moment, the payment gateway confirms the purchase, and the backend credits the item and closes the offer.

A break in any link doesn't look like an error in the logs — it looks like an unhappy player who either didn't see the promotion, or paid twice, or lost their purchase progress midway.

The most common mistake is incorrect display conditions. An offer is tied to a trigger (level, session, no purchases for N days), but the condition check lives on the client, not the server.

The player changes the device clock, reinstalls the app, or logs in from another account — and gets an offer they aren't entitled to, or loses one that was already shown.

The fix is server-side eligibility calculation and an idempotent offer key: one player — one impression per campaign, regardless of device.

The second category is purchase crediting errors. The payment gateway responds slowly, the client retries the request, and the backend handler doesn't check transaction uniqueness.

The result is double crediting, which only surfaces during reconciliation with the store, by which point the player has already spent the extra. The solution is idempotent processing by transaction ID and a separate crediting log that can be used to reconstruct the picture.

The third failure is losing purchase progress when the connection drops. The player paid, the app closed, and the receipt never reached the server. Without a queue of deferred confirmations and background receipt re-submission, the purchase "hangs" between the store and the game. What helps here is local storage of incomplete transactions and re-validation on the next launch.

All three failures share one thing: the offer state must live on the server, not in the client's memory. Let's break down how this is closed at the architecture level and what checks are put in place at each step.

How special offers delivery works: modes, checks, effect

Special offers delivery is not "showing a banner at the right moment" but a transactional system: the server decides who gets what offer, the client only displays it, and the purchase is confirmed separately.

If the delivery decision lives on the client, any edit of local data opens access to the promotion, and resending the request leads to a double charge.

That is why delivery logic, promotion limits, and server-side purchase validation stay on the backend, while the app receives an already prepared set of offers with identifiers.

Offer display modes

The mode determines when the player sees the promotion and directly affects the load. Push delivery by event (login, level completion, resource drop) gives high response but requires a queue and protection against storms during mass online.

Pull delivery on client request is simpler to operate but adds latency and extra calls. Hybrid — a base set on request plus targeted events — is usually the choice: peak load is smoothed out, and the promotion arrives on time.

Option When it fits Limitations
Push by event Reaction to player action, time-limited promotions Needs a queue and protection against spikes during mass login
Pull on request Simple promotions, rare events Delivery latency, excessive calls to the server
Hybrid The main scenario in prod More complex configuration and priority testing

Idempotency and limits

Each purchase carries a unique operation key: resending the same request returns the result of the first one instead of creating a second transaction. This closes double charges on connection loss and retries.

Promotion limits — how many times a player can buy, the total delivery volume, the lifetime — are checked on the server in the same transaction as the purchase, otherwise the limit is bypassed under parallel requests.

Checks before delivery

Server-side purchase validation checks the right to the promotion, the remaining limit, the payment state, and the absence of a duplicate — before crediting. An error at any step rolls back the entire transaction, so the player either receives the item or loses nothing. This order removes the class of failures "charged but not credited," the most expensive in support.

Google Play Billing and similar payment loops provide receipt confirmation but do not replace server-side validation: the receipt confirms payment, while the right to the promotion and the limits are handled only by your backend.

Stages of implementing promotional offer mechanics

Implementing offers starts not with code, but with a monetization audit: we look at which player events are already logged, how purchases are structured, and where conversion is lost between impression and payment.

If analytics cannot distinguish the source of a purchase, any promotion becomes blind firing — the effect cannot be separated from a seasonal spike. That is why we first fix the measurement points, then design the promotion issuance scheme.

  1. Monetization and data audit. We analyze current events, the purchase funnel, and breakdowns by player segments. The output is a map of points where offer triggers can be attached without modifying the core.
  2. Designing the issuance scheme. We define trigger conditions, per-player limits, the offer's lifetime, and priority rules for when a player matches several promotions at once. The scheme is described declaratively so that parameters can be changed without a client release.
  3. Configuration and server-side setup. Offers are moved into a managed config: segment, product, discount, display window. The server delivers the offer upon client request, and the client only displays it — this eliminates desynchronization of app versions among players.
  4. Testing on a test group of players. We roll out the promotion to a limited segment and verify conversion, redemption share, and load on the payment loop. The test group is separated from the general population, so an unsuccessful hypothesis does not spoil the metrics for the entire product.
  5. Scaling and monitoring. After the effect is confirmed, we expand the reach and set up alerts for anomalies: a spike in payment failures, a drop in redemption, or a rise in support requests.
  6. Configuration handover. We provide the client's team with the issuance scheme, the set of parameters, instructions for starting and stopping a promotion, and the procedure for rolling back to the previous state.
  7. Supporting the first campaigns. We stay in touch during the first launches so that condition adjustments are made based on actual data rather than retroactively.

This order provides predictability: each promotion is launched and switched off without a release, and the result is measured on a limited group before all players see it.

How server-side offer delivery differs from client-side?

Client-side delivery keeps the promotion logic in the app build: the conditions, the reward composition, and the moment of display are hardcoded, and the crediting happens on the device.

This is cheap at the start and works without a network — the player sees special offers even in the subway.

The price for this is trust in the client: system time, local storage, and traffic are under the player's control, so protection against cheating boils down to obfuscation and server-side checks after the fact.

Any change to the conditions requires a new release and passing store reviews, while the old version continues to live on for part of the audience.

Server-side delivery moves the decision to the backend: the app requests a set of available promotions, receives a signed response with the offer ID and expiration time, and confirms the crediting with a separate call.

The key here is state synchronization: the server knows what has already been granted, what has been activated, and what has expired, so a repeated request does not create a second reward.

Protection against cheating is built on idempotency of operations and binding to the account rather than to the device — changing the clock or reinstalling the app changes nothing.

The difference shows up in failures. With client-side delivery, a discrepancy between the device and the backend is discovered when the player has already received extra, and the incident has to be investigated through logs.

With server-side delivery, the state remains the single source of truth: if the response did not arrive, the client will repeat the request and get the same result.

In practice, the approaches are combined. The server decides who gets shown an offer and when, stores quotas and activation history; the client is responsible for rendering, caching the last response, and offline display.

Such a hybrid provides promotion manageability without a release and preserves interface responsiveness on a weak connection.

Case study: how special offers stopped losing purchases

Seasonal promotions and in-game bundles brought a significant share of revenue, but the special offers mechanic worked unreliably. A purchase was confirmed on the client but not processed on the server: the player saw the charge, but the item never arrived.

Every such case meant a support ticket, a manual log review, and a refund, while some players simply left without waiting for a response.

What it was like before the rework

The offer lived on the client side: the promotion timer, price, and bundle contents were stored in the app and synced with the server "whenever possible." If the connection dropped at the moment of payment, the transaction hung in an intermediate state, and re-activating the same offer created a duplicate or a rejection.

The share of successful purchases hovered around 70%, support tickets about promotions came in a steady stream, and repeat activations were rare — players didn't trust the mechanic.

What was changed

The offer state was moved to the server: the client requests the current bundle, the server locks in the reservation and confirms the grant only after a successful transaction.

An idempotency key was introduced for each attempt — a repeated request after a connection drop doesn't create a second purchase but returns the result of the first one.

Timers and promotion conditions became server-side, so tampering with the device clock no longer unlocks an expired offer.

Repeat activations were reworked separately: after a purchase, the player receives the next step in the offer chain rather than the same bundle. This kept interest in the promotion alive and reduced the rejection rate at the confirmation stage.

What it became

Metric Before After
Share of successful purchases ~70% above 96%
Support tickets about promotions steady stream dropped severalfold
Share of repeat activations low grew severalfold
Refunds and manual reviews frequent isolated

The transaction confirmation and idempotency scheme was built on a model close to how it's solved in Google Play Billing — server-side purchase confirmation instead of trusting the client.

This approach eliminates an entire class of failures: hung transactions, duplicates, and "paid but didn't receive."

If your promotions are losing purchases or support is drowning in repetitive tickets — describe your task, and we'll get back to you with an estimate and a plan for reworking the mechanic.

Doubts before starting: access, rollback, compatibility

Before starting, the client usually asks three questions: what is needed on our side, what happens if the release fails, and whether it will break the current game.

For server access, a test environment and an account with deployment rights are enough — production keys and payment secrets stay with you, we work through separate service accounts with a limited lifespan.

The rollback plan is fixed before work begins: the special offers configuration is taken outside the build, so turning off a promotion is a flag switch, not a rebuild and re-moderation.

Compatibility with the current game is checked against your client version and server logic: if the balance, inventory, or player progress change according to their own rules, we adapt to them rather than rewriting them.

What if the promotion is already running and needs to be stopped urgently?

The configuration is stored separately from the code, so stopping is a state change on the server side: new grants stop immediately, already granted rewards remain with the players. No code rollback is required, no release to the store is needed.

What if we have our own team and don't want to hand over the server side? We work on your side: we hand over the specification, configurations, and tests, your engineers make the changes themselves, and we join for acceptance.

What if the game is already in production and there are live players? We roll out the promotion to a share of the traffic, verify the grant metrics, and only then enable it for everyone.

At the end of the work, you receive:

  • promotion configurations with a description of parameters and trigger conditions;
  • a diagram of the interaction between the client, server, and reward storage;
  • a rollback policy and emergency shutdown procedure;
  • a set of automated tests for granting, re-granting, and edge cases;
  • an event log and a dashboard for promotion metrics;
  • handover documentation: how to add a new promotion without a developer's involvement.

Describe the task and your current stack — we'll get back to you with an estimate and a work plan.