Skip to content
revenue-sdk
Esc
navigateopen⌘Jpreview
On this page

Capability matrix

The full per-provider RevenueCapabilities reference for Polar, Lemon Squeezy, Stripe, Paddle, and Dodo Payments.

A complete reference of the RevenueCapabilities values each provider reports. Every provider exposes this object as capabilities, also surfaced on client.capabilities. The client gates on these values and throws unsupported rather than silently dropping an option — see Capabilities.

Matrix

Capability Type Polar Lemon Squeezy Stripe Paddle Dodo Payments
cancellationReason boolean true false true false true
checkoutCustomAmount boolean true true false false false
checkoutExpiresAt boolean false true true false false
checkoutStatus boolean true false true true true
checkoutSuccessUrl boolean true true true false true
customerMetadata boolean true false true true true
endTrial boolean true true true true false
hostedCheckout boolean true true true false true
licenseKeys boolean true true false false true
listOrdersByCustomer boolean true false true true true
listSubscriptionsByCustomer boolean true false true true true
pause boolean true true true true false
pauseBehaviors PauseBehavior[] period_end immediately immediately immediately, period_end []
portalReturnUrl boolean true false true false true
prorationBehaviors ProrationBehavior[] invoice_now, prorate invoice_now, prorate, none invoice_now, none, prorate invoice_now, none, prorate invoice_now, none
revoke boolean true false true true true
uncancel boolean true true true true true
usageReporting boolean true false true false true

The in-memory provider from revenue-sdk/testing reports every capability true, all three proration behaviors and both pause behaviors, and accepts a Partial<RevenueCapabilities> override — see Testing provider.

What each field gates

PropType
cancellationReason?boolean

Whether subscriptions.cancel forwards reason/comment. Passing either without support throws unsupported.

Typeboolean
checkoutCustomAmount?boolean

Whether checkouts.create accepts customAmount, the buyer-chosen price of a pay-what-you-want product. Passing it without support throws unsupported.

Typeboolean
checkoutExpiresAt?boolean

Whether checkouts.create accepts expiresAt. Passing it without support throws unsupported — Polar, Paddle, and Dodo Payments apply a fixed lifetime instead.

Typeboolean
checkoutStatus?boolean

Whether Checkout.status is populated. When false, status is always null (Lemon Squeezy checkouts carry no lifecycle status).

Typeboolean
checkoutSuccessUrl?boolean

Whether checkouts.create accepts successUrl. Passing it without support throws unsupported (Paddle configures redirects in Paddle.js).

Typeboolean
customerMetadata?boolean

Whether customers.create and customers.update accept metadata. Passing it without support throws unsupported (the Lemon Squeezy customer object has no metadata field).

Typeboolean
endTrial?boolean

Whether subscriptions.endTrial is supported. Calling it without support throws unsupported.

Typeboolean
hostedCheckout?boolean

Whether checkouts.create returns a ready-to-use provider-hosted URL. When false (Paddle), the URL is your own Paddle.js page and needs a configured default payment link plus an approved domain.

Typeboolean
licenseKeys?boolean

Whether the licenseKeys namespace is supported. Calling any of its methods without support throws unsupported (Stripe has no license API; Paddle Billing v1 dropped license keys). Validating and activating keys needs no client at all — see the provider subpath exports.

Typeboolean
listOrdersByCustomer?boolean

Whether orders.list/listAll accept customerId. Passing it without support throws unsupported (Lemon Squeezy filters orders by store, user email, and order number only). Listing unfiltered works everywhere.

Typeboolean
listSubscriptionsByCustomer?boolean

Whether subscriptions.list/listAll accept customerId. Passing it without support throws unsupported.

Typeboolean
pause?boolean

Whether subscriptions.pause and subscriptions.resume are supported. Calling either without support throws unsupported.

Typeboolean
pauseBehaviors?('immediately' | 'period_end')[]

Behaviors subscriptions.pause accepts. Any other value throws unsupported before the request; omitting behavior uses the provider default. Empty when pause is false.

Type('immediately' | 'period_end')[]
portalReturnUrl?boolean

Whether customerPortal.createSession accepts returnUrl. Passing it without support throws unsupported.

Typeboolean
prorationBehaviors?('prorate' | 'invoice_now' | 'none')[]

Behaviors subscriptions.changePlan accepts. Any other value throws unsupported before the request.

Type('prorate' | 'invoice_now' | 'none')[]
revoke?boolean

Whether subscriptions.revoke (cancel immediately) is supported.

Typeboolean
uncancel?boolean

Whether subscriptions.uncancel can revert a scheduled cancellation.

Typeboolean
usageReporting?boolean

Whether usage.report is supported. Calling it without support throws unsupported (Lemon Squeezy keys usage on a subscription item and has no idempotency; Paddle has no usage API).

Typeboolean

Beyond the capability object

Some limits are too fine-grained for a boolean and are enforced by the adapters, which throw RevenueError { code: 'unsupported' } at call time:

Limitation Providers
Checkout item quantity must be 1 Polar
Exactly one checkout item Lemon Squeezy
customerId not accepted on a checkout (use customerEmail) Lemon Squeezy
Plan-change quantity must be 1 Polar, Lemon Squeezy
No customer portal until the customer has a subscription Lemon Squeezy (not_found)

These gaps trace back to real differences between the underlying APIs — Stripe vs Polar vs Lemon Squeezy vs Paddle vs Dodo explains where each one comes from.

Reading capabilities at runtime

if (client.capabilities.revoke) {
  showRevokeButton();
}

const proration = client.capabilities.prorationBehaviors.includes('none') ? 'none' : 'prorate';

if (!client.capabilities.hostedCheckout) {
  // Paddle: render your own Paddle.js page instead of redirecting.
}

Last updated on August 8, 2026

Was this page helpful?