Selling software licenses on Gumroad
Selling software licenses on Gumroad
Connect a Gumroad account to LicenseSeat and sales of linked products issue license keys; eligible email delivery sends them to the buyer. Membership renewals extend the license. No app to install and no API key to create: the connection uses Gumroad's built-in Ping, a one-line setting in your Gumroad account.
One thing to know up front: Gumroad's Ping reports sales only. Refunds are not sent to LicenseSeat, so a refund does not revoke the license by itself (see Refunds below).
Setup takes about three minutes.
Before you start
Link the product to a license plan before testing. Automatic license emails require an eligible LicenseSeat plan, Settings → Organization → Email license keys to my customers enabled, and a valid buyer email. Issuance can succeed without sending an email. Use a separate test organization when you need complete separation: connections in one organization share product mappings by provider.
Read Email delivery, subscription expiry and event recovery for the common prerequisites and recovery procedure. Setup instructions remain available on the connection page after saving.
1. Create the connection in LicenseSeat
In the LicenseSeat dashboard sidebar open Connected platforms, click Connect Your First Platform (or Connect Another), choose Gumroad, and give the connection a name. The page shows your webhook URL. Copy it. Keep it private: Gumroad does not sign its pings, so the random part of this URL is the only thing stopping someone else from issuing licenses for your products.
2. Paste the URL into Gumroad
In Gumroad go to Settings → Advanced (gumroad.com/settings/advanced) and scroll to the Ping section:
| Field | Value |
|---|---|
| Ping endpoint | your LicenseSeat webhook URL from step 1 |
Then click Update settings at the top of the page.
Gumroad has one Ping URL per account, so this URL now receives every sale from every product you sell. LicenseSeat only acts on the products you link in step 3 and ignores the rest.
3. Link your products
Tell LicenseSeat which license plan to issue for each Gumroad product. On the connection page click Link Product, pick the plan, and paste the product's Gumroad URL.
To get the URL, open the product in Gumroad, click Share, then Copy URL. It looks like https://you.gumroad.com/l/your-product. Pasting the whole URL works; LicenseSeat keeps the part after /l/.
Two Gumroad details worth knowing:
- Every product has a default short link (the one ending in a code such as
/l/QaSmj) that keeps working even after you give the product a custom URL. Either form works here. - If you later rename a custom URL in Gumroad, the old one stops matching (Gumroad does not redirect old custom URLs). Update the linked product in LicenseSeat too.
4. Test it
Three levels, from cheapest to most complete:
- Reachability. In Gumroad's Ping section click Send test ping to URL. Gumroad re-sends your most recent sale with
test=trueand tells you the HTTP status LicenseSeat answered with. The LicenseSeat connection page shows Last webhook received. No license is issued: LicenseSeat deliberately ignores test pings. If your account has no sales yet, Gumroad says "There are no sales on your account to test with. Please make a test purchase and try again." - Test purchase. Stay logged in to Gumroad, open your product page, click I want this!, and at checkout pay with the Test card that Gumroad shows to the product's owner. You are not charged. The ping arrives marked
test=true, so again LicenseSeat updates the connection’s received timestamp but creates no payment event or license. - Real rehearsal. Create a 100% discount code in Gumroad and buy the product from a different email address. That is a real sale: the license is issued and emailed to that address. This is also how Gumroad itself recommends testing sale-triggered automations. Do not buy your own product with a real card; Gumroad warns that this looks like card testing and can get the account suspended.
What happens on each event
| What happens in Gumroad | LicenseSeat |
|---|---|
| A product is bought (one-time) | Issues a license for the linked product, owned by the buyer's email, and emails the key. Quantity follows the purchase (multi-seat licenses on Gumroad arrive as a quantity). |
| A membership is started, including a free-trial signup | Issues the license the same way. |
| A membership renews (each recurring charge) | Extends the existing license issued for that membership. |
| A membership is cancelled or ends | Nothing arrives. The license is simply not extended again. |
| A sale is refunded | Nothing arrives. See Refunds. |
| Test ping or logged-in test purchase | Connection received timestamp updated; no payment-event row or license. |
| A sale of a product you have not linked | Ignored. |
Refunds
Gumroad's Ping only carries sales. When you refund a sale in Gumroad, nothing is sent to your Ping URL, so LicenseSeat cannot revoke the license automatically. After refunding, open the license in LicenseSeat and revoke it there.
Optional: automatic revocation through Gumroad's API
Gumroad does offer refund notifications through its API, as a "resource subscription". Setting one up takes an access token:
-
In Gumroad go to Settings → Advanced, scroll to Applications, and click Create application (any name; for the Redirect URI Gumroad's help says to enter
http://127.0.0.1when you only need a token for your own account). Then click Generate access token. Treat the token like a password. -
Subscribe your LicenseSeat webhook URL to the
refundresource:curl https://api.gumroad.com/v2/resource_subscriptions \ -d "access_token=ACCESS_TOKEN" \ -d "resource_name=refund" \ -d "post_url=YOUR_LICENSESEAT_WEBHOOK_URL" \ -X PUTor, with Gumroad's CLI:
gumroad webhooks create --resource refund --url YOUR_LICENSESEAT_WEBHOOK_URL.
From then on a full refund in Gumroad revokes the license and emails the buyer. Partial refunds do not revoke: Gumroad keeps the buyer's access after a partial refund, and so does LicenseSeat. The API subscription is tied to the token; if you delete the application or revoke the token, refund notifications stop.
Good to know
-
Existing perpetual mappings. Subscription purchases still issue on a perpetual plan. Events that identify a subscription show a warning; cancellation does not revoke lifetime access. Existing perpetual licenses remain perpetual on renewal. Choose a finite plan for access that should expire, and review subscription access and recovery before changing existing mappings.
-
Membership expiry and trials. Use a finite license plan matching the billing interval. Initial signup grants that duration, including for a free trial; it does not synchronize Gumroad’s trial end. Renewals use the sale timestamp plus the plan duration. Cancellation sends no Ping and does not revoke; access ends at the stored expiry without another renewal.
-
Fully refunded delayed sales. If an old sale is delivered with
refunded=true, LicenseSeat treats it as a reversal instead of granting fresh access. This does not make basic Ping a refund subscription. -
Existing product mappings. Legacy mixed-case and custom-domain URLs continue matching without a database rewrite. If multiple legacy mappings normalize to the same identifier, fulfillment fails visibly; remove the ambiguity and retry instead of letting an arbitrary plan win.
-
No signing secret. Gumroad has no webhook signature. LicenseSeat identifies your account by the long random token in the webhook URL, which is why that URL must stay private. Use the HTTPS URL LicenseSeat gives you; Gumroad recommends HTTPS endpoints.
-
Retries. Gumroad delivers at least once and retries a failed delivery with increasing delays (consult the current Ping reference for its delivery schedule), only for HTTP 499/500/502/503/504, and gives the endpoint 5 seconds to answer. LicenseSeat answers immediately and processes in the background; a re-delivered sale is recognised by its
sale_id, so a sale never issues twice. -
Amounts and currency. Gumroad reports the price paid in USD cents regardless of the product's listed currency; that is what LicenseSeat records on the event.
-
Multi-seat licenses. If the Gumroad product lets buyers choose a number of seats, the ping's quantity is the seat count and LicenseSeat issues that many licenses.
-
Gifts. A gifted product pings once, for the recipient's purchase; the license goes to the recipient's email.
Troubleshooting
- The connection stays "Incomplete". No product is linked yet. Gumroad needs no secret, so linking a product is the only requirement.
- The connection stays "Awaiting webhook" after a test ping or test purchase. Expected: those carry
test=trueand update the received timestamp without creating a payment event. The status flips on the first real sale of a linked product (a 100% discount code from another email counts). - The event shows as "ignored" with "no active mapping". The product URL you linked does not match what Gumroad sent. Open the product in Gumroad, click Share → Copy URL, and compare; if you renamed the custom URL, relink with the new one (or use the default short link, which never changes).
- Gumroad's test ping reports a non-2xx status. Gumroad shows the status it received. A 404 means the URL is wrong or the connection was deleted; a 400 means the request was malformed (Gumroad itself never sends one, so something is rewriting the request between Gumroad and LicenseSeat).
- A refund did not revoke. Basic Ping does not send refunds; revoke manually or configure the API subscription above. With an API subscription, verify a full refund delivered
resource_name=refundandrefunded=true, then inspect/retry the LicenseSeat event.
References
These are Gumroad's own pages. If a label or menu in Gumroad ever differs from this guide, they are the source of truth:
-
Gumroad Ping — the mechanism this integration uses: the HTTP POST, the full parameter table (
sale_id,product_permalink,short_product_id,email,price,quantity,subscription_id,is_recurring_charge,refunded,test,resource_name), delivery guarantees, retries and the 5-second timeout. -
Account settings — the Settings page, the "Update Settings" button, and what the Advanced tab holds (custom domain, blocked emails, Ping, API applications).
-
Customize and share your product's URL — Share → Copy URL, and how to change the URL suffix.
-
Custom product URLs — the
username.gumroad.com/l/QaSmj→/l/poetryclubrename, the fact that old custom URLs do not redirect, and that the default link keeps working. -
Testing a purchase — the logged-in Test card flow and the warning against paying yourself with a real card.
-
Send automated emails with Workflows — Gumroad's own advice to rehearse sale-triggered automations with a 100% discount code from another email.
-
Issuing a refund — full vs partial refunds; buyers keep access after a partial refund.
-
Selling memberships and subscriptions — how memberships, free trials and recurring charges work.
-
Gumroad API: resource subscriptions — the API-only notifications (
sale,refund,dispute,dispute_won,cancellation,subscription_updated,subscription_ended,subscription_restarted). -
Create an application for the API — Create application and Generate access token under Settings → Advanced.
-
Gumroad CLI —
gumroad webhooks create --resource <name> --url <url>. -
Gumroad Ping payload implementation (pinned) — exact payload and refunded/test flags used for this audit.