UNPKG

@getpaidhq/sdk

Version:

TypeScript SDK for GetPaidHQ API - Comprehensive subscription billing platform

633 lines (508 loc) 15.4 kB
# @getpaidhq/sdk Official TypeScript SDK for the GetPaidHQ API (v1.0.5) - A comprehensive subscription billing platform supporting traditional subscriptions, usage-based billing, hybrid models, and public payments. - Website: [getpaidhq.co](https://getpaidhq.co) - Developer Guide: [getpaidhq.co/docs/developer-guide](https://getpaidhq.co/docs/developer-guide) - API Documentation: [getpaidhq.co/docs/api-guide](https://getpaidhq.co/docs/api-guide) ## Installation ```bash npm install @getpaidhq/sdk # or yarn add @getpaidhq/sdk # or pnpm add @getpaidhq/sdk ``` ## What's New in v1.0.5 - **Public Payments**: New `PublicPaymentsResource` for handling public payment pages and orders without authentication - **Token Authentication**: Support for token-based authentication via query parameters for public endpoints - **Cart Management**: New `CartsResource` for shopping cart functionality - **Enhanced Invoice Payments**: Added `initiatePayment` method for invoice payment initiation - **Complete Resource Coverage**: All GetPaidHQ API resources now supported ## Quick Start ```typescript import { GetPaidHQClient } from '@getpaidhq/sdk'; // Initialize with API key (recommended for backend applications) const client = new GetPaidHQClient({ apiKey: 'sk_your_api_key', }); // Or initialize with Bearer token (for OAuth/JWT authentication) const client = new GetPaidHQClient({ bearerToken: 'your_bearer_token', }); // Or initialize with token (for public payment endpoints) const publicClient = new GetPaidHQClient({ token: 'your_public_payment_token', }); // Create a customer const customer = await client.customers.create({ email: 'john@example.com', first_name: 'John', last_name: 'Doe', phone: '+27123456789', country: 'ZA', company: 'Tech Corp', }); ``` ## Authentication The SDK supports three authentication methods: ### API Key Authentication ```typescript const client = new GetPaidHQClient({ apiKey: 'sk_your_api_key', // Must start with 'sk_' }); ``` ### Bearer Token Authentication ```typescript const client = new GetPaidHQClient({ bearerToken: 'your_bearer_token', // OAuth/JWT token }); ``` ### Token Authentication (Public Payments) ```typescript // For public payment endpoints only const client = new GetPaidHQClient({ token: 'your_public_payment_token', // Used as query parameter }); ``` You can also update authentication credentials at runtime: ```typescript client.updateApiKey('sk_new_api_key'); // or client.updateBearerToken('new_bearer_token'); ``` ## Configuration ```typescript const client = new GetPaidHQClient({ apiKey: 'sk_your_api_key', baseURL: 'https://api.test.getpaidhq.co', // Optional: custom base URL timeout: 60000, // Optional: request timeout in ms (default: 30000) retries: 5, // Optional: number of retries (default: 3) retryDelay: 2000, // Optional: delay between retries in ms (default: 1000) userAgent: 'MyApp/1.0.0', // Optional: custom user agent }); ``` ## Resources ### Customers ```typescript // List customers const customers = await client.customers.list({ page: 0, limit: 20, status: 'active', email: 'john@example.com', }); // Get a customer const customer = await client.customers.get('customer-123'); // Update a customer const updated = await client.customers.update('customer-123', { email: 'newemail@example.com', company: 'New Company Ltd', }); // Delete a customer await client.customers.delete('customer-123'); // Suspend/Activate a customer await client.customers.suspend('customer-123'); await client.customers.activate('customer-123'); // Customer invoices const invoices = await client.customers.listInvoices('customer-123', { status: 'paid', }); // Payment methods const paymentMethod = await client.customers.createPaymentMethod('customer-123', { name: 'Primary Card', type: 'card', psp: 'paystack', token: 'pm_xyz', is_default: true, }); ``` ### Products and Pricing ```typescript // Create a product const product = await client.products.create({ name: 'Premium Plan', description: 'Our premium subscription plan', type: 'service', }); // Create a variant const variant = await client.products.createVariant(product.id, { name: 'Monthly', description: 'Monthly billing', }); // Create a price const price = await client.prices.create({ variant_id: variant.id, currency: 'USD', category: 'subscription', scheme: 'fixed', unit_price: 9999, // $99.99 in cents billing_interval: 'month', billing_interval_qty: 1, }); ``` ### Subscriptions ```typescript // Create a subscription const subscription = await client.subscriptions.create({ customer_id: customer.id, currency: 'USD', items: [ { price_id: price.id, name: 'Premium Plan', quantity: 1, }, ], }); // Pause a subscription await client.subscriptions.pause(subscription.id, { reason: 'Customer requested pause', pause_mode: 'temporary', resume_at: '2024-02-01T00:00:00Z', }); // Resume a subscription await client.subscriptions.resume(subscription.id, { reason: 'Customer requested resume', resume_behavior: 'start_new_period', proration_mode: 'credit_unused', }); // Cancel a subscription await client.subscriptions.cancel(subscription.id, { reason: 'Customer requested cancellation', cancel_at: 'period_end', }); // Change subscription plan const result = await client.subscriptions.changePlan(subscription.id, { new_variant_id: 'variant-123', new_price_id: 'new-price-id', proration_mode: 'immediate', effective_date: 'immediate', reason: 'Customer upgrade', }); ``` ### Usage-Based Billing ```typescript // Record usage (CloudEvents format - recommended) const usage = await client.usage.recordEvent({ subscription_item_id: 'si_123', quantity: 100, timestamp: new Date().toISOString(), action: 'increment', idempotency_key: 'unique-key-123', }); // Batch record usage const batchResult = await client.usage.batchRecord({ records: [ { subscription_item_id: 'si_123', quantity: 50, timestamp: '2024-01-01T00:00:00Z', }, { subscription_item_id: 'si_124', quantity: 75, timestamp: '2024-01-01T00:00:00Z', }, ], }); // Get usage summary const summary = await client.usage.getSummary('si_123', { start_date: '2024-01-01T00:00:00Z', end_date: '2024-01-31T23:59:59Z', }); // Get subscription usage estimate const estimate = await client.subscriptions.getUsageEstimate('sub_123'); ``` ### Meters ```typescript // Create a meter for usage-based billing const meter = await client.meters.create({ name: 'API Calls', slug: 'api-calls', event_name: 'api_request', aggregation_type: 'sum', value_property: 'count', unit_type: 'requests', }); // Get meter by slug const meter = await client.meters.getBySlug('api-calls'); ``` ### Invoices ```typescript // Create an invoice const invoice = await client.invoices.create({ customer_id: customer.id, due_date: '2024-02-01T00:00:00Z', line_items: [ { description: 'Premium subscription', quantity: 1, unit_price: 9999, // $99.99 in cents }, ], }); // Send an invoice await client.invoices.send(invoice.id); // Mark as paid await client.invoices.markPaid(invoice.id); // Generate PDF const pdfBlob = await client.invoices.generatePdf(invoice.id); // Initiate payment for invoice const paymentInitiation = await client.invoices.initiatePayment(invoice.id, { payment_processor: 'stripe', success_url: 'https://yourapp.com/success', cancel_url: 'https://yourapp.com/cancel', }); ``` ### Payment Gateways ```typescript // Create a payment gateway const gateway = await client.gateways.create({ psp_id: 'paystack', name: 'Paystack Gateway', settings: { api_key: 'sk_paystack_key', connect_id: 'connect_123', }, is_active: true, }); // List gateways const gateways = await client.gateways.list(); ``` ### Organizations and Settings ```typescript // Create an organization (onboarding) const org = await client.organizations.create({ name: 'Tech Corp', country: 'US', timezone: 'America/New_York', }); // Get API keys const apiKeys = await client.organizations.getApiKeys(); // Manage settings const settings = await client.settings.list('org_123'); await client.settings.update('org_123', { value: 'new_value', description: 'Updated setting', }); ``` ### Public Payments Public payment endpoints allow customers to pay invoices without authentication: ```typescript // Initialize client with token for public payments const publicClient = new GetPaidHQClient({ token: 'your_public_payment_token', }); // Get public payment details (no auth required) const paymentDetails = await publicClient.publicPayments.getPublicPaymentDetails('payment-slug'); // Create public payment order const order = await publicClient.publicPayments.createPublicPaymentOrder('payment-slug', { payment_processor: 'stripe', customer_email: 'customer@example.com', customer_name: 'John Doe', success_url: 'https://yourapp.com/success', cancel_url: 'https://yourapp.com/cancel', metadata: { custom_field: 'value', }, }); // Check order status const orderStatus = await publicClient.publicPayments.getPublicOrderStatus( 'payment-slug', order.order_id ); ``` ### Carts Management ```typescript // Add item to cart const cart = await client.carts.addItem('cart-123', { price_id: 'price_123', quantity: 2, }); // Remove item from cart await client.carts.removeItem('cart-123', { cart_item_id: 'item_123', }); // Validate coupon code const cartWithCoupon = await client.carts.validateCoupon('cart-123', { coupon_code: 'DISCOUNT10', }); ``` ## Error Handling The SDK provides typed errors for better error handling: ```typescript import { GetPaidHQError, ValidationError, AuthenticationError, NotFoundError, RateLimitError } from '@getpaidhq/sdk'; try { const customer = await client.customers.get('invalid_id'); } catch (error) { if (error instanceof NotFoundError) { console.error('Customer not found:', error.message); } else if (error instanceof ValidationError) { console.error('Validation failed:', error.details); } else if (error instanceof RateLimitError) { console.error('Rate limited, retry after:', error.retryAfter); } else if (error instanceof AuthenticationError) { console.error('Authentication failed'); } else if (error instanceof GetPaidHQError) { console.error('API error:', error.statusCode, error.message); } else { console.error('Unexpected error:', error); } } ``` ## Pagination All list endpoints support pagination: ```typescript const result = await client.customers.list({ page: 0, // 0-based page number limit: 50, // Items per page (max 100) sort_by: 'created_at', sort_order: 'desc', }); console.log('Total customers:', result.meta.total); console.log('Current page:', result.meta.page); console.log('Customers:', result.data); ``` ## TypeScript Support The SDK is written in TypeScript and provides full type definitions: ```typescript import type { Customer, Subscription, Invoice, CreateCustomerRequest, SubscriptionStatus, // Public Payment types PublicPaymentDetailsResponse, PublicCreateOrderRequest, PublicOrderResponse, PublicOrderStatusResponse, // Cart types CartResponse, AddCartItemRequest, RemoveCartItemRequest, ValidateCouponRequest } from '@getpaidhq/sdk'; // All types are fully typed const createCustomer = async (data: CreateCustomerRequest): Promise<Customer> => { return await client.customers.create(data); }; // Type-safe status checks const activeSubscriptions = subscriptions.filter( (sub): sub is Subscription & { status: 'active' } => sub.status === 'active' ); ``` # Tree-Shaking Examples This SDK is fully optimized for tree-shaking, allowing consumers to import only what they need. ## Full Client Usage (includes everything) ```typescript import { GetPaidHQClient } from '@getpaidhq/sdk'; const client = new GetPaidHQClient({ apiKey: 'sk_...' }); await client.customers.list(); ``` ## Individual Resource Usage (tree-shakeable) ```typescript import { CustomersResource } from '@getpaidhq/sdk'; import { HttpClient } from '@getpaidhq/sdk/client'; // Only imports customers functionality const httpClient = new HttpClient(config, authManager); const customers = new CustomersResource(httpClient); await customers.list(); ``` ## Specific Module Imports (highly tree-shakeable) ```typescript // Import only specific resources import { CustomersResource, PaymentsResource, PublicPaymentsResource, CartsResource } from '@getpaidhq/sdk/resources'; // Import only specific types import type { Customer, Payment, PublicPaymentDetailsResponse, CartResponse } from '@getpaidhq/sdk/types'; // Import only specific errors import { ValidationError, NotFoundError } from '@getpaidhq/sdk/errors'; ``` ## Type-Only Imports (zero runtime cost) ```typescript import type { Customer, CreateCustomerRequest, Payment, Invoice, PublicPaymentDetailsResponse, PublicOrderResponse, CartResponse } from '@getpaidhq/sdk'; // These imports have zero runtime cost function processCustomer(customer: Customer): void { // Type-safe operations } function processPublicPayment(payment: PublicPaymentDetailsResponse): void { // Type-safe public payment operations } ``` ## Bundle Analysis The SDK is built with: - ✅ **ES Modules** - Modern import/export syntax - ✅ **Code Splitting** - Separate chunks for different modules - ✅ **Tree-shaking enabled** - Dead code elimination - ✅ **Side-effect free** - `"sideEffects": false` in package.json - ✅ **Multiple entry points** - Granular imports possible - ✅ **Named exports** - Better for static analysis ## Bundle Sizes | Import Style | Approximate Size | Use Case | |--------------|------------------|----------| | Full client | ~18KB | Complete SDK functionality | | Individual resources | ~2-5KB per resource | Specific API operations | | Types only | 0KB | Type definitions only | | Specific functions | <1KB per function | Minimal footprint | ## Optimal Usage Patterns ### For Full-Featured Apps ```typescript import { GetPaidHQClient } from '@getpaidhq/sdk'; ``` ### For Micro-services/Serverless ```typescript import { CustomersResource } from '@getpaidhq/sdk/resources'; import type { Customer } from '@getpaidhq/sdk/types'; ``` ### For Libraries/Components ```typescript import type { Customer, Payment } from '@getpaidhq/sdk/types'; // Only import types for interfaces, implement your own HTTP layer ``` ## Advanced Usage ### Custom HTTP Client Access For advanced use cases, you can access the underlying Axios instance: ```typescript const axios = client.httpClient.getAxiosInstance(); // Add custom interceptors axios.interceptors.request.use((config) => { console.log('Request:', config.url); return config; }); ``` ### Health Check ```typescript const health = await client.healthCheck(); console.log('API Status:', health.status); // "ok" ``` ## API Reference For detailed API documentation, visit [https://docs.getpaidhq.co/api](https://docs.getpaidhq.co/api) ## Support - Documentation: [https://docs.getpaidhq.co](https://docs.getpaidhq.co) - Email: support@getpaidhq.co - Issues: [GitHub Issues](https://github.com/getpaidhqco/typescript-sdk/issues) ## License MIT License - see LICENSE file for details