Commet
  • Precios
Iniciar SesiónRegistrarse

Migrar de Lemon Squeezy a Commet

Guía práctica para mover stores, subscriptions y usage records de Lemon Squeezy a Commet, con código lado a lado para cada paso.


Introducción

Lemon Squeezy te puso a vender rápido: checkout hosteado, impuestos resueltos, cero tarea de compliance. Pero desde la adquisición por Stripe venís mirando el roadmap de reojo, tus necesidades de billing superaron a los variants y usage records, y el único SDK oficial es de JavaScript.

Commet también es Merchant of Record, así que impuestos, compliance, refunds y payouts siguen fuera de tu plato. Lo que ganás es un modelo de billing construido para productos SaaS y de IA: planes como fuente de verdad, metering de uso nativo y SDKs en cinco lenguajes.

Saltá directo a cualquier sección:

  • Historia
  • Conceptos
  • SDKs oficiales
  • Crear customers y subscriptions vía API
  • Medir uso / metering
  • Webhooks
  • Impuestos y compliance
  • Precios
  • Conclusión

Historia

Lemon Squeezy se lanzó en 2021 como Merchant of Record para productos digitales — licencias de software, descargas, membresías y subscriptions de SaaS — con un foco fuerte en desarrolladores indie que querían vender globalmente sin tocar compliance fiscal. En julio de 2024, Stripe adquirió Lemon Squeezy, y sus capacidades de Merchant of Record empezaron a alimentar el roadmap de Stripe.

Commet aplica el mismo modelo de Merchant of Record a un segmento específico: productos SaaS y de IA que cobran por consumo. Los planes definen precios y features, las subscriptions facturan solas, y los eventos de uso alimentan cobros medidos, por créditos o por balance, con pricing en moneda local para mercados donde el checkout en USD lastima la conversión.

Como las dos plataformas son Merchant of Record, la cobertura fiscal se traslada sin cambios: la comparación que importa es superficie de API, profundidad de metering y fees. De eso trata el resto de esta guía.

Conceptos

Las dos plataformas son Merchant of Record, así que el modelo de vendedor de registro se traslada. Los objetos de billing mapean así:

Lemon SqueezyCommet
StoreTu organización
Product + VariantPlan (precio, features e intervalos en un solo objeto)
Checkout (URL hosteada)checkoutUrl que devuelve subscriptions.create
SubscriptionSubscription
Customer (creado en el checkout)Customer (creado vía API, idempotente)
Usage records sobre subscription itemsEventos de uso sobre features medidas
DiscountsCódigos promocionales
WebhooksWebhooks (opcionales — el estado es consultable)

La diferencia estructural: en Lemon Squeezy, el checkout es el punto de entrada y el customer se materializa después de la compra. En Commet, el customer y la subscription son objetos de API primero: el checkout es una URL que la API te devuelve.

Estados de subscription

Los ciclos de vida se traducen limpio:

Estado en Commet¿Da acceso?Estado más cercano en Lemon Squeezy
pending_paymentNo— (checkout aún no completado)
trialingSíon_trial
activeSíactive
past_dueSí (período de gracia)past_due
pausedNopaused
canceledNocancelled
expiredNoexpired

Dale acceso con active o trialing, y tratá past_due como período de gracia mientras corren los reintentos de pago.

Modelos de consumo

Cada plan de Commet usa exactamente un modelo de consumo — son mutuamente excluyentes por plan:

  • metered: pago por uso, agregado y facturado a fin de período. Mapea a los variants usage-based de Lemon Squeezy.
  • credits: los clientes compran paquetes de créditos por adelantado; el uso los consume.
  • balance: un balance monetario prepago que se debita por evento, incluyendo pricing por token de IA.

Créditos y balance no tienen equivalente en Lemon Squeezy — son los modelos que los productos de IA necesitan cuando el metering plano queda corto.

SDKs oficiales

Lemon Squeezy publica un solo SDK oficial, en JavaScript. Commet cubre cinco lenguajes más integraciones de framework:

SDK / herramientaLemon SqueezyCommet
Node.js / TypeScript@lemonsqueezy/lemonsqueezy.js@commet/node
Python—commet
Go—commet-go
Java—commet-java
PHP—commet-php
Browser / checkoutLemon.js (overlay, opcional)No hace falta — el checkout es una URL de redirect
Helpers para Next.js—@commet/next (handler de webhooks, helpers de rutas)
Integración con AI SDK—commet-ai-sdk (tracking de tokens)
Integración de auth—commet-better-auth
CLI—CLI commet (commet listen para webhooks locales)

