Ad Reward App
A reward app where users earn points by watching ads and completing missions, then withdraw them as cash. We built the entire system across web, mobile and admin
Case Summary
Client
Ad reward service operator (undisclosed)
Industry
Ad rewards, points-based app service
Period
February 2026 – May 2026 (about 4 months)
Challenge
Because points in a reward app become real cash, earning, settlement, abuse prevention and tax handling all had to interlock before the service could open
Key features
Ad viewing credits, missions and mini-games, referral rewards, membership, withdrawal approval, admin settlement console
Outcome
The entire process from earning to withdrawal handled in a single system, with a structure that automatically applies withholding tax and settlement
1. About the Client
- Client: Ad reward service operator (undisclosed)
- Industry: Ad reward service operation
- Service format: Mobile app (Android and iOS) + web, with points earned and then withdrawn as cash
- Challenge: Build a reward service that ties ad revenue, user rewards and tax handling into a single structure
We were responsible for full-stack development, covering the web service, the mobile app, the admin console and the settlement structure.
2. Background
On the surface, a reward app is simple. You watch an ad and points accumulate; once you have enough points, you exchange them for cash. But that one sentence contains every condition needed to open the service.
Five conditions for opening the service
First, because points are real cash, there has to be a record of why they were earned. If you cannot confirm that the ad was really watched or the mission was actually completed, those points cannot be paid out. Users ask, "I definitely watched it, but the points never arrived," and the operator cannot answer without a way to check.
Second, a withdrawal is a monetary transaction. Because income arises, tax has to be withheld, and a review step is needed before payment. Calculating the amount and keeping the basis for that calculation are two different jobs.
Third, any service that pays rewards inevitably attracts abuse. People create multiple accounts to collect referral rewards repeatedly, or request credit without watching the ad. If these attempts are not stopped, payouts exceed ad revenue and the service itself does not hold together.
Fourth, ad revenue comes from outside. The results sent by ad networks and offerwalls have to be received and converted into points, and these signals can arrive late or more than once. Crediting the same ad twice is a loss of exactly that amount.
Fifth, settlement has to add up. Ad revenue comes in and points go out. If the two are managed separately, there is no way to know whether the service is making money. Payouts and revenue have to be aggregated on the same basis before there is any ground for adjusting policy.
Data structure comes before screens
Reward apps usually do not fail because they lack features. They fail because the payout structure outgrows revenue, because costs leak through abuse that was not stopped, or because slow withdrawal processing costs them trust. That is why in this project we decided the data structure before the screens.
From February to May 2026, we built the service on the premise of these five conditions. Defining the flow of earning, settlement and verification was more central to the project than building screens.
In one line Because points become real cash, earning, settlement, abuse prevention and tax handling all have to interlock before the service can open.
3. Key Features
We made the web service the core and built the mobile app as a wrapper around it. A company website and an admin console were added, and everything is managed in a single repository.
Composition
The user web, the mobile app and the company website are managed in a single repository. Because the three applications share the same rules and types, a policy change never leaves one of them behind on an old version.
Relationship between the app and the web
All core features are implemented on the web, and the mobile app acts as a shell that holds them. Feature fixes do not have to wait for app review, and Android and iOS get the same screens.
However, things that only an app can do are handled by the app. Social login is handed off to an external browser and the result comes back through a deep link, while push notifications and payment app integration are handled in the app layer. By separating what the web can do from what has to be the app, we secured both development speed and feature scope.
Points ledger structure
Points are not managed as a single balance. The wallet holds the current balance, and every increase and decrease is recorded in a ledger. Because each entry records when, why and how much came in or went out, a balance that does not add up can be traced through the ledger to its cause.
Some credits are not confirmed immediately. Credits that need confirmation from the ad network or still have a verification step remaining are kept in a pending state and reflected in the balance only after they are confirmed. Separating pending from confirmed means a cancelled credit never has to be subtracted from the balance.
Earning channels
We set up several channels through which points come in. Ad viewing, mission completion, attendance check-in, mini-games, referral rewards and helping friends are each a separate channel, and the source of each credit is recorded by channel.
The channels are separated because operational decisions need it. When payouts rise, you have to know which channel they rose in before you can adjust policy. A rise in ad credits and a rise in referral rewards have different causes and call for different responses.
Ad revenue and settlement
Ad revenue is generated by external networks. Revenue data and payout records are managed together so that you can see how much came in and how much went out in a given period. A separate settlement ledger keeps per-period snapshots, so the state at a past point in time can be traced back.
Per-country policies are also separated. Reward rates and conditions can differ by region, so these values are managed as settings. The structure anticipates the service not staying in Korea alone.
Withdrawals and tax handling
A withdrawal goes through request, review and payment stages. The user submits a request, an administrator checks and approves it, and the status of each stage is recorded. Withholding tax is calculated and applied automatically at the time of the request, so the payout amount and the tax amount are always recorded together.
Identity verification is also tied to withdrawals. Because money changes hands, the account has to be confirmed to match the actual user, and without a verification result the process does not move on to the withdrawal stage.
Abuse prevention
Accounts are linked to devices to restrict one account being used on several devices at the same time, or several accounts being rotated on one device. Sessions have an expiry period and are rechecked periodically, and blocked accounts are filtered out at the access stage.
Ad credits are verified by keeping a viewing record. Points are not granted on a credit request alone; the request is checked against the result sent by the ad network. Duplicate signals from outside are handled so that the same viewing is not credited twice.
Missions and mini-games
If ad viewing is the only earning channel, users have a reason to open the app only once a day. So we placed missions and mini-games alongside it.
Missions are organized into categories and registered by administrators. Missions tied to an ad provider are processed on a completion signal received from outside, while in-house missions are checked for completion within the app. Completion records are kept per user, which prevents the same mission from being completed more than once.
The mini-games consist of attendance check-in, roulette, drop ball and boost. Each game credits only a small amount, but it creates a reason to come back every day. Reward amounts and the number of plays allowed are managed as policy values so they can be adjusted during operation.
Referrals and membership
Referral rewards apply to both the inviter and the invitee. When an invited user watches an ad or completes a mission, a set percentage also goes back to the inviting user, and ad commissions and mission commissions are recorded separately.
This structure is also the point most vulnerable to abuse. If someone creates multiple accounts that refer one another, rewards are generated without any real activity. So referral history is managed separately, and device linking and identity verification are applied together to restrict repeated collection.
Membership uses tiers to differentiate earning rates and usage conditions. Payment is integrated with Toss Payments, and the payment request is separated from the application of the tier so that a failed payment does not disturb the tier status.
Notifications and exposure management
Push notifications, notices, modal messages, banners and floating ads are handled in the admin console. For a reward service, getting users to come back every day is the core of operations, so notifications and exposure channels have to be managed as operational tools rather than in code.
Send history is recorded, so you can check which notification went out and when. Notification targets and send sources are stored separately, so sends to everyone and sends to users matching specific conditions are handled apart.
Admin console
We built more than 20 screens needed for operations. Members and missions, finance and settlement, withdrawal approval, ad revenue, notices and notifications, banner and exposure settings, app update policy, per-country policy and account deletion requests are each a separate area.
Administrator actions leave an audit record. Adjusting points or approving a withdrawal directly affects money, so who changed what and when has to be kept.
App update policy and operational settings are also handled in the console. The point at which a forced update is required, or a maintenance notice, has to be applicable without an app release in order to respond immediately when a problem occurs. Account deletion requests are processed on a separate screen, so the request and its outcome remain on record.
Screen layout
The user screens are laid out so that what there is to do today is visible as soon as the user comes in. The home screen shows the current point balance and the earning activities available today first, and missions, mini-games, the market, point history and settings are divided into their own areas. Informational screens such as the lounge and notices are placed after them.
The point history screen is the one users look at most sensitively. It shows earned, spent and pending points separately, and indicates which activity each item came from. If only the balance is shown, questions asking "why this amount" turn directly into operational load.
The withdrawal screen is divided into steps. It first shows the amount available to request and the actual payout after withholding tax, and accounts that have not finished identity verification are guided to that step. On a screen where money is involved, an amount that differs from what the user expected costs trust, so the calculation result is stated before the request is made.
How we worked
Over four months, we first finalized the points structure and then layered features on top of it. Until the earning channels, the ledger structure and the withdrawal flow are settled, any feature you build has to be reworked later.
Once the structure was in place, we attached the earning channels one at a time. We completed ad viewing first to confirm the external integration and verification flow, then added missions, mini-games and referral rewards. Each channel is verified differently, so it was safer to go all the way through one before attaching the next.
The admin console was built alongside each feature as it was completed. In a service that handles points and withdrawals, having no management tool means opening the database directly to check things throughout development, and operations cannot be handed over in that state.
Core design Keeping only the calculated result is not enough; what event produced that value has to be kept. That is why there is a ledger.
4. Outcome
We completed a structure that handles the entire process from earning to withdrawal in a single system. Points earned through ad viewing and missions are recorded in the ledger, withholding tax is applied automatically when a withdrawal is requested, and payment is made after administrator approval. Because each stage is recorded, there is something to check against when an inquiry comes in.
Managing points as a ledger rather than a balance had the biggest effect in operations. A question like "why did my points go down" cannot be answered with a balance alone, but with a ledger it ends with a lookup. Thanks to separating credits into pending and confirmed, we also avoided having to claw back a cancelled ad credit after it had already been paid.
Recording earning channels separately gave us a basis for adjusting policy. Changes in payouts can be viewed by channel, which makes it possible to judge which reward needs adjusting. Placing a screen in the admin console that shows ad revenue and payouts together serves the same purpose.
Because we chose a structure with the web as the core and the app as a wrapper, feature changes are not tied to the app review cycle. A reward service adjusts its policies and reward mix frequently, and in this structure those adjustments end with a web deployment.
Placing abuse prevention where users do not notice it also affected the result. Device linking and session checks run in the background, and identity verification is required only at the time of withdrawal. If every verification is imposed at sign-up, legitimate users are the first to drop off.
Because policy values are handled in the admin console, changing reward amounts or the mission lineup does not involve development. A reward service has to keep adjusting while watching the balance between payouts and revenue, and if that adjustment cycle is tied to the deployment cycle, the response is slow.
Over about four months, from February to May 2026, we built the web, the mobile app, the company website and the admin console in full.
5. Technical Stack
Web — Built with the Next.js 14 App Router, TypeScript and Tailwind CSS. The user screens and the admin console are separated by route within the same application, and the API lives in the same codebase.
Mobile — The app is built with React Native and Expo and structured as a wrapper around the web service. Social login is handed off to an external browser and the result is received through a deep link, while push notifications and payment app integration are handled in the app layer.
Backend / Data — We use Prisma ORM and PostgreSQL. Users and sessions, wallets and the points ledger, missions and ad viewing records, withdrawals and settlement, and notifications and operational settings are each separate models.
Authentication — Session tokens are stored as hashes and have an expiry period. Accounts are linked to devices to restrict concurrent use, and administrator sessions are handled in a flow separate from regular users. Social login supports Kakao and Google.
Payments / Notifications — Membership payment is integrated with Toss Payments. Push notifications use Firebase Cloud Messaging, and send history is recorded.
Setup — The user web, the mobile app and the company website are managed together in a monorepo. The development environment is containerized, and the database runs locally.
Design principle — The most important thing in this service is the basis for points. Because the value turns into money, keeping only the calculated result is not enough; what event produced that value has to be kept. Having a ledger, separating credit sources and leaving audit records for administrator actions are all decisions that follow from this principle.
Problems we dealt with during implementation
- Duplicate and delayed external signals.: Results from ad networks and offerwalls can arrive late or more than once. We handled them so that the same event is not credited twice, and managed credits in a pending state until they are confirmed.
- Balancing abuse prevention and usability.: Strict verification inconveniences legitimate users as well. We put mechanisms users do not notice, such as device linking and session checks, up front, and arranged for identity verification to be required only at the time of withdrawal.
- Where tax handling sits.: If withholding tax is calculated at the time of payment, the request record and the amount do not match. We calculate it at the time of the request and record them together, so the amount the user saw when requesting matches the actual payout.
- Constraints of the webview environment.: Social login and payment do not work as they are inside a webview. The app intercepts only those flows, hands them off to an external browser or payment app, and receives the result back through a deep link.
- How often operating policy changes.: Reward amounts and the mission lineup change frequently during operation. Policy values are not fixed in code but handled in the admin console, so they can be adjusted without a deployment.
6. Project Information
| Item | Details |
|---|---|
| Project name | Ad Reward App Development |
| Scope | Full-stack development (web, mobile app, admin console, settlement structure) |
| Technologies | Next.js 14, React Native, Expo, TypeScript, Prisma, PostgreSQL, Toss Payments, Firebase Cloud Messaging |
Planning a similar project?
Share your requirements and timeline, and we will outline a suitable scope and setup.
Comments 0
Be the first to leave a comment.