Skip to content

ZipTax/ziptax-node

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

23 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Ziptax Node.js SDK

Official Node.js SDK for the Ziptax API - Get accurate sales and use tax rates for any US address.

npm version Test codecov

Features

  • âś… Full TypeScript support with comprehensive type definitions
  • âś… Promise-based async/await API
  • âś… Automatic retry logic with exponential backoff
  • âś… Request/response logging
  • âś… Comprehensive error handling
  • âś… Support for both CommonJS and ES Modules
  • âś… Zero runtime dependencies (except axios)
  • âś… 80%+ test coverage
  • âś… TaxCloud order management integration (optional)

Installation

npm install @ziptax/node-sdk

Quick Start

import { ZiptaxClient } from '@ziptax/node-sdk';

// Initialize the client with your API key
const client = new ZiptaxClient({
  apiKey: 'your-api-key-here',
});

// Get sales tax rate by address
const result = await client.getSalesTaxByAddress({
  address: '200 Spectrum Center Drive, Irvine, CA 92618',
});

console.log('Total Tax Rate:', result.taxSummaries?.[0]?.rate);
console.log('Base Rates:', result.baseRates);

API Reference

Client Initialization

Basic Initialization (Tax Rate Lookups Only)

const client = new ZiptaxClient({
  apiKey: 'your-api-key-here',
  baseURL?: 'https://api.zip-tax.com', // Optional: Override base URL
  timeout?: 30000, // Optional: Request timeout in ms
  enableLogging?: false, // Optional: Enable request/response logging
  retryOptions?: {
    maxAttempts: 3,
    initialDelay: 1000,
    maxDelay: 10000,
    backoffMultiplier: 2,
  },
});

With TaxCloud Order Management (Optional)

const client = new ZiptaxClient({
  apiKey: 'your-ziptax-api-key-here',
  taxCloudConnectionId: '25eb9b97-5acb-492d-b720-c03e79cf715a', // Optional: TaxCloud Connection ID (UUID)
  taxCloudAPIKey: 'your-taxcloud-api-key-here', // Optional: TaxCloud API Key
  // ... other options
});

Note: TaxCloud order management features are optional and only available when both taxCloudConnectionId and taxCloudAPIKey are provided during client initialization.

Get Sales Tax by Address

Returns sales and use tax rate details from an address input.

const result = await client.getSalesTaxByAddress({
  address: '200 Spectrum Center Drive, Irvine, CA 92618',
  taxabilityCode?: '12345', // Optional: Product/service taxability code
  countryCode?: 'USA', // Optional: 'USA' or 'CAN' (default: 'USA')
  historical?: '202401', // Optional: Historical date (YYYYMM format)
  format?: 'json', // Optional: 'json' or 'xml' (default: 'json')
});

Get Sales Tax by Geolocation

Returns sales and use tax rate details from a geolocation input.

const result = await client.getSalesTaxByGeoLocation({
  lat: '33.65253',
  lng: '-117.74794',
  countryCode?: 'USA', // Optional: 'USA' or 'CAN' (default: 'USA')
  historical?: '202401', // Optional: Historical date (YYYYMM format)
  format?: 'json', // Optional: 'json' or 'xml' (default: 'json')
});

Get Sales Tax by Postal Code

Returns sales and use tax rate details from a postal code input.

const result = await client.getRatesByPostalCode({
  postalcode: '92694', // Required: 5-digit US postal code
  format?: 'json', // Optional: 'json' or 'xml' (default: 'json')
});

Get Account Metrics

Returns account metrics and usage information.

const metrics = await client.getAccountMetrics();

console.log('Requests:', metrics.request_count, '/', metrics.request_limit);
console.log('Usage:', metrics.usage_percent.toFixed(2), '%');

TaxCloud Order Management (Optional)

The SDK includes optional TaxCloud integration for order management operations. These features require TaxCloud credentials to be configured during client initialization.

