Skip to content

Setup LemonSqueezy

The LemonSqueezy integration in ShipFlutter consists of three main components:

  • Directoryapp/web/payment/
    • lemon_squeezy.js // Web SDK integration
  • Directoryapp/lib/core/account/payments/web/
    • web_payments_service.dart // Dart-JS interop
  • Directoryfunctions/src/payment/
    • lemon_squeezy.ts // Webhook handler & API

Structure

  1. Web SDK Integration (lemon_squeezy.js)

    • Loads the LemonSqueezy script dynamically
    • Handles checkout flow and events
    • Communicates purchase results back to Flutter
  2. Dart Integration (web_payments_service.dart)

    • Platform-specific implementation for web
    • Uses JS interop to communicate with LemonSqueezy SDK
    • Handles purchase flow, entitlement updates and paywall retrival
  3. Server Integration (lemon_squeezy.ts)

    • Processes webhook events (subscriptions, orders)
    • Syncs products with Firestore
    • Manages user entitlements

Setup

The LemonSqueezy integration has three main components:

  1. Creating a product (Paywall) and variants
  2. Setting up a webhook
  3. Enable API

Prerequisites

  1. A Lemon Squeezy account
  2. An approved store

Creating a product (Paywall)

LemonSqueezy does not has a Paywall concept, but products are the equivalent. You can define a description and variants (pacakge).

A variant in LemonSqueezy can be a single payment option or a subscription (e.g weekly, monthly, etc..).

  1. Go to https://app.lemonsqueezy.com/products

  2. New product

  3. Fill the name and description

  4. Add a variant

  5. Define the variant name and description

  6. Select pricing model (single or subscription)

  7. Fill mandatory info

  8. Save and add other variatns if you want (e.g Weekly, Monthly, Yearly)

  9. Ignore the rest of options and save the product.

Configure Webhooks

This is crucial to ensure entitlements are updated in the app.

  1. Go to https://app.lemonsqueezy.com/settings/webhooks

  2. Click the ’+’ button

  3. Use your deployed Firebase Function as Callback URL

    https://LOCATION-PROJECTID.cloudfunctions.net/api/v1/payment/event/ls
  4. You can define a secret and check it matches in the function (ignored by default)

  5. Select the event types based on your product type:

    1. order_created (for one-time payments)
    2. subscription_created
    3. subscription_updated
  6. Save webhook.

Configure LemonSqueezy API

The LemonSqueezy API is required to sync the products from the store to the Firestore database.

  1. Create an API key

  2. Copy the API key and save it to the functions/.env file.

    KEY_LEMON_SQUEEZY_API=xxxx
  3. Deploy Firebase functions

  4. Call the /api/v1/payment/sync/ls endpoint with the product ID as a path parameter

    Terminal window
    curl -X POST https://{{LOCATION-PROJECTID}}.cloudfunctions.net/api/v1/payment/update/ls/{{PRODUCT_ID}}

Troubleshooting

Here are some common issues you might encounter:

Products not showing up

  1. Missing API Key

    Terminal window
    Error: Missing LemonSqueezy API key

    Make sure you have added KEY_LEMON_SQUEEZY_API to your functions/.env file and deployed the functions.

  2. Test Mode Products

    Terminal window
    Error: Product not found or invalid store ID

    If you’re using test mode, make sure to:

    • Use test mode product IDs
    • Enable test mode in your store settings
    • Test purchases with test card numbers
  3. Product Sync Failed

    Terminal window
    Error: Failed to sync products
    • Check if the product ID is correct
    • Verify the product is published and active
    • Try syncing again with the update endpoint