Vatly
JavaScript Fluent

Checkouts

Create a hosted payment page, then redirect the customer to checkout.getUrl().

Create a hosted payment page, then redirect the customer to checkout.getUrl().

One-off or mixed purchases

import type { Vatly } from '@getvatly/fluent';

export async function buyProduct(
  vatly: Vatly, customerId: string, productId: string, purchaseId: string,
) {
  const checkout = await vatly.checkoutBuilder({ vatlyId: customerId })
    .withItems([{ id: productId, quantity: 2 }])
    .withMetadata({ purchaseId })
    .withLocale('en_US')
    .create({}, { idempotencyKey: `checkout:${purchaseId}` });
  return { id: checkout.id, url: checkout.getUrl() };
}

Set both redirect URLs in configuration, or use withRedirectUrlSuccess(url) and withRedirectUrlCanceled(url) on the builder. withItems appends items and supports mixed carts.

Subscription checkout

import type { Vatly } from '@getvatly/fluent';

export async function startSubscription(
  vatly: Vatly, customerId: string, planId: string, purchaseId: string,
) {
  return vatly.subscribe({ vatlyId: customerId })
    .toPlan(planId)
    .withQuantity(3)
    .withTrialDays(14)
    .create({}, { idempotencyKey: `subscribe:${purchaseId}` });
}

subscribe makes no request until create(), which creates a checkout, not a subscription. The subscription builder uses one plan; use checkoutBuilder for mixed carts. Quantity and trial days must be positive safe integers. Omit trial methods for no trial, or use withTrialEndsAt(date) to round up to whole days.

Payloads and retries

Use a new builder per purchase. payload(overrides?) returns a detached request snapshot without calling the API. create(overrides?, requestOptions?) returns the SDK checkout plus getUrl(). On plain SDK checkouts, read links.checkoutUrl.href.

Persist the purchase ID before calling create(). Reuse its idempotency key on retries; use a new key for a new purchase. Validate customer, product, price, and redirect overrides on the server rather than passing browser input through.

inTestmode() and inLiveMode() check the API key's mode; they do not change it. For a known customer, create or bind them first and authorize their ID. An email-only profile does not create a customer. Omit the profile for an anonymous checkout where the API supports it.

Save the checkout ID. Confirm payment through webhooks, not the return page. For product and checkout fields, see the Checkouts API reference and Subscription Plans.

Copyright © 2026