Full-Stack Applications · Backend & Integrations
Khsrni
خسّرني
Subscription payments, entitlements, and administration for an Arabic trivia gaming platform.
- Company
- Fifty Studios Holding Company
- My role
- Software Engineer, Monetization & Administration
- Key result
- ~10,000 platform users
- React
- TypeScript
- Node.js
- Strapi
- SQLite
- UPayments
Overview
Khsrni (خسّرني) is an Arabic trivia game: players compete across question categories, and their results feed leaderboards. The platform has approximately 10,000 users.
The game is free to start, with paid subscription plans. My work is the business layer around the game: how a player subscribes and pays, what a subscription unlocks, how promotions work, and the tools the team uses to run the platform.
Problem and context
A game with an audience needs a way to earn revenue without trusting the client. Payment results arrive from outside the system, sometimes twice and sometimes never, and each one decides whether a player gets paid access.
The team running the platform also needed to see and manage what was happening: users, subscriptions, promotions, and results, without asking an engineer.
My contributions
Designed and developed
My own work
- The subscription purchase flow, from plan selection to confirmed access.
- Server-side payment verification and idempotent settlement.
- Subscription entitlements across the lifecycle: activation, renewal, and expiry.
- Coupons, promotional codes, and free-game codes.
- Administrative user management and account restrictions.
- Leaderboard and statistics APIs.
Integrated
Third-party services I connected
- UPayments as the payment gateway.
Done with the team
Shared work
- Shared subscription utilities and platform features developed with the team.
Built by others
Not my work
- The trivia gameplay engine and the original application, built by the team.
Technical architecture
Subscription payment lifecycle
Conceptual diagram
- 01
Checkout
Plan and coupon, priced on the server
- 02
UPayments
Payment gateway
- 03
Verification
Server asks the gateway
- 04
Settlement
Claimed once, applied once
- 05
Entitlement
Access follows subscription state
- One settlement routine
- The gateway’s server callback and the player’s return to the site both lead to the same settlement code. There is one place where a payment can turn into access.
- Prices live on the server
- The amount charged is computed on the server from the stored plan price and any valid coupon. The client chooses a plan; it never states a price.
- Entitlements resolved on read
- Whether a player has premium access is decided each time it is checked, from the plan and its end date. A scheduled job reconciles stored state for reporting.
- Backend and administration
- Custom controllers and services on Node.js and Strapi provide the payment, subscription, coupon, and statistics APIs, with authorization enforced on the server.
Engineering challenges
Not trusting the payment callback
- Challenge
- Anything that arrives from the browser or over a public callback URL can be forged. Granting a subscription because a request says “paid” is how platforms give access away.
- Approach
- A callback is treated only as a hint that something changed. The server then asks the gateway for the payment’s status itself and grants access only if the gateway’s record matches the order. Outcomes it cannot confirm stay pending.
- Technology
- UPayments API
- Server-side verification
- Strapi services
- Outcome
- Access follows the gateway’s confirmed state, never the client’s claim.
Settling exactly once
- Challenge
- The gateway callback and the player’s success page can arrive at the same moment, and both try to activate the same order. Processing both would extend a subscription twice.
- Approach
- Settlement first claims the payment record with a conditional update from pending to completed, and continues only if that update changed a row. The second arrival finds nothing to claim and does nothing. A late failure message cannot overwrite a completed order.
- Technology
- Atomic conditional updates
- Unique order IDs
- SQL
- Outcome
- Repeated or simultaneous notifications apply a payment once.
Coupons that cannot be gamed
- Challenge
- Discounts create edge cases: expired codes, usage limits, codes applied and then abandoned, and discounts that bring the price to zero.
- Approach
- Coupons are validated on the server for expiry and remaining uses, validated again at settlement, and counted as redeemed only when payment is confirmed. A fully discounted checkout skips the gateway and settles directly.
- Technology
- Server-side validation
- Node.js
- Strapi
- Outcome
- An abandoned checkout does not consume a coupon, and a used-up coupon cannot be replayed.
Access that changes over time
- Challenge
- Subscriptions expire and renew. A lapsed player should fall back to the free plan immediately, and a player who renews early should not lose the days already paid for.
- Approach
- Access is computed when it is checked, from the plan and end date, so expiry needs no job to take effect. Renewals extend from the remaining paid period, and an hourly task keeps stored state accurate for the admin tools.
- Technology
- Scheduled tasks
- Entitlement checks
- Outcome
- Players see the correct plan the moment their subscription state changes.
Results and impact
- Users on the platform
- ~10,000
- Approximate.
- Gateway-verified subscription payments with idempotent settlement
- Coupons, promotional codes, and free-game codes
- Tools for users, subscriptions, and account restrictions
Visuals
No product screenshots published
Screenshots will be added once approved for publication. The cover and the architecture diagram on this page are conceptual illustrations.