MyScoreStore
A storefront for musicians to sell their sheet music.
Next.js · Supabase · Stripe · per-buyer watermarking

Customer buys then composer paid then file delivered
The problem
A composer who writes a brass quintet has two bad options. Go through a publisher and give up most of the money and all of the pricing. Or list on a general marketplace, where the work sits next to unrelated PDFs, the branding is somebody else's, and the customer is never really theirs. This is a storefront they can put in a program note or an Instagram bio, with the money landing in their own account.
What I built
- A public storefront at the composer's own handle, with the first page of the score as a preview, the instrumentation and the grade level.
- Upload for the score, audio samples and cover art, with the preview rendered automatically.
- Checkout that pays the composer directly, and delivery the moment the payment clears.
- Every download watermarked for the person who bought it, generated at the moment they ask for it.
- A dashboard for listings, sales, refunds and discounts.
- Reporting and takedown handling, which a site selling notated music needs from day one.
Decisions and tradeoffs
The composer is the merchant, not me
Checkout is a direct charge on the composer's own Stripe account. Their name is what a buyer sees on their statement, and refunds and disputes are theirs to handle. It is more work than running everything through one platform account and paying out later, but it means the sale genuinely belongs to them.
The file is built for one buyer, as they download it
Nothing is stored pre-watermarked, so there is never a finished copy of one person's file sitting around to be handed to somebody else. The same pass strips anything executable out of the PDF, because a sheet music file has no business running code and a site that takes uploads from strangers should not be how one gets delivered. If any of that fails, the download fails. It never falls back to serving the original.
Paid and refunded are two different questions
An order tracks whether it was delivered separately from whether the money stayed. Those really are independent, since an order can be delivered and charged back at the same time, and collapsing them into a single status forces you to lie about one of them. Downloads check the money, so a refund pulls access without erasing the record that the sale happened.
A price floor that discounts cannot get under
Sellers can run a sale across the store, a sale on one piece, or promo codes. Only the largest applies; they never stack. Any discount that would push a price under the floor is dropped completely, and it is checked again at checkout rather than trusting what was set up weeks earlier. A stacking bug should not be able to sell a piece somebody spent three months writing for forty cents.
A freed handle waits two weeks
If a composer gives up their custom handle, it sits unclaimed for fourteen days before anyone else can take it. A link printed in a program note or sitting in a bio should not hand a stranger someone else's storefront the moment it is released.
What you see is a storefront and a buy button. Nearly all of the work is in two places, the money and the file. Both come down to the same question: what would make a composer stop trusting this with their work, and how do I make that structurally hard rather than merely unlikely.