Staying in sync with webhooks
Webhooks allow Lemon Squeezy to send new data to your application when certain events occur inside your store.
For example, if a subscription renewal is charged, data about the payment can be sent automatically to an endpoint in your app. You can then consume and process this data and update your application so that your users can see this renewal (and, crucially, retain access to your product).
Webhook events
These are the different events for which webhooks are sent:
order_created
order_refunded
subscription_created
subscription_updated
subscription_cancelled
subscription_resumed
subscription_expired
subscription_paused
subscription_unpaused
subscription_payment_failed
subscription_payment_success
subscription_payment_recovered
license_key_created
license_key_updated
To find out what these events reflect in your Lemon Squeezy account, find the detailed run-down in the Webhooks documentation.
Example webhook data
Webhook events are sent as JSON via POST requests to your endpoint.
The data
that is available in each webhook request is either a Subscription, Subscription invoice, Order or License key object. Each of our webhooks follows the same structure as below.
An example subscription_created
event’s request looks like this:
You can see the data
object here is a Subscription object.
If you added custom data to the checkout, it will be available in meta.custom_data
:
When you receive webhooks events to your endpoint, you should update any local data in your app, like an order ID, renewal date, status or update payment method URL.
Alongside the data are relationships to related objects inside Lemon Squeezy. You can use the provided URLs to make sequential GET requests to access, for example, a product variant object using the URL from relationships.variant.links.related
.
Creating webhooks
Setting up webhooks is quick and easy. You can create and manage webhooks from your Lemon Squeezy dashboard or with the API.
From the dashboard
Go to Settings > Webhooks in Lemon Squeezy and click the plus icon.
Specify the endpoint URL you want the data to be sent to in your app, then add a signing secret, which will help validate any requests to your endpoint (read on for information about signing and validating webhooks).
The last step is to select the events you want to be sent to your app. It's recommended to only select the events you need for your app, to limit the amount of requests hitting your service.
With the API
Alternatively you can use the Lemon Squeezy API to create and manage your webhooks.
For example, creating a new webhook requires a simple POST
request, specifying the webhook endpoint you want data sent to, the events you want to subscribe to and a signing secret to keep webhook requests safe and secure.
Find out more about the webhooks API, including viewing, modifying and deleting webhooks, in the Webhooks API docs.
Adding an endpoint to your app
You will need an endpoint in your app that serves as the receiver for all webhook requests. This should accept POST requests and be able to process and/or save each webhook as it is sent.
To tell Lemon Squeezy that a webhook request was recieved OK, return a HTTP 200
response. Any other response code will tell Lemon Squeezy that the webhook failed and the event will be sent again up to three more times. If your app has not returned a HTTP 200
response by the fourth attempt, the event will not be tried again automatically, though you can re-send recent webhooks from your webhooks settings.
We recommend that you store, at least temporarily, webhook events locally (either in your database or a cache) so that you can return the HTTP 200 response quickly and process the data outside of the webhook request. As a bonus, if your app ever fails to process a webhook, you will then have the data to make a bug fix and process it successfully without waiting for it to be resent.
Signing and validating webhook requests
To check that data sent to your specified webhook endpoint is actually from Lemon Squeezy, you should verify the signature that is sent along with the event data.
The signature is sent in the X-Signature
header and is a hash made up of the signing secret you specified when creating the webhook in your Lemon Squeezy account plus the request body.
To verify the webhook is from Lemon Squeezy you should attempt to create a matching hash and check that it matches the signature in the header.
Here is an example of creating the hash in PHP:
For more language examples, go to the Webhooks documentation.
Simulate subscription webhooks in Test mode
We know building an API integration can be difficult, especially when you need to test subscription webhook events that happen in the future and can’t be easily tested via the checkout.
This is why we built a webhook simulation feature. When in test mode, you can manually trigger certain subscription events from your Lemon Squeezy account.
Once you have some subscriptions in your test mode account (you can create these by purchasing products through the test mode checkout) you will see a "Simulate event" option in each subscription’s side panel.
Simply select the event you want to trigger and a matching event will be sent to your endpoint.
Note: If you want to test subscription renewal events (subscription_payment_*
), your subscriptions will have to had a renewal occur first (we create the simulation webhooks based on this data). To get to this point faster, create test subscription products with daily
billing intervals. This way you will get an initial renewal payment the next day and you’ll then see the option to simulate subscription_payment_*
events.