Create Order

Create orders from marketplace transactions, pre-existing systems, or bulk uploads.

const orderResponse = await client.createOrder({
  orderId: 'my-order-1',
  customerId: 'customer-453',
  transactionDate: '2024-01-15T09:30:00Z',
  completedDate: '2024-01-15T09:30:00Z',
  origin: {
    line1: '323 Washington Ave N',
    city: 'Minneapolis',
    state: 'MN',
    zip: '55401-2427',
  },
  destination: {
    line1: '323 Washington Ave N',
    city: 'Minneapolis',
    state: 'MN',
    zip: '55401-2427',
  },
  lineItems: [
    {
      index: 0,
      itemId: 'item-1',
      price: 10.8,
      quantity: 1.5,
      tax: { amount: 1.31, rate: 0.0813 },
      tic: 0,
    },
  ],
  currency: { currencyCode: 'USD' },
});

Get Order

Retrieve a specific order by its ID from TaxCloud.

const order = await client.getOrder('my-order-1');

console.log('Order ID:', order.orderId);
console.log('Customer:', order.customerId);
console.log('Total Tax:', order.lineItems.reduce((sum, item) => sum + item.tax.amount, 0));

Update Order

Update an existing order's completedDate in TaxCloud.

const updatedOrder = await client.updateOrder('my-order-1', {
  completedDate: '2024-01-16T10:00:00Z',
});

Refund Order

Create a refund against an order in TaxCloud. An order can only be refunded once, regardless of whether the order is partially or fully refunded.

// Partial refund (specific items)
const refunds = await client.refundOrder('my-order-1', {
  items: [
    {
      itemId: 'item-1',
      quantity: 1.0,
    },
  ],
});

// Full refund (omit items or pass empty array)
const fullRefunds = await client.refundOrder('my-order-1');

Response Types

All methods return fully typed responses:

ZipTax API Response Types

interface V60Response {
  metadata: V60Metadata;
  baseRates?: V60BaseRate[];
  service: V60Service;
  shipping: V60Shipping;
  sourcingRules?: V60SourcingRules;
  taxSummaries?: V60TaxSummary[];
  addressDetail: V60AddressDetail;
}

interface V60PostalCodeResponse {
  version: string;
  rCode: number;
  results: V60PostalCodeResult[];
  addressDetail: V60PostalCodeAddressDetail;
}

interface V60AccountMetrics {
  request_count: number;
  request_limit: number;
  usage_percent: number;
  is_active: boolean;
  message: string;
}

TaxCloud API Response Types

interface OrderResponse {
  orderId: string;
  customerId: string;
  connectionId: string;
  transactionDate: string;
  completedDate: string;
  origin: TaxCloudAddressResponse;
  destination: TaxCloudAddressResponse;
  lineItems: CartItemWithTaxResponse[];
  currency: CurrencyResponse;
  channel: string | null;
  deliveredBySeller: boolean;
  excludeFromFiling: boolean;
  exemption: Exemption;
}

interface RefundTransactionResponse {
  connectionId: string;
  createdDate: string;
  items: CartItemRefundWithTaxResponse[];
  returnedDate?: string;
}

See the full type definitions for complete details.

Note: Most API responses use camelCase field names (e.g., baseRates, taxSummaries), but account metrics use snake_case (e.g., request_count, is_active).

Error Handling

The SDK provides specific error types for different failure scenarios:

import {
  ZiptaxError,
  ZiptaxAPIError,
  ZiptaxAuthenticationError,
  ZiptaxValidationError,
  ZiptaxNetworkError,
  ZiptaxRateLimitError,
} from '@ziptax/node-sdk';

try {
  const result = await client.getSalesTaxByAddress({
    address: '200 Spectrum Center Drive',
  });
} catch (error) {
  if (error instanceof ZiptaxAuthenticationError) {
    console.error('Invalid API key');
  } else if (error instanceof ZiptaxValidationError) {
    console.error('Invalid request parameters:', error.message);
  } else if (error instanceof ZiptaxRateLimitError) {
    console.error('Rate limit exceeded. Retry after:', error.retryAfter);
  } else if (error instanceof ZiptaxNetworkError) {
    console.error('Network error:', error.message);
  } else if (error instanceof ZiptaxAPIError) {
    console.error('API error:', error.statusCode, error.message);
  } else if (error instanceof ZiptaxError) {
    console.error('ZipTax error:', error.message);
  } else {
    console.error('Unexpected error:', error);
  }
}

TaxCloud Error Handling

When using TaxCloud features, a ZiptaxConfigurationError will be thrown if the credentials are not configured:

import { ZiptaxConfigurationError } from '@ziptax/node-sdk';

try {
  const order = await client.createOrder({
    orderId: 'my-order-1',
    // ... order details
  });
} catch (error) {
  if (error instanceof ZiptaxConfigurationError) {
    console.error('Please provide taxCloudConnectionId and taxCloudAPIKey during client initialization');
  } else {
    // Handle other errors
    console.error('Error creating order:', error);
  }
}

Advanced Usage

Concurrent Requests

// Fetch tax rates for multiple addresses in parallel
const addresses = [
  '200 Spectrum Center Drive, Irvine, CA 92618',
  '1600 Amphitheatre Parkway, Mountain View, CA 94043',
];

const results = await Promise.all(
  addresses.map((address) => client.getSalesTaxByAddress({ address }))
);

Working with Multiple Orders

// Create multiple orders concurrently
const orders = [
  {
    orderId: 'order-1',
    customerId: 'customer-1',
    // ... order details
  },
  {
    orderId: 'order-2',
    customerId: 'customer-2',
    // ... order details
  },
];

const createdOrders = await Promise.all(
  orders.map((order) => client.createOrder(order))
);

console.log(`Created ${createdOrders.length} orders`);

Custom Retry Configuration

const client = new ZiptaxClient({
  apiKey: 'your-api-key-here',
  retryOptions: {
    maxAttempts: 5,
    initialDelay: 2000,
    maxDelay: 30000,
    backoffMultiplier: 2,
    shouldRetry: (error, attempt) => {
      // Custom retry logic
      return attempt < 3 && error.name === 'ZiptaxNetworkError';
    },
  },
});

Enable Logging

const client = new ZiptaxClient({
  apiKey: 'your-api-key-here',
  enableLogging: true, // Logs all requests and responses
});

Examples

See the examples directory for more usage examples:

Running Examples

Basic examples require a valid ZipTax API key:

# Run basic usage example
ZIPTAX_API_KEY=your-api-key npm run example:basic

# Run async operations example
ZIPTAX_API_KEY=your-api-key npm run example:async

# Run error handling example
ZIPTAX_API_KEY=your-api-key npm run example:errors

TaxCloud example requires both ZipTax and TaxCloud credentials:

# Run TaxCloud order management example
ZIPTAX_API_KEY=your-api-key \
TAXCLOUD_CONNECTION_ID=your-connection-id \
TAXCLOUD_API_KEY=your-taxcloud-key \
npm run example:taxcloud

Or export the environment variables first:

export ZIPTAX_API_KEY=your-api-key
export TAXCLOUD_CONNECTION_ID=your-connection-id
export TAXCLOUD_API_KEY=your-taxcloud-key
npm run example:taxcloud

Requirements

  • Node.js >= 18.0.0
  • npm or yarn

Development

# Install dependencies
npm install

# Run tests
npm test

# Run tests with coverage
npm run test:coverage

# Run linting
npm run lint

# Format code
npm run format

# Type check
npm run type-check

# Build the package
npm run build

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for details.

License

MIT License - see LICENSE file for details.

Support

Links

About

Ziptax Node SDK

Resources

License

Contributing

Stars

Watchers

Forks

Packages

No packages published