← Back to ERP system builders

Skill · Version 1.0.0

Paddle and Lemon Squeezy integration

Connects Merchant of Record billing events to local customers and access without confusing provider and seller responsibilities.

paddle-lemonsqueezy-mor

Team members using this skill

See how it helps

When is it useful?

Use when integrating Paddle or Lemon Squeezy checkout and subscriptions under the chosen commercial arrangement.

What does it help you do?

  • Maps provider products, prices and checkout metadata to internal tenant identities.
  • Verifies webhook evidence and handles duplicate or reordered lifecycle events.
  • Keeps buyer invoicing, local entitlements and settlement records appropriately separate.

Try asking this

Design subscription activation from verified MoR events, including repeated webhooks and refund changes without duplicate customer invoices. Replay activation and refund notifications in reverse order. Reconcile provider state before changing access, and avoid issuing a second invoice for the same buyer transaction.

Detailed documentation

Read the skill’s original instructions, examples and checks in their authored language.

Details…Show less

Paddle & Lemon Squeezy (Merchant of Record)

Unlike standard payment processors (Stripe, Barion, Adyen) where your company is the legal seller responsible for global VAT/GST/sales-tax registration, calculation and invoicing, Paddle and Lemon Squeezy act as the Merchant of Record (MoR): they sell the product to the end customer in their own name, calculate and remit global taxes, issue the customer-facing tax invoice/receipt, and pay out net revenue to you.

1. Architectural Implications of Merchant of Record

  • Do not double-issue customer tax invoices: when Paddle or Lemon Squeezy is the MoR, the MoR issues the legal buyer invoice and handles B2B VAT ID validation and reverse-charge rules. Do not simultaneously trigger Billingo or Számlázz.hu to issue a duplicate B2C/B2B invoice to the end buyer for the same transaction unless explicitly instructed for a B2B payout settlement invoice to the MoR entity itself.
  • Price and Tax Display: pass customer location or use the MoR's client/server price preview APIs so inclusive vs. exclusive tax amounts (tax_mode) match what the checkout overlay calculates.

2. Paddle Billing (v1 / Modern Paddle API)

  • Catalog Hierarchy: Product -> Price (recurring or one-time) -> Discount.
  • Checkout Correlation (custom_data):
    • When opening Paddle.Checkout.open({ items: [{ priceId, quantity }], customData: { userId, workspaceId } }) or creating a server-side transaction, always pass your internal tenant/user identifiers in custom_data.
    • Paddle copies custom_data onto the resulting transaction and subscription objects.
  • Webhook Verification & Lifecycle:
    • Verify Paddle-Signature header (ts=...;h1=... HMAC-SHA256 over ${ts}:${rawBody}) using the official Paddle SDK or constant-time HMAC check.
    • Core events:
      • transaction.completed: payment succeeded and invoice finalized; provision one-time purchases or confirm renewal.
      • subscription.created, subscription.activated, subscription.updated, subscription.past_due, subscription.paused, subscription.canceled.
    • Plan Changes & Proration: call PATCH /subscriptions/{id} with items and proration_billing_mode (prorated_immediately, prorated_next_billing_period, full_immediately, do_not_bill).
    • Scheduled Changes: inspect subscription.scheduled_change (action: 'cancel' | 'pause' | 'resume', effective_at) — do not revoke access while status === 'active' and a future scheduled_change is pending!

3. Lemon Squeezy Integration

  • Catalog Hierarchy: Store -> Product -> Variant (each billing interval/tier is a distinct variant_id).
  • Checkout Creation (POST /v1/checkouts):
    • Pass checkout_data.custom: { user_id, workspace_id } and lock prefilled email/discount fields where required.
  • Webhook Verification (X-Signature):
    • Verify the hex-encoded HMAC-SHA256 signature in X-Signature against the raw request body using your webhook signing secret.
    • Key events: order_created, order_refunded, subscription_created, subscription_updated, subscription_payment_success, subscription_payment_failed, subscription_payment_recovered, subscription_cancelled, subscription_expired.
    • Note: in Lemon Squeezy, subscription_cancelled means the user canceled future renewals (cancelled: true, status "cancelled" during the grace period until ends_at), whereas subscription_expired fires when access should actually end (ends_at reached). Always check ends_at before revoking access!

Included files 1

  • SKILL.md