Skip to main content

@paymint/node

Low-level HTTP client for the Paymint API.

Installation

npm install @paymint/node
Note: For most use cases, use @paymint/server or @paymint/nextjs instead. This package provides the underlying HTTP client.

Quick Start

import { PaymintClient } from '@paymint/node';

const client = new PaymintClient({
  apiKey: 'paymint_test_xxx', // or paymint_live_xxx for production
});

// Get products
const products = await client.products.list();

// Initialize checkout
const init = await client.checkout.initialize({ email: '[email protected]' });

// Get subscriptions
const subscriptions = await client.subscriptions.list({ email: '[email protected]' });

// Cancel subscription
await client.subscriptions.cancel('[email protected]', 'sub_xxx', {
  effectiveFrom: 'next_billing_period',
});

Configuration

API Key Format

  • paymint_test_xxx - Sandbox/test environment
  • paymint_live_xxx - Production environment
The environment is automatically detected from your API key.

Client Options

const client = new PaymintClient({
  apiKey: 'paymint_test_xxx',     // Required
  baseUrl: 'https://api.paymint.dev', // Optional, defaults to api.paymint.dev
  timeout: 30000,                      // Optional, request timeout in ms
});

Resources

The client is organized into resources that map to API endpoints:

client.products

// List all products with prices
const products = await client.products.list();

// Product structure
interface Product {
  id: string;
  name: string;
  description: string | null;
  prices: Price[];
}

interface Price {
  id: string;
  name: string;
  description: string | null;
  unitPrice: {
    amount: string;
    currencyCode: string;
  };
  billingCycle: {
    interval: 'month' | 'year';
    frequency: number;
  };
  trialPeriod: {
    interval: 'day';
    frequency: number;
  } | null;
}

client.checkout

// Initialize checkout for a customer
const init = await client.checkout.initialize({
  email: '[email protected]',
});

// Returns
interface InitializeResponse {
  clientSideToken: string;      // Pass to Paddle.js
  paddleEnvironment: 'sandbox' | 'production';
  customerExists: boolean;
}

// Use with Paddle.js
Paddle.Initialize({
  token: init.clientSideToken,
  environment: init.paddleEnvironment,
});

client.subscriptions

// List subscriptions for a customer
const subscriptions = await client.subscriptions.list({
  email: '[email protected]',
});

// Cancel a subscription
await client.subscriptions.cancel('[email protected]', 'sub_xxx', {
  effectiveFrom: 'next_billing_period', // or 'immediately'
});

// Pause a subscription
await client.subscriptions.pause('[email protected]', 'sub_xxx', {
  effectiveFrom: 'next_billing_period',
  resumeAt: '2024-03-01T00:00:00Z', // Optional: auto-resume
});

// Resume a paused subscription
await client.subscriptions.resume('[email protected]', 'sub_xxx', {
  effectiveFrom: 'immediately',
});

// Activate a trialing subscription
await client.subscriptions.activate('[email protected]', 'sub_xxx');

Error Handling

All errors extend PaymintError:
import {
  PaymintClient,
  PaymintError,
  AuthenticationError,
  ValidationError,
  NotFoundError,
  RateLimitError,
  NetworkError,
} from '@paymint/node';

try {
  const products = await client.products.list();
} catch (error) {
  if (error instanceof AuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof ValidationError) {
    console.error('Invalid request:', error.message);
  } else if (error instanceof NotFoundError) {
    console.error('Resource not found');
  } else if (error instanceof RateLimitError) {
    console.error('Rate limited. Retry after:', error.retryAfter);
  } else if (error instanceof NetworkError) {
    console.error('Network error:', error.message);
  } else if (error instanceof PaymintError) {
    console.error('Paymint error:', error.message, error.requestId);
  } else {
    console.error('Unknown error:', error);
  }
}

Error Types

ErrorStatusDescription
AuthenticationError401Invalid API key
ValidationError400Invalid request parameters
NotFoundError404Resource not found
RateLimitError429Too many requests
NetworkError-Connection or timeout issues

TypeScript Support

Full TypeScript types are included:
import type {
  Product,
  Price,
  Subscription,
  SubscriptionStatus,
  InitializeRequest,
  InitializeResponse,
  CancelSubscriptionOptions,
  PauseSubscriptionOptions,
  ResumeSubscriptionOptions,
} from '@paymint/node';

Complete Example

import { PaymintClient, PaymintError } from '@paymint/node';

async function billingExample() {
  const client = new PaymintClient({
    apiKey: process.env.PAYMINT_API_KEY!,
  });

  try {
    // Get available products
    const products = await client.products.list();
    console.log('Available products:', products.map(p => p.name));

    // Initialize checkout
    const init = await client.checkout.initialize({
      email: '[email protected]',
    });
    console.log('Checkout token:', init.clientSideToken);

    // Check existing subscriptions
    const subscriptions = await client.subscriptions.list({
      email: '[email protected]',
    });

    const activeSubscription = subscriptions.find(
      s => s.status === 'active' || s.status === 'trialing'
    );

    if (activeSubscription) {
      console.log('Active subscription:', activeSubscription.id);
      
      // Cancel at end of period
      await client.subscriptions.cancel(
        '[email protected]',
        activeSubscription.id,
        { effectiveFrom: 'next_billing_period' }
      );
      console.log('Subscription will cancel at end of period');
    }

  } catch (error) {
    if (error instanceof PaymintError) {
      console.error('Billing error:', error.message);
    } else {
      throw error;
    }
  }
}

Advanced Usage

Custom Base URL

For testing or self-hosted instances:
const client = new PaymintClient({
  apiKey: 'paymint_test_xxx',
  baseUrl: 'http://localhost:3002', // Override for local development
});
Environment-based Auto-Configuration: By default, all SDKs connect to https://api.paymint.dev. To use a local API server during Paymint internal development:
PAYMINT_USE_LOCAL_API=true npm run dev
This will automatically use http://localhost:3002 instead of the production API.

Timeout Configuration

const client = new PaymintClient({
  apiKey: 'paymint_test_xxx',
  timeout: 10000, // 10 seconds
});

Request ID Tracking

All errors include a request ID for support:
try {
  await client.products.list();
} catch (error) {
  if (error instanceof PaymintError) {
    console.log('Request ID:', error.requestId);
    // Include this when contacting support
  }
}

License

MIT