Skip to content

Lemon Squeezy Webhooks: Verify the Event Before Granting Product Access

Separate signed webhook verification, order matching and entitlement updates so a browser redirect or repeated event cannot grant unintended access.

GuideDeveloper tools

By

Updated 2 min read
Lemon Squeezy Webhooks: payment illustration with IndieTools branding

Grant application access from verified payment facts, not from the browser returning to a success page. A Lemon Squeezy webhook handler should authenticate the event, match it to the intended purchase and apply the resulting entitlement only once.

The Lemon Squeezy signing guide describes an HMAC signature over the request payload, sent in the X-Signature header. Verification is the first boundary; business validation remains a separate responsibility.

Preserve the signed payload

Follow the provider's documented verification method against the original request bytes. Parsing and reserializing JSON can change the representation being checked.

Reject missing or invalid signatures before treating the event as an instruction. Keep the signing secret out of logs and client code, and handle malformed signature input safely.

Test a valid fixture, a modified payload and an absent signature in an isolated environment.

Match the purchase to the application

After authenticity is established, verify the relevant store, environment, product or variant and order relationship. Connect the purchase to an application account through a controlled mapping.

Cliptude describes a video-generation product and has a declared Lemon Squeezy association. Its billing implementation is not disclosed. A generation product illustrates why access or credit grants must correspond to the actual purchased offer.

A signed event for a different offer should not accidentally unlock the same entitlement.

Give fulfilment a durable identity

Record enough provider and application references to recognize an already processed event or completed grant. Repeated delivery should not create another allowance or duplicate access record.

Apply related database changes transactionally where the application requires them to agree. Keep an inspectable state for work that was accepted but not fully completed.

External side effects, such as a notification, may need a separate delivery record so retrying fulfilment does not resend everything.

Treat lifecycle changes explicitly

Decide how the application handles refunds, cancellations and other supported events relevant to its commercial model. Do not infer a permanent entitlement from every payment-related event name.

Preserve historical order facts rather than rewriting them to match a newly configured price. Current catalogue settings and past purchases answer different questions.

Document which state transition each accepted event can cause.

Verify recovery, not only success

Test repeated events, delayed events and a failure between verification and fulfilment. Confirm that a retry finishes the same logical operation rather than creating a new purchase.

Also test a valid event with an unexpected account or offer mapping. It should remain unresolved or rejected according to policy, with enough diagnostic context for an operator.

The companion Lemon Squeezy test-mode guide covers safe environment and catalogue checks.

Keep test purchases isolated from real customer access and avoid unnecessary payment details in reports. Record references, expected transitions and observed outcomes.

A robust webhook integration can explain why access was granted, which purchase authorized it and what happened when processing was repeated. That evidence is more valuable than a success screen that merely looks complete. Include an already-fulfilled order in the fixture set and assert that its original access record remains unchanged after replay.

More guide articles