Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/remorses/lemonsqueezy-webhooks
Types and utilities for handling lemon-squeezy webhooks in JavaScript and TypeScript
https://github.com/remorses/lemonsqueezy-webhooks
lemon-squeezy lemonsqueezy webhooks
Last synced: 2 months ago
JSON representation
Types and utilities for handling lemon-squeezy webhooks in JavaScript and TypeScript
- Host: GitHub
- URL: https://github.com/remorses/lemonsqueezy-webhooks
- Owner: remorses
- Created: 2023-03-23T14:33:47.000Z (almost 2 years ago)
- Default Branch: main
- Last Pushed: 2024-07-16T14:59:58.000Z (6 months ago)
- Last Synced: 2024-10-19T18:48:35.319Z (3 months ago)
- Topics: lemon-squeezy, lemonsqueezy, webhooks
- Language: TypeScript
- Homepage:
- Size: 84 KB
- Stars: 22
- Watchers: 2
- Forks: 3
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
## Install
```
npm i lemonsqueezy-webhooks
```## Usage
This package exposes the lemon-squeezy webhooks types and an utility functions to handle webhooks in Node.js
### `nodejsWebHookHandler`
Checks the signature of the request body and parses it to a `WebhookPayload` type.
It also adds a top level `event_name` field to make [Typescript discriminated unions](https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions) work inside `onData`.
## Usage in Node.js
```ts
import { nodejsWebHookHandler } from 'lemonsqueezy-webhooks'const secret = process.env.LEMON_SQUEEZY_WEBHOOK_SECRET
// ... Express app setup
app.post('/webhooks', async (req, res) => {
await nodejsWebHookHandler({
async onData(payload) {
console.log(payload)
// payload.event_name allows TypeScript to infer the type of payload.data
if (payload.event_name === 'order_created') {
// payload.data is an Order
console.log(payload.data.attributes.status)
}
},
req,
res,
secret,
})
})
```## Usage in Next.js (with Node runtime)
You can also see the source code in the Next.js app example in this repo for a full example.
```ts
// api/webhook.ts
import type { NextApiResponse, NextApiRequest } from 'next'
import { nodejsWebHookHandler } from 'lemonsqueezy-webhooks'export const config = {
api: {
// important! otherwise the body signature check will fail
bodyParser: false,
},
}const secret = process.env.SECRET
if (!secret) {
throw new Error('SECRET is not set')
}export default async function handler(
req: NextApiRequest,
res: NextApiResponse,
) {
await nodejsWebHookHandler({
async onData(payload) {
console.log(payload)
if (payload.event_name === 'order_created') {
// payload.data is an Order
console.log(payload.data.attributes.status)
}
},
req,
res,
secret,
})
}
```## Usage in Next.js (with Web Streams)
You can also use the `whatwgWebhooksHandler` function to handle webhooks in Next.js routes that export a `POST` and `GET` handler.
```ts
// api/webhook.tsimport { whatwgWebhooksHandler } from 'lemonsqueezy-webhooks'
const secret = process.env.SECRET
if (!secret) {
throw new Error('SECRET is not set')
}export const POST = (request: Request) => {
return whatwgWebhooksHandler({
async onData(payload) {
console.log(payload)
if (payload.event_name === 'order_created') {
// payload.data is an Order
console.log(payload.data.attributes.status)
}
},
request,
secret,
})
}
```Exported types:
- `WebhookPayload`, the lemonsqueezy json body of a webhook
- `Order`, the `payload.data` type for the events
- `order_created`
- `order_updated`
- `order_deleted`
- `Subscription`, the `payload.data` type for the events
- `subscription_created`
- `subscription_cancelled`
- `subscription_resumed`
- `subscription_expired`
- `subscription_paused`
- `subscription_unpaused`
- `SubscriptionInvoice`, the `payload.data` type for the events
- `subscription_payment_success`
- `subscription_payment_failed`
- `subscription_payment_recovered`
- `LicenseKey`, the `payload.data` type for the events
- `license_key_created`Exported functions
- `nodejsWebHookHandler`, it handles webhooks signature check and parsing. It also adds a top level `event_name` field to the payload to make [Typescript discriminated unions](https://www.typescriptlang.org/docs/handbook/unions-and-intersections.html#discriminating-unions) work and infer the payload.data type under if blocks inside `onData`.
## Sponsors
[**Notaku**](https://notaku.so)
[![Notaku](https://notaku.so/github_banner.jpg)](https://notaku.so)
---
[Licensed under MIT]().