Checkouts
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.