UpbidA pay-to-rank public leaderboard for Indonesia

Upbid is a public board where anyone can paste a link, pay a bid in rupiah, and see the listing ranked by the total it has been paid. We designed and built the product, its payments and its ledger, in informal Indonesian from the first screen to the receipt.

The Upbid home page on desktop, headed Bayar. Naik. Dilihat orang., with a field for pasting a link, between the same page on a phone and the live board on a phone with the top listings
Client
Upbid
Sector
Advertising
Year
2026
Platforms
Web app, Mobile web
Services
Product and UX design, Web development

A leaderboard that anything with a link can join: a website, an app, a product, a shop or a creator account. The first bid puts a listing on the board, anyone can add to any listing’s total, the highest total sits on top, and a tie goes to whoever reached the total first. Bids are final.

Built for

  • Small businesses, app makers and creators in Indonesia who want to be seen.
  • Visitors who browse the board and click through to what is on it.
  • Anyone who wants to move a listing up, their own or someone else’s.

The problem

The idea fits in one sentence, and every part of it involves money. A bid has to land on the board exactly once, in the right position, even when two people pay at the same moment or a gateway sends the same notification twice.

Indonesian buyers pay with QRIS, e-wallets, bank virtual accounts and minimarket counters, and a gateway can switch its channels on and off while it reviews a merchant. The product has to offer only what the live gateway serves on the day.

Every listing starts as a link typed by a stranger. Fetching that link to build a preview card opens a way into the server unless the fetch is locked down.

Goals

  1. 01Put a listing on the board from nothing but a link, with no account.
  2. 02Make every rupiah traceable, with the board built from an append-only ledger.
  3. 03Confirm a payment only from the gateway itself.
  4. 04Keep taking orders when one gateway is down.
  5. 05Write the whole product in the informal aku/kamu register.

Our role

We designed, built and run Upbid.

What we delivered

  • Product rules: floor bid, step, ties, final bids and claim links
  • Board, listing pages, how to play, rules, terms, privacy and statistics
  • Paste-a-link entry with previews from websites, app stores, GitHub and social links
  • Payments through DOKU and Midtrans behind one interface, with signed webhooks
  • Append-only ledger and rank history in PostgreSQL
  • Receipts and claim links by email and WhatsApp
  • Self-hosted analytics, and deployment on a VPS

How we worked

  1. 01

    Write the rules down first

    The floor bid, the step, tie-breaking, refunds and who receives the claim link were fixed before the screens. The money rules live in one file and again in Postgres check constraints, so the database refuses an amount the code would refuse.

  2. 02

    Treat money as a ledger

    Bids are rows that are never edited. Totals, ranks and every movement chip on the board are derived from them, and each change of rank is recorded with the payment that caused it.

  3. 03

    Put two gateways behind one door

    DOKU and Midtrans are adapters behind a single payment interface, and a setting decides their order. A gateway that is down hands the order to the next one before the buyer sees anything. Once a QR code or account number is on screen, the order stays where it is.

  4. 04

    Lower the floor after launch

    After the first weeks the floor bid came down from Rp20.000 to Rp2.000 and the step from Rp5.000 to Rp1.000. The change went through the code, the copy and three database constraints in one release.

Screens and features

  • A link is all it takes

    Paste a website, an App Store or Play Store link, a GitHub repository or a social account, and the card fills itself with a name, a description and an image. Nobody needs an account to bid.

  • An overtake price on every row

    Each row shows the exact amount that would move it one place up: the total of the row above, plus Rp1.000.

  • Chips that say what happened

    Naik, kesalip and pegang #1 sejak Sabtu (holding #1 since Saturday) come from the rank history, written in the same transaction as the bid that caused them.

  • A locked-down link fetcher

    The only code that fetches a user’s link checks every address against private ranges, pins the connection to the checked address, re-checks each redirect and stops at 5 seconds or 2 MB. Links can also be screened with Google Web Risk.

  • Payments confirmed by the gateway

    A webhook is a reason to look. After its signature checks out, the settle step asks the gateway for the payment’s status and records the bid from that answer.

  • Ways to pay that match the gateway

    The payment methods named on the page and in the rules come from a setting listing what the live gateway serves, so the copy names only channels that are switched on.

  • A claim link for the first payer

    The receipt, by email or WhatsApp, gives the first person to pay for a listing a private link, valid for 90 days, to edit its card and see its clicks.

Technical choices

What the product is built with, and why.

Next.js 16 with Cache Components
The board and listing pages are cached on the server and dropped after a settled payment or a counted click, so the board is fresh after every change and cheap to serve between them.
PostgreSQL 18 with Prisma 7
Recording a bid takes one lock for the whole board, so two settlements never re-rank at the same time. A unique index on the payment makes a second settlement of the same payment do nothing.
DOKU first, Midtrans second, behind one port
Failover happens only before a checkout exists. A gateway that is down passes the order on; a gateway that refuses the request stops it, because the same request would be refused everywhere.
An own fetcher on undici
Pinning each connection to the address that passed the check closes the DNS rebinding gap that a check-then-connect fetcher leaves open.
Self-hosted Umami
Visit counts stay on the same server in their own database, with no cookies, and session replay and heatmaps switched off. The privacy page names it.
Vitest and a Playwright scenario suite
Unit tests cover the money and ranking rules, and a browser suite runs checkout scenarios against the gateway’s sandbox.

Building something that takes payments?

Ledgers, gateways and the edge cases between them are work we enjoy. Tell us how your customers pay.