Installation and configuration
Fluent 0.1.0-alpha.2 requires SDK 0.3.0-alpha.4. Pin both during alpha:
npm install --save-exact @getvatly/sdk@0.3.0-alpha.4 @getvatly/fluent@0.1.0-alpha.2
Use Node 20+ or a runtime with Fetch and Web Crypto. ESM, CommonJS, and TypeScript
declarations are included. Keep keys and secrets on the server, never in browser
code or NEXT_PUBLIC_* variables.
Create the billing service
Pass your server's VATLY_API_KEY to this factory:
import { VatlyClient } from '@getvatly/sdk';
import { Vatly, type Wiring } from '@getvatly/fluent';
export function createBilling(
apiKey: string,
drivers: Omit<Wiring, 'api' | 'redirectUrlSuccess' | 'redirectUrlCanceled'> = {},
) {
return new Vatly({
...drivers,
api: new VatlyClient({ apiKey, timeoutMs: 15_000, maxRetries: 2 }),
redirectUrlSuccess: 'https://app.example.com/billing/return',
redirectUrlCanceled: 'https://app.example.com/billing/canceled',
});
}
test_ keys select test mode; live_ keys charge real money. Both use the same
API URL. All IDs and bindings must match the key's storefront and mode.
Checkout creation needs only api and redirect URLs. Add storage drivers
for bindings, local subscription updates, and webhook persistence. Missing drivers
fail when used. For webhooks, also set webhookSecret from VATLY_WEBHOOK_SECRET,
the endpoint's signing secret—not the API key.
Use vatly.api for SDK operations without a Fluent helper, including catalogue
management, pagination, and webhook endpoints.
Handle errors and retries
import { VatlyValidationError } from '@getvatly/sdk';
import { FluentError, type Vatly } from '@getvatly/fluent';
export async function renameCustomer(vatly: Vatly, customerId: string, name: string) {
try {
return await vatly.customer(customerId).update({ name });
} catch (error) {
if (error instanceof VatlyValidationError) {
return { validationErrors: error.errors };
}
if (error instanceof FluentError) throw error; // Fix local input or wiring.
throw error; // Preserve SDK status, details, and cause for your error handler.
}
}
SDK errors pass through unchanged. Most local input and wiring errors use
FluentError; missing billing-update redirects throw a plain Error in this alpha.
Reuse an idempotencyKey when retrying the same mutation: a timeout does not mean
it failed. See checkout retries.
For HTTP options and field details, see the API reference and errors guide.