Instalá el SDK de Node.js:

npm install @commet/node

Inicializá el cliente:

lib/commet.ts
import { Commet } from '@commet/node'

export const commet = new Commet({
  apiKey: process.env.COMMET_API_KEY!,
})

Las API keys están separadas por entorno: las keys ck_sandbox_xxx pegan contra tu organización sandbox, así que el mismo código corre en sandbox y producción cambiando solo la key.

Crear customers y subscriptions vía API

En Lemon Squeezy, creás un checkout para un store y un variant; el customer y la subscription nacen cuando el comprador lo completa:

Lemon Squeezy
import { lemonSqueezySetup, createCheckout } from '@lemonsqueezy/lemonsqueezy.js'

lemonSqueezySetup({ apiKey: process.env.LEMONSQUEEZY_API_KEY! })

const checkout = await createCheckout(storeId, variantId, {
  checkoutData: {
    email: 'billing@acme.com',
    custom: { user_id: 'user_123' },
  },
})

// redirigir a checkout.data?.data.attributes.url

Vincular esa compra con tu usuario implica hacer viajar el custom data ida y vuelta por webhooks.

En Commet, creás el customer explícitamente con tu propio ID, después la subscription, y la URL de checkout vuelve en la misma llamada:

Commet
const customer = await commet.customers.create({
  email: 'billing@acme.com',
  id: 'user_123',
})

const subscription = await commet.subscriptions.create({
  customerId: 'user_123',
  planCode: 'pro',
})

// redirigir a subscription.data.checkoutUrl

customers.create es idempotente: si ya existe un customer con el mismo id, devuelve el registro existente. Tu ID de usuario funciona en todos lados; sin tabla de mapeo, sin ida y vuelta de custom data.

Los parámetros que acepta subscriptions.create:

ParámetroTipoDescripción
customerIdstringID de customer de Commet (cus_xxx) o tu ID externo
planCodestringCódigo del plan (alternativa a planId)
planIdstringUUID del plan (alternativa a planCode)
billingIntervalstringweekly, monthly, quarterly, yearly o one_time
initialSeatsobjectCódigos de tipo de seat mapeados a cantidades
skipTrialbooleanSaltear el período de trial del plan
successUrlstringURL de redirect después del pago exitoso

Verificar acceso es una consulta directa:

Commet
const sub = await commet.subscriptions.getActive({ customerId: 'user_123' })

if (sub.data?.status === 'active') {
  // El usuario pagó
}

Cambios de plan y proration

Commet trae una sola política por defecto para cambios de plan: los cambios que benefician al cliente aplican inmediatamente; los que lo perjudican aplican en la renovación.

Los upgrades proratean y toman efecto al instante; los downgrades se programan para el próximo período. Los clientes también pueden cambiar de plan solos a través del Customer Portal — el equivalente en Commet del customer portal de Lemon Squeezy, creado automáticamente por cliente.

Trials

Los trials se definen en el plan, y skipTrial: true los saltea por subscription. Durante un trial la tarjeta se captura pero no se cobra, y Commet emite trial.started, trial.will_end (3 días antes del vencimiento) y trial.converted o trial.expired al final.

Medir uso / metering

Lemon Squeezy soporta billing por uso a través de usage records reportados contra un subscription item:

Lemon Squeezy
import { createUsageRecord } from '@lemonsqueezy/lemonsqueezy.js'

await createUsageRecord({
  quantity: 1,
  action: 'increment',
  subscriptionItemId: 123456,
})

Notá el identificador: el uso se ata a un subscription item ID, que tenés que buscar y almacenar por cliente.

En Commet, el uso se ata al customer y a un código de feature que definís vos, sin IDs intermedios:

Commet
await commet.usage.track({
  customerId: 'user_123',
  feature: 'api_calls',
  value: 1,
  idempotencyKey: 'req_abc123',
})

La lista completa de parámetros:

ParámetroTipoRequeridoDescripción
featurestringSíCódigo de evento de una feature medida (a-z0-9_)
customerIdstringSíID de customer de Commet o tu ID externo
valuenumberNoCantidad consumida. Default 1
idempotencyKeystringNoEvita eventos duplicados
timestampstringNoDatetime ISO 8601. Default: ahora
propertiesobjectNoMetadata clave-valor para debugging

La idempotencyKey evita eventos duplicados: Commet rechaza eventos con una key ya registrada para el mismo customer.

Los chequeos de entitlements corren contra la misma definición del plan, así que podés hacer gating en tiempo real en lugar de descubrir el overage al facturar:

Commet
const { data } = await commet.featureAccess.get({
  code: 'api_calls',
  customerId: 'user_123',
})

if (data.allowed) {
  // Servir el request
}

Billing de tokens de IA

Si cobrás por uso de IA, Commet mantiene un catálogo de precios de más de 180 modelos. Pasá model, inputTokens y outputTokens al mismo método track, y Commet calcula el costo, aplica tu margen configurado y debita el balance del cliente:

Commet
await commet.usage.track({
  customerId: 'user_123',
  feature: 'ai_chat',
  model: 'gpt-4o',
  inputTokens: 1500,
  outputTokens: 300,
})

En Lemon Squeezy, este pipeline — lookup de precio por modelo, margen, débito de balance, facturación de overage — es código que escribís y mantenés actualizado cuando cambian los precios de los modelos.

Mirá usage-based billing para comparar metered, créditos y balance.

Las features medidas también pueden llevar cuotas y límites de seats: Commet emite quota.threshold_reached y quota.exceeded cuando los clientes se acercan a sus límites, y seats.updated / seats.limit_reached para features basadas en seats — señales que de otra forma calcularías desde tus propias tablas de uso.

Webhooks

Lemon Squeezy firma los webhooks con HMAC-SHA256 en el header X-Signature, y la verificación es manual:

Lemon Squeezy
import crypto from 'node:crypto'

const digest = crypto
  .createHmac('sha256', process.env.LEMONSQUEEZY_WEBHOOK_SECRET!)
  .update(rawBody)
  .digest('hex')

if (!crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature))) {
  throw new Error('Invalid signature')
}

const event = JSON.parse(rawBody)

switch (event.meta.event_name) {
  case 'subscription_created':
    // Dar acceso
    break
  case 'subscription_cancelled':
    // Quitar acceso
    break
}

Commet verifica por vos. En Next.js, @commet/next trae un handler tipado:

app/api/webhooks/commet/route.ts
import { Webhooks } from '@commet/next'

export const POST = Webhooks({
  webhookSecret: process.env.COMMET_WEBHOOK_SECRET!,

  onSubscriptionActivated: async (payload) => {
    // Dar acceso
  },

  onSubscriptionCanceled: async (payload) => {
    // Quitar acceso
  },
})

Fuera de Next.js, commet.webhooks.verifyAndParse({ rawBody, signature, secret }) hace el chequeo HMAC y devuelve el payload tipado; la firma llega en el header X-Commet-Signature.

Los eventos que manejás hoy mapean directo:

Evento de Lemon SqueezyEvento de Commet
subscription_createdsubscription.created / subscription.activated
subscription_updatedsubscription.updated
subscription_plan_changedsubscription.plan_changed
subscription_cancelledsubscription.canceled
subscription_payment_successpayment.received
subscription_payment_failedpayment.failed
subscription_payment_recoveredpayment.recovered
order_refundedpayment.refunded

Detalles operativos:

  • Las entregas fallidas se reintentan con backoff exponencial — 8 intentos, de 1 minuto a 6 horas — y después Commet te manda por email el endpoint, el evento y la última respuesta.
  • Para desarrollo local, commet listen localhost:3000/api/webhooks/commet reenvía eventos en vivo a tu máquina, sin herramientas de tunneling.
  • Si tres entregas seguidas fallan, Commet desactiva el endpoint automáticamente y te manda un email de confirmación; reactivalo desde Settings → Webhooks cuando tu receptor esté arreglado.
  • El estado de la subscription es consultable vía subscriptions.getActive, así que los webhooks son notificaciones — no el mecanismo que mantiene tu base de datos correcta.

Impuestos y compliance

Las dos plataformas son Merchant of Record: cada una le vende a tu cliente, calcula y remite impuestos, y absorbe el compliance. Si te sumaste a Lemon Squeezy por su cobertura fiscal, no perdés nada al moverte a Commet.

Las diferencias están en cobertura de mercados y superficie de pagos:

  • Monedas locales en Latinoamérica. Commet cobra planes en ARS, BRL, CLP, COP, PEN, UYU, PYG, BOB, MXN, CAD y EUR, con un precio canónico en USD y la moneda auto-detectada según el país de facturación del cliente en el checkout. Para clientes de LatAm, pagar en moneda local afecta directamente la conversión y las tasas de aprobación de tarjetas.
  • Métodos de pago. Lemon Squeezy soporta tarjetas más PayPal. El checkout de Commet hoy es solo con tarjeta: si el volumen por PayPal importa en tu revenue, tenelo en cuenta al planificar la migración.
  • Refunds y disputas los maneja el Merchant of Record en ambas plataformas. En Commet, los refunds son gratis y las disputas cuestan $15.
  • Payouts son parte del trato de Merchant of Record en los dos lados: la plataforma cobra a tus clientes y te liquida tu revenue neto.

El pricing es regional por diseño. Definís un precio canónico en USD por plan, agregás precios locales solo para las monedas que te importan, y la contabilidad interna queda en USD.

Precios

Las dos plataformas cobran un único fee todo-incluido: procesamiento, impuestos y responsabilidad de Merchant of Record:

Lemon SqueezyCommet
Por transacción exitosa5% + $0.504.5% + $0.40
Procesamiento de pagosIncluidoIncluido
Cálculo y remisión de impuestosIncluidoIncluido
Tarjetas internacionalesIncluidas en el fee base+1.5% (tarjetas no estadounidenses)
DisputasSegún la política vigente de Lemon Squeezy$15 por disputa
Refunds—Gratis

Sobre $500K de revenue anual con tarjeta y una transacción promedio de $25, la diferencia de cabecera — 0.5% más $0.10 por transacción — son $4,500 por año. La brecha crece con la cantidad de transacciones, así que corrélo contra tu propia distribución.

Ninguna de las dos plataformas cobra fees mensuales de plataforma — las dos son take-rate puro, así que el costo escala con el revenue desde la primera transacción.

Detalles completos en la página de precios.

Conclusión

Moverse entre Merchants of Record es una migración contenida: tu historia de impuestos no cambia, y el trabajo se concentra en los objetos de billing.

Hay una cosa que no migra automáticamente, así que planificala: las facturas y órdenes históricas. Mantené acceso a Lemon Squeezy para los registros viejos; Commet genera facturas desde el primer ciclo migrado en adelante.

  1. Modelá tus Products y Variants como planes de Commet con features explícitas.
  2. Reemplazá la creación de checkouts hosteados por customers.create + subscriptions.create → redirect al checkoutUrl.
  3. Cambiá los usage records atados a subscription item IDs por commet.usage.track con tu propio ID de usuario.
  4. Portá los handlers de webhooks: @commet/next elimina la verificación HMAC manual.
  5. Hacé el corte en la renovación, corriendo un ciclo en paralelo para comparar facturas.

La ganancia se concentra en los pasos 2 y 3: tus propios IDs de usuario fluyen por todo el sistema de billing, y las tablas de lookup de subscription items desaparecen.

Probá el flujo completo antes de tocar producción: cada cuenta de Commet incluye un entorno sandbox aislado con tarjetas de prueba y un test clock, así que podés simular un ciclo de billing completo — checkout, uso, renovación — en minutos.

Arrancá con el quickstart, o mirá cómo se compara Commet con Stripe Billing y Paddle.

Desarrolladores

  • Documentación
  • Templates
  • GitHub

Frameworks

  • Next.js
  • Remix
  • Nuxt
  • SvelteKit
  • Astro
  • Express
  • Hono
  • Django
  • FastAPI

Recursos

  • Blog
  • Changelog
  • Precios

IA

  • Agentes
  • Servidor MCP
  • Agent Skills
  • Claude Code
  • Codex
  • Cursor

Aprender

  • Guías
  • Glosario
  • Soluciones
  • Facturación por Modelo de IA
  • Commet VS otros

Comparar

  • Alternativa a Stripe
  • Alternativa a Orb
  • Alternativa a Recurly
  • Alternativa a Paddle
  • Alternativa a Chargebee
  • Alternativa a Lago

Nosotros

  • Nosotros
  • Open Source
  • Términos y condiciones
  • Política de privacidad

Países

  • México
  • Argentina
  • Colombia
  • Chile
  • Perú
  • Ecuador
  • Uruguay
  • Paraguay
  • Bolivia
  • Panamá
  • El Salvador
  • Brasil
XLinkedInGitHub