Customers and bindings
Find or create a Vatly customer for your signed-in user. Wire binding storage first.
Create and bind
import type { Vatly } from '@getvatly/fluent';
export async function customerFor(vatly: Vatly, hostId: string, email: string) {
const existing = await vatly.customers.findByHostCustomerId(hostId);
if (existing) return existing;
return vatly.customers.createFor(
hostId,
{ email, name: 'Example Customer' },
{ metadata: { accountId: hostId } },
{ idempotencyKey: `customer-for:${hostId}` },
);
}
createFor rejects an already-bound host. The API may return an existing customer
for the email; Fluent checks the binding before attaching it. A binding failure
cannot undo remote creation. Reconcile the customer before retrying.
To link a verified existing customer, use vatly.customers.attribute(vatlyId, hostId).
To create without a host owner, use createUnattributed(profile, extra?, requestOptions?);
it still needs bindings to record the ID.
Read and update identity
import type { Vatly } from '@getvatly/fluent';
export async function updateIdentity(vatly: Vatly, customerId: string) {
const customer = vatly.customer(customerId);
await customer.update({ name: null }); // Explicitly clear the display name.
await customer.sync(); // Refresh the cached API resource.
return customer.identity(); // { name, email }
}
export async function matchingCustomers(vatly: Vatly, email: string) {
const ids: string[] = [];
for await (const customer of vatly.customers.findByEmail(email)) ids.push(customer.id);
return ids;
}
Handles fetch lazily and cache per handle. model(), name(), and email() read
that cache; sync() refreshes it. Email lookup searches all cursor pages on the
server. findOneByEmail returns the first match or null, not proof of ownership.
Identity updates do not change invoice addresses; use the
billing-update flow.
Returning from checkout
customerIdFromCheckout(checkoutId) returns an ID or null for a missing customer
or 404; other API errors propagate. claimCustomerFromCheckout(checkoutId, hostId)
binds that customer. Verify checkout ownership before calling it: an ID in a return
URL is not proof. See payment confirmation.
See customer portal for portal links and the Customers API reference for field details.