Implement a Gumroad webhook endpoint to record valid sales, generate restore codes, and persist sale records in the purchase ledger.
## Summary Implement the Gumroad webhook endpoint that records a valid sale and generates a restore code exactly once. ## Scope - receive Gumroad Ping on a Netlify function - validate and parse the sale payload used by CozyBlock's product - look up an existing record by sale ID before creating anything - generate a restore code on the first valid sale - persist the sale record in the purchase ledger - return clean success/error responses for operational debugging ## Acceptance Criteria - duplicate webhook deliveries do not create duplicate records - successful sales create exactly one purchase record - invalid or unusable payloads fail cleanly - restore code generation happens only on the first successful recording of a sale ## Dependencies - Blocked by #30 - Blocked by #31 - Blocked by #32 ## Notes Keep this focused on webhook ingestion and ledger writes. Claim and restore endpoints are separate work.