Package Exports
- @4players/payment
Readme
@4players/payment
Official TypeScript SDK for the 4Players Payment API. Manage projects, billing accounts, invoices, access keys, and user permissions with full type safety.
Works in Node.js, Deno, Bun, browsers, and edge runtimes.
Installation
npm install @4players/paymentQuick Start
import { PaymentClient } from '@4players/payment';
const client = new PaymentClient({
sessionId: 'your-fusion-sid',
});
// List all projects
const projects = await client.getProjects();
console.log(projects);
// Get a specific project
const project = await client.getProject('project-id');
console.log(project.name, project.subscription);Authentication
The API uses session-based authentication via the fusion-sid HTTP header. Pass your session ID when creating the client:
const client = new PaymentClient({
sessionId: 'your-fusion-sid',
});Configuration
const client = new PaymentClient({
// Required: your fusion session ID
sessionId: 'your-fusion-sid',
// Optional: override the base URL (default: https://secure.4players.de/public/api/v1)
baseUrl: 'https://your-custom-url/api/v1',
// Optional: provide a custom fetch implementation
fetch: customFetchFn,
});API Reference
Projects
// List all projects
const projects = await client.getProjects();
// Get project for a specific fleet app
const project = await client.getFleetProject('app-id');
// Get project details
const project = await client.getProject('project-id');
// Update a project
await client.editProject('project-id', {
name: 'New Name',
description: 'Updated description',
});Billing
// List billing accounts
const accounts = await client.getBillingAccounts();
// Get a specific billing account
const account = await client.getBillingAccount('billing-account-id');
// Get billing options for a project
const options = await client.getBillingOptions('project-id');
// Assign a billing account to a project
await client.setBillingAccount('project-id', {
billingAccountId: 'billing-account-id',
billingState: 'active',
});
// Cancel billing for a project
await client.cancelBilling('project-id');
// Create a Stripe setup session for a new billing account
const session = await client.createSetupSession({
name: 'My Company',
email: 'billing@example.com',
successUrl: 'https://example.com/success',
cancelUrl: 'https://example.com/cancel',
});
// Create a Stripe billing portal session
const portal = await client.createBillingPortalSession('billing-account-id', {
returnUrl: 'https://example.com/billing',
});Invoices
// List all invoices
const invoices = await client.getInvoices();
// List invoices for a billing account
const invoices = await client.getBillingAccountInvoices('billing-account-id');
// Preview the current month's invoice for a project
const preview = await client.getInvoicePreview('project-id');Access Keys
// Get an access key
const key = await client.getAccessKey('key-id');
// Create a new access key
const newKey = await client.createAccessKey({
projectId: 'project-id',
name: 'My Access Key',
});
// Update an access key
await client.editAccessKey('key-id', { name: 'Renamed Key' });
// Delete an access key
await client.deleteAccessKey('key-id');Project Members
// Add a user to a project
const userRole = await client.addProjectMember('project-id', {
email: 'user@example.com',
role: 'developer',
});
// Change a member's role
await client.changeMemberRole('project-id', {
permissionId: 'permission-id',
role: 'admin',
});
// Remove a user from a project
await client.deleteProjectMember('project-id', {
permissionId: 'permission-id',
});Tokens & Secrets
// Create an ODIN access token
const token = await client.createAccessToken('project-id', {
roomId: 'my-room',
userId: 'user-123',
});
// Revoke and regenerate a project's secret
const updatedProject = await client.revokeSecret('project-id');Metrics
// Get peak peers over time
const peers = await client.getPeersOverTime('project-id', {
start: 1700000000, // Unix timestamp
});
// Get room count over time
const rooms = await client.getRoomsOverTime('project-id', {
start: 1700000000,
end: 1700086400, // optional end timestamp
});
// Get Fleet server instances over time
const instances = await client.getInstancesOverTime('project-id', {
start: 1700000000,
});Resource Pricing
// Get price for a single resource package
const price = await client.getResourcePackagePrice('project-id', {
resourcePackageId: 'package-id',
region: 'eu',
amount: 1,
});
// Get prices for multiple resource packages
const prices = await client.getResourcePackagePrices('project-id', {
resourcePackageIds: ['package-1', 'package-2'],
region: 'eu',
amount: 1,
});Error Handling
The SDK provides structured error classes:
import {
PaymentClient,
PaymentApiError,
PaymentAuthError,
PaymentNotFoundError,
PaymentRateLimitError,
} from '@4players/payment';
try {
const project = await client.getProject('invalid-id');
} catch (err) {
if (err instanceof PaymentApiError) {
// Application-level error from the API response envelope
console.error(`API error ${err.code}: ${err.message} (HTTP ${err.httpStatus})`);
} else if (err instanceof PaymentAuthError) {
// 401/403 - invalid or expired session
console.error('Authentication failed');
} else if (err instanceof PaymentNotFoundError) {
// 404 - resource not found
console.error(err.message);
} else if (err instanceof PaymentRateLimitError) {
// 429 - rate limited
console.error(err.message);
}
}Note: The Payment API can return application-level errors even with HTTP 200 status codes (legacy behavior). The SDK detects these automatically and throws
PaymentApiError.
Examples
See the examples/ directory for runnable scripts:
npx tsx examples/list-projects.ts
npx tsx examples/project-details.ts [projectId]
npx tsx examples/billing-and-invoices.tsEach script prompts for your fusion-sid and queries the live API.
Development
# Install dependencies
npm install
# Generate types from OpenAPI spec
npm run generate:types
# Build the SDK
npm run build
# Type-check without emitting
npm run typecheck
# Build in watch mode
npm run dev