Penned — send, sign, and get paid in a single link

How I designed and built Penned, a proposal platform that turns send, sign, and get paid into a single link. React, TypeScript, Supabase, and Stripe.

Visit the website
Stage
Waitlist open
Penned landing page reading Proposal software that closes deals, with Join the waitlist and Browse templates buttons above a mocked proposal window

Penned is an all-in-one proposal platform: send a proposal, collect an e-signature, and take payment from a single link. Built on React, TypeScript, Supabase, and Stripe. It's my own product, currently pre-launch with the waitlist open at getpenned.xyz.

Context

Closing a deal as a freelancer or small agency usually means a relay race across four tools: a proposal PDF from one app, a signature request from another, an invoice from a third, and a payment link from a fourth. Every handoff is a place for the deal to stall. The client opens the proposal Tuesday, the signature request lands Thursday, the invoice goes out the following week — and somewhere in there, momentum dies.

Penned collapses that into one link. The client reads the proposal, signs it, and pays — same page, same session. The moment of "yes" and the moment of payment stop being days apart.

Constraints

  • Signatures and payments demand correctness. A bug in a blog is a typo; a bug in an e-signature or payment flow is a legal and financial problem. The stack had to make the risky parts boring.
  • Solo build. One developer shipping design, frontend, backend, and integrations meant choosing tools that do heavy lifting out of the box.
  • The single-link promise is non-negotiable. The whole product thesis is "no second email, no third tool." Any feature that broke that flow didn't ship.

The build

1. Supabase as the backend

Auth, database, and row-level security from Supabase instead of a hand-rolled backend. For a solo build handling contracts and payment state, this was the highest-leverage decision: Postgres with policies enforcing who can see which proposal, without me writing and maintaining an API layer for every table.

2. Stripe for payments, natively in the proposal

Payment isn't a link to somewhere else — Stripe is integrated into the proposal itself. The client signs and pays in the same flow. This is the feature that justifies the product's existence, so it got built into the core document experience rather than bolted on.

3. TypeScript end to end

Proposals move through states — draft, sent, viewed, signed, paid — and money and signatures hang off those states. TypeScript across the whole codebase meant the state machine is checked by the compiler, not by hoping I remembered every edge case.

4. E-signatures in the document, not around it

Signing happens inline where the client is already reading. Every redirect or "check your email to continue" is a chance to lose the deal; Penned removes them.

Results

Penned hasn't launched, so there are no results to report. The waitlist is open and that's the honest status.

What's checkable is the build itself: legally-binding e-signature capture, Stripe payments, and proposal templates, running on Supabase with row-level security, designed and shipped by one person. You can see the product surface at getpenned.xyz.

I'd rather show you a real thing at an early stage than a fake number attached to a finished one.

The product is live at getpenned.xyz.

Want something like this?

Penned is a full SaaS — auth, database, e-signatures, payments — built by one person on a modern stack. If you need a web app that handles real money and real workflows, that's my web apps service; custom builds start from $6,500 (details on pricing). Or just tell me what you're trying to build.