Projects

Kash creator checkout

A creator-checkout demo with server-priced amounts, duplicate-submission handling, and a sales dashboard. Mock payments only.

  • Software

My work on this demo connects creator setup, a checkout interface, and a sales dashboard. The engineering focus was keeping amounts on the server, representing money in integer cents, validating requests, and handling repeat submissions without creating another payment record.

When
April 2026
Where
Playto engineering challenge
Role
Designer and developer
Flow
Creator setup, checkout page, sales dashboard
Money
Prices loaded on the server, stored as integer cents
Payments
Mock payments and simulated receipts
Tools
Next.js, React, TypeScript, Prisma, SQLite, Zod, Vitest

Paying twice with one key

The checkout page makes one idempotency key when it loads and sends it with every submission. The server looks up the price itself, then inserts the payment. The payments table allows each key once, so a repeat fails the insert, and the server returns the payment that already has that key, marked as a replay, without another receipt. Try a retry, a double submit, and a fresh page.

Local simulation. No payment details are collected and no request leaves your browser.

Checkout page 1

Example creator

Sticker pack

$12.00

Shown for display. The server stores 1200 cents and charges from its own price table.

Idempotency key for this page
7f3a9c2e…
Each request sends
Product sticker-pack and this key. No amount.
Simulation controls

Nothing sent yet. This checkout page's key, 7f3a9c2e…, goes with every request it sends.

The buttons need JavaScript. The description above covers each case.

Server and database

Payments table, unique constraint on the key
PaymentKeyAmount, centsRequests with this key
No rows yet.

Simulated receipts logged: 0

Request log

Newest first.

  1. No requests yet.

How it works

A creator picks a handle, a product, and a price. A buyer pays on the creator’s checkout page, and the creator sees each sale, newest first, on a dashboard.

Decisions

  • The client never sends a price. The payment request has no amount field. The server looks up the creator and copies the price from the database, so editing the page cannot change what is charged.
  • Money is an integer number of cents. Prices are stored as cents. Dollar input is parsed with at most two decimal places and an upper bound, which avoids floating-point rounding.
  • Handles are normalized. Handles are trimmed and lowercased on write and on lookup, and limited to letters, digits, underscores, and hyphens.
  • Every request is validated. Request bodies pass through Zod schemas before any database work.
  • Only the last four card digits are kept. The mock card form never stores a full number.

Duplicate submissions

When the checkout page loads, the browser creates one random idempotency key and sends it with every submission from that page, including retries after an error. The payment table has a unique constraint on the key.

The first request inserts the payment and logs a simulated receipt. If the same key arrives again, the insert fails on the unique constraint, and the server loads the payment that already has that key and returns it, marked as a replay, without sending another receipt. Two requests that race each other resolve the same way: one inserts and the other replays. No locks are needed because the database’s unique index decides which one wins.

Tests

Unit tests cover money parsing and request validation, including rejected keys and malformed email addresses.