@paymint/server
Server-side SDK for Paymint billing.Installation
Copy
npm install @paymint/server
Note: For Next.js apps, use @paymint/nextjs instead - it includes this package plus React hooks.
Quick Start
Copy
import { PaymintServer } from '@paymint/server';
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY!,
// baseUrl is auto-configured:
// - Default: https://api.paymint.dev
// - Local: Set PAYMINT_USE_LOCAL_API=true for localhost:3002
});
// Or override explicitly:
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY!,
baseUrl: 'http://localhost:3002', // Only for internal testing
});
// Get all products
const products = await paymint.getProducts();
// Initialize checkout (returns Paddle client token)
const init = await paymint.initialize('[email protected]');
// init.clientSideToken - for Paddle.js
// init.paddleEnvironment - 'sandbox' or 'production'
// Get billing state (products + subscriptions)
const billing = await paymint.getBilling('[email protected]');
// billing.products
// billing.subscriptions
// billing.hasActiveSubscription
// Get subscriptions only
const subscriptions = await paymint.getSubscriptions('[email protected]');
// Cancel subscription
await paymint.cancelSubscription('[email protected]', 'sub_xxx', {
effectiveFrom: 'next_billing_period', // or 'immediately'
});
// Pause subscription
await paymint.pauseSubscription('[email protected]', 'sub_xxx', {
effectiveFrom: 'next_billing_period',
resumeAt: '2024-03-01', // optional auto-resume date
});
// Resume subscription
await paymint.resumeSubscription('[email protected]', 'sub_xxx');
// Activate trial
await paymint.activateSubscription('[email protected]', 'sub_xxx');
Scoped Customer Pattern
When making multiple calls for the same customer, useforCustomer() for cleaner code:
Copy
const paymint = new PaymintServer({ apiKey: process.env.PAYMINT_API_KEY! });
// Without scoped customer
const billing = await paymint.getBilling('[email protected]');
await paymint.cancelSubscription('[email protected]', 'sub_xxx', {
effectiveFrom: 'next_billing_period'
});
// With scoped customer - cleaner!
const customer = paymint.forCustomer('[email protected]');
const billing = await customer.getBilling();
await customer.cancelSubscription('sub_xxx', { effectiveFrom: 'next_billing_period' });
Scoped Customer Methods
Copy
const customer = paymint.forCustomer('[email protected]');
// All methods - email is already bound
const billing = await customer.getBilling();
const subscriptions = await customer.getSubscriptions();
const init = await customer.initialize();
// Subscription actions
await customer.cancelSubscription('sub_xxx', { effectiveFrom: 'next_billing_period' });
await customer.pauseSubscription('sub_xxx', { effectiveFrom: 'next_billing_period' });
await customer.resumeSubscription('sub_xxx');
await customer.activateSubscription('sub_xxx');
BillingState Type
Copy
interface BillingState {
products: Product[];
subscriptions: Subscription[];
hasActiveSubscription: boolean;
activeSubscription: Subscription | null;
isTrialing: boolean;
isPaused: boolean;
isCanceled: boolean;
}
Complete Examples
Check Subscription Access
Copy
import { PaymintServer } from '@paymint/server';
async function checkAccess(email: string) {
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY!,
});
const billing = await paymint.getBilling(email);
if (billing.hasActiveSubscription) {
console.log('User has active subscription:', billing.activeSubscription?.id);
return { access: true, subscription: billing.activeSubscription };
}
if (billing.isTrialing) {
console.log('User is on trial');
return { access: true, trial: true };
}
return { access: false };
}
Subscription Management
Copy
import { PaymintServer } from '@paymint/server';
async function manageSubscription(email: string, subscriptionId: string) {
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY!,
});
const customer = paymint.forCustomer(email);
// Get current state
const billing = await customer.getBilling();
const subscription = billing.subscriptions.find(s => s.id === subscriptionId);
if (!subscription) {
throw new Error('Subscription not found');
}
// Cancel at end of period (recommended)
if (subscription.status === 'active') {
await customer.cancelSubscription(subscriptionId, {
effectiveFrom: 'next_billing_period'
});
console.log('Subscription will cancel at end of billing period');
}
// Or pause temporarily
if (subscription.status === 'active') {
await customer.pauseSubscription(subscriptionId, {
effectiveFrom: 'next_billing_period',
resumeAt: '2024-03-01T00:00:00Z' // Auto-resume
});
console.log('Subscription paused until March 1st');
}
// Resume paused subscription
if (subscription.status === 'paused') {
await customer.resumeSubscription(subscriptionId);
console.log('Subscription resumed');
}
}
Initialize Checkout
Copy
import { PaymintServer } from '@paymint/server';
async function createCheckout(email: string) {
const paymint = new PaymintServer({
apiKey: process.env.PAYMINT_API_KEY!,
});
const init = await paymint.initialize(email);
return {
token: init.clientSideToken,
environment: init.paddleEnvironment,
customerExists: init.customerExists,
};
}
Error Handling
All errors extendPaymintError from @paymint/shared:
Copy
import { PaymintServer } from '@paymint/server';
import { PaymintError, ValidationError } from '@paymint/shared';
const paymint = new PaymintServer({ apiKey: process.env.PAYMINT_API_KEY! });
try {
const billing = await paymint.getBilling('[email protected]');
} catch (error) {
if (error instanceof ValidationError) {
console.error('Invalid email or parameters:', error.message);
} else if (error instanceof PaymintError) {
console.error('Paymint error:', error.message, 'Request ID:', error.requestId);
} else {
console.error('Unexpected error:', error);
}
}
Environment
The API key format determines the environment:paymint_test_xxx→ Sandboxpaymint_live_xxx→ Production
Comparison with @paymint/node
| Use Case | Package | Reason |
|---|---|---|
| Full-stack Next.js | @paymint/nextjs | Includes server + React hooks |
| React SPA + custom backend | @paymint/server | Server utilities |
| Raw HTTP access | @paymint/node | Low-level client |
| Type definitions only | @paymint/shared | Types and errors |
