AtlatestRenderedmarkdown
Readme

sigil-lemonsqueezy

Lemon Squeezy API client library for Sigil. Provides functions for managing products, checkouts, orders, subscriptions, webhooks, and license keys via the Lemon Squeezy API.

Features

  • JSON:API parsing — Helpers for extracting data, attributes, relationships, and included resources from JSON:API responses
  • Products & Variants — List and retrieve products and their variants
  • Checkouts — Create checkout URLs with custom data, product options, and pricing overrides
  • Orders & Order Items — List and retrieve orders and line items
  • Subscriptions — List, retrieve, update, and cancel subscriptions
  • Webhooks — CRUD operations plus HMAC-SHA256 signature verification
  • License Keys — Manage keys via the main API; validate, activate, and deactivate via the unauthenticated License API
  • Pagination — Built-in support for page-based pagination and filtering

Modules

ModuleDescription
(lemonsqueezy)Core client, auth, JSON:API helpers, pagination
(lemonsqueezy product)Products and variants
(lemonsqueezy checkout)Checkout creation and retrieval
(lemonsqueezy order)Orders, order items, subscriptions
(lemonsqueezy webhook)Webhook CRUD and signature verification
(lemonsqueezy license)License key management and validation

Quick Start

(import (lemonsqueezy)
        (lemonsqueezy product)
        (lemonsqueezy order)
        (lemonsqueezy checkout))

;; Create a client with your API key
(define client (ls-client api-key: "your-api-key"))

;; List products
(define products (ls-products client))
(for-each (lambda (p)
            (display (ls-product-name p))
            (display " - ")
            (display (ls-product-price-formatted p))
            (newline))
          products)

;; Get a single product
(define product (ls-product-get client "123"))

;; Create a checkout with custom data
(define checkout
  (ls-create-checkout client "1" "10"
    #{ checkout-data: #{ email: "[email protected]"
                         custom: #{ user_id: "42" } } }))
(display (ls-checkout-url checkout))

;; List orders with filtering
(define orders
  (ls-orders client #{ filter: #{ store_id: "1" } }))

Webhooks

Verify incoming webhook signatures and parse event payloads:

(import (lemonsqueezy)
        (lemonsqueezy webhook))

;; Verify the X-Signature header
(if (ls-verify-webhook signing-secret raw-request-body x-signature-header)
    (let ((event (parse-webhook-event raw-request-body)))
      (let ((event-name (ls-webhook-event-name event))
            (custom-data (ls-webhook-event-custom-data event)))
        ;; Dispatch by event name
        (cond
          ((string=? event-name "order_created")
           ;; Grant access using custom_data.user_id
           (grant-access (dict-ref custom-data user_id:)))
          ((string=? event-name "subscription_expired")
           ;; Revoke access
           (revoke-access (dict-ref custom-data user_id:))))))
    (error "Invalid webhook signature"))

License Keys

The License API endpoints (validate, activate, deactivate) do not require an API key and are designed for use in client applications:

(import (lemonsqueezy license))

;; Validate a license key (no auth needed)
(define result (ls-validate-license "38b1460a-5104-4067-a91d-77b872934d51"))
(if (ls-license-validation-valid result)
    (display "License is valid!")
    (display "License is invalid"))

;; Activate a license key
(define activation
  (ls-activate-license "38b1460a-5104-4067-a91d-77b872934d51" "mysite.com"))

;; Deactivate
(ls-deactivate-license "38b1460a-5104-4067-a91d-77b872934d51" "instance-uuid")

JSON:API Helpers

Lemon Squeezy uses JSON:API format. The core module provides helpers:

;; Extract data from a response
(jsonapi-data response)           ; single resource
(jsonapi-data-list response)      ; list of resources
(jsonapi-attr resource name:)     ; get attribute
(jsonapi-attrs resource)          ; full attributes dict

;; Relationships
(jsonapi-relationship-id resource store:)     ; single relationship ID
(jsonapi-relationship-ids resource variants:) ; has-many relationship IDs

;; Included resources
(jsonapi-included response)                           ; all included
(jsonapi-find-included response "variants" "10")      ; find by type+id

;; Pagination
(jsonapi-pagination-meta response)  ; => #{ current-page: 1 last-page: 3 ... }
(ls-paginate (lambda (page) ...))   ; auto-paginate all pages

Pagination and Filtering

All list endpoints accept an options dict:

;; Paginate
(ls-products client #{ page: 2 per-page: 50 })

;; Filter
(ls-subscriptions client #{ filter: #{ status: "active" product_id: "1" } })

;; Include related resources
(ls-products client #{ include: "variants,store" })

;; Auto-paginate all pages
(ls-paginate
  (lambda (page)
    (ls-get/json client
      (string-append
        (ls-api-url client "v1" "products")
        (build-query-string (ls-list-params #{ page: page per-page: 100 }))))))

Building

sigil deps install
sigil build
sigil test

Dependencies

  • sigil-stdlib (core, dict, string, struct, crypto)
  • sigil-http (HTTP client)
  • sigil-json (JSON parsing)

API Coverage

ResourceOperations
Productslist, get
Variantslist, get
Checkoutscreate, get, list
Orderslist, get
Order Itemslist, get
Subscriptionslist, get, update, cancel
Webhookscreate, get, list, update, delete, verify
License Keyslist, get, update (main API)
License APIvalidate, activate, deactivate (no auth)

License

BSD-3-Clause