product · case study

AffiliateManager

Booking, payments and commission tracking for a business that sells through affiliates. A public booking site, plus portals for the owner and every affiliate, on one Go API.

The problem

The client sold services through independent affiliates. Bookings arrived over chat, payments were checked by hand, and commissions were worked out in a spreadsheet at the end of each month. Nobody, the affiliates included, could easily see where a sale came from or what they were owed.

What I built

Three front ends on one Go API:

  • Booking site. Customers pick a slot, pay and get a confirmation. Built with Next.js.
  • Owner portal. Leads, bookings, affiliates and payouts in one place.
  • Affiliate portal. Each affiliate sees their own leads, sales and earnings.

How it fits together

Customersbook and payOwnerruns the businessAffiliatestheir own salesBooking siteNext.jsOwner portalReactAffiliate portalReactAPIGo: bookings, leads,commissions, payoutsMySQLorders, leads,commissionsRedissessions,response cachePayment providercheckout, paymentwebhooksPeopleFront endsBackendStorage and servicesRESTcheckout
AffiliateManager: three front ends on one Go API

Decisions worth explaining

Attribution is stored on the order

The referral code is captured at booking and saved with the order, together with the commission rate at that moment. Changing an affiliate’s rate later never rewrites past earnings.

Payment webhooks are idempotent

Each provider event ID is recorded in the same transaction that marks an order paid, so a retried webhook is a no-op instead of a double booking.

Every cache key gets an expiry

Early on I cached API responses in Redis with no TTL and ended up with thousands of stale keys next to session tokens. I wrote up the cleanup.

Testing

This is where the QA background shows. Every order state transition has an API test, the payment flow runs against the provider’s sandbox in CI, and a nightly job reconciles paid orders with the provider’s records.

Next projectMidasoo