Purchases namespace

Reference for the digital product download page, downloads, reviews and the buyer's library.

Every digital product purchase has a download page reached by its purchase token, the secret in the link the buyer is emailed (downloadUrl from checkout). board.purchases reads that page, signs downloads, records the buyer's review, resends the link and lists a signed-in user's purchases.

Render the download page at your board's purchase route (by default /purchases/<token>, from purchasePath(token) in @cavuno/board/paths). Never put purchase paths in a sitemap, analytics or a shared cache key.

The first open of a download link and the buyer's own signed-in account pass straight through. On a board built with Cavuno's AI Builder, so does the visitor IP that bought it; a frontend that calls the API from its own server sends every visitor from one address, so there the IP is never used. Anyone else opening a forwarded link gets purchase_email_confirmation_required (403) and must type the purchase email with confirmEmail.

Responses that pass the check return a confirmationToken. The API also sets it as an HttpOnly cookie, but a frontend that calls the API from its server should keep the token itself (for example in its own cookie for that purchase) and pass it back as the confirmationToken option, which sends the X-Cavuno-Purchase-Confirmation header.

board.purchases.get()

The download page: product summary and thank-you message, files and links with their state (ready, preparing while the buyer's stamped PDF is made, limit_reached), downloads left, receiptUrl, the refund policy and the buyer's own review.

board.purchases.confirmEmail()

Checks the typed email. A match returns confirmationToken; a mismatch is purchase_email_mismatch. Attempts are throttled per link.

board.purchases.download()

Counts one download and returns a signed, short-lived url that downloads as an attachment. Redirect the browser to it right away. purchase_file_preparing (409) means the stamped copy is still being made; the buyer is emailed when it is ready and nothing was counted. purchase_download_limit_reached (409) means no downloads are left for that file; it is not a rate limit, so do not retry (the board can reset the buyer's downloads).

board.purchases.downloadAll()

Counts every ready file and returns a short-lived link to a single ZIP. Files still being stamped or out of downloads are listed in preparing and limitReached.

board.purchases.review()

One review per purchase (stars 1 to 5, optional comment and displayName); writing again replaces it. Returns product_reviews_disabled when ratings are off and purchase_refunded for refunded purchases.

board.purchases.resend()

"Email me this link again" for an email (and optionally one productSlug). Always accepted, so it never reveals whether the email bought anything. Render the website honeypot hidden and leave it empty.

board.purchases.mine()

The signed-in board user's purchases: those made while signed in and those made with their verified email. Each row carries downloadUrl. Requires a board user session.

Errors

purchases_not_found, purchase_file_not_found, purchase_email_confirmation_required, purchase_email_mismatch, purchase_awaiting_payment, purchase_access_removed, purchase_unavailable, purchase_refunded, purchase_file_preparing, purchase_download_limit_reached, purchase_download_all_unavailable, purchase_review_invalid, product_reviews_disabled, rate_limited and rate_limit_unavailable.