Customer portal
Send a signed-in customer to their invoices and subscription controls:
import type { Vatly } from '@getvatly/fluent';
export async function portalUrl(vatly: Vatly, authenticatedHostId: string) {
const customer = await vatly.customers.findByHostCustomerId(authenticatedHostId);
if (!customer) return null;
const session = await vatly.customer(customer.id).portalSession({
returnUrl: 'https://app.example.com/account/billing',
});
return session.url;
}
Look up the customer through bindings; do not accept a customer ID
from the browser. Redirect to the returned URL with Cache-Control: no-store.
It is a short-lived, single-use credential: never log, cache, or persist it. If an
idempotent retry returns a consumed link, request another with a fresh key.
An eligible issued invoice is required; a subscription alone is not enough. One-off buyers can view invoice history too. On an eligibility 404, show your billing page instead of retrying.
The portal stays in the key's storefront and mode, with no storefront picker.
returnUrl is an HTTPS return link, not an automatic redirect. For a direct
billing-details flow, see subscriptions.
For eligibility and response fields, see Create a customer portal session.