Protected Downloads with Supabase, Stripe, R2, and Cloudflare
A practical overview of how ImgKit connects login, checkout, product access, private files, and signed download URLs.
Paid digital products need a boring but important foundation: buyers should be able to pay, sign in, and download the right file without exposing a public ZIP link.
ImgKit uses a simple protected download pattern:
- Supabase handles login.
- Stripe handles checkout.
- The application records product access.
- R2 stores private files.
- Cloudflare Functions return short-lived signed URLs.
Why Protected Downloads Matter
If a paid ZIP file lives in a public folder, anyone with the URL can share it. That may be acceptable for free samples, but it is weak for paid products.
Protected downloads add a server-side check:
- Who is the user?
- Did this user buy the product?
- Is the download asset active?
- Can the server generate a temporary URL?
The user still gets a normal browser download, but the permanent storage path is not public.
Supabase Login
Supabase gives ImgKit an account identity. A buyer signs in with email, then checkout and downloads can be attached to that account.
For early products, email login is enough. Buyers do not need a complicated dashboard just to download a protected file.
Stripe Checkout
Stripe handles the payment session. The buyer starts checkout from the site, pays, and returns to ImgKit.
The server then needs to connect the completed session to product access. That can happen through webhooks and a checkout sync endpoint so the buyer sees access soon after payment.
Product Access
Product access should be separate from generic membership labels. A buyer may own one product but not another.
For ImgKit, the retired Builder Case Study used its own product entitlement. That model still lets future products exist without turning every buyer into a broad subscription member.
R2 Private Storage
R2 stores the actual ZIP package outside the public website bundle. The site does not link directly to the R2 object.
Instead, a download endpoint checks access and asks storage for a temporary URL.
Signed URLs
A signed URL gives temporary access to a private file. If the URL expires after a short window, it is less useful to share permanently.
This is not heavyweight DRM. It is a practical paid-delivery boundary for an MVP.
What ImgKit Learned
The archived ImgKit Builder Case Study page preserves the surrounding implementation decisions: why paid software sales were paused, how protected downloads were shaped, and how the source-code package was tested as a first paid offer.
That context matters because the technical flow is only half the product. The other half is deciding what should be sold first.
FAQ
Why not put paid ZIP files in a public folder?
Public files can be shared directly. Protected delivery lets the server check account access and return short-lived download URLs.
Does Stripe store the file?
No. Stripe handles payment. Product access and download delivery are handled by the application and private storage.
Why use signed URLs?
Signed URLs let a private file be downloaded for a limited time without exposing permanent storage access.