JSPM

  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 59
  • Score
    100M100P100Q77400F
  • License MIT

Package Exports

    This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@tjoc/payments) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.

    Readme

    Payment Integration Package

    A comprehensive payment integration system that intelligently routes payments between Stripe and Paystack based on geographical context, with built-in retry logic and fallback mechanisms.

    Features

    • Intelligent Provider Routing: Automatically selects the best payment provider based on customer location and currency
    • Multi-Provider Support: Seamlessly integrates with both Stripe and Paystack
    • Geographic Detection: Detects customer country from IP address or browser locale
    • Retry Logic: Built-in retry mechanisms with exponential backoff
    • Fallback Support: Automatic fallback to secondary provider if primary fails
    • Webhook Handling: Unified webhook processing for both providers
    • TypeScript Support: Fully typed interfaces and comprehensive error handling

    Installation

    # Using pnpm (recommended)
    pnpm add @tjoc/payments
    
    # Using npm
    npm install @tjoc/payments
    
    # Using yarn
    yarn add @tjoc/payments

    Quick Start

    Basic Setup

    import { 
      PaymentRouter, 
      StripeProvider, 
      PaystackProvider,
      CountryDetectionService 
    } from '@tjoc/payments';
    
    // Initialize providers
    const stripeProvider = new StripeProvider({
      apiKey: process.env.STRIPE_SECRET_KEY!,
    });
    
    const paystackProvider = new PaystackProvider({
      secretKey: process.env.PAYSTACK_SECRET_KEY!,
      publicKey: process.env.PAYSTACK_PUBLIC_KEY!,
    });
    
    // Create payment router
    const paymentRouter = new PaymentRouter({
      providers: {
        primary: stripeProvider,
        fallback: paystackProvider
      },
      routing: {
        paystackCountries: ['NG', 'GH', 'ZA', 'KE'], // Nigeria, Ghana, South Africa, Kenya
        defaultProvider: 'stripe'
      },
      retryConfig: {
        maxRetries: 2,
        retryDelay: 1000
      }
    });

    Creating a Payment

    // Create a payment with automatic provider selection
    const transaction = await paymentRouter.createPayment({
      amount: 100.00,
      currency: 'USD',
      customerId: 'cust_123',
      description: 'Product purchase'
    }, {
      country: 'US', // Optional: helps with provider selection
      currency: 'USD'
    });
    
    console.log('Payment created:', transaction.id);
    console.log('Provider used:', transaction.provider);

    Geographic Detection

    // Detect country from IP address
    const geoInfo = await CountryDetectionService.detectCountryFromIP('192.168.1.1');
    if (geoInfo) {
      console.log('Country:', geoInfo.country);
      console.log('Currency:', geoInfo.currency);
    }
    
    // Get country information and preferred provider
    const countryInfo = CountryDetectionService.getCountryInfo('NG');
    console.log('Preferred provider for Nigeria:', countryInfo.preferredProvider); // 'paystack'
    
    // Check if country supports Paystack
    const supportsPaystack = CountryDetectionService.isPaystackCountry('NG');
    console.log('Nigeria supports Paystack:', supportsPaystack); // true

    API Reference

    PaymentRouter

    The main class that handles intelligent routing between payment providers.

    Constructor

    interface PaymentRouterConfig {
      providers: {
        primary: PaymentProvider;
        fallback?: PaymentProvider;
      };
      routing: {
        paystackCountries: string[]; // Country codes that should use Paystack
        defaultProvider: 'stripe' | 'paystack';
      };
      retryConfig?: {
        maxRetries: number;
        retryDelay: number;
      };
    }

    Methods

    Payment Operations
    // Create a new payment
    createPay ment(options: CreatePaymentOptions, context?: PaymentContext): Promise<Transaction>
    
    // Confirm a payment
    confirmPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
    
    // Cancel a payment
    cancelPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
    
    // Get payment details
    getPayment(paymentId: string, context?: PaymentContext): Promise<Transaction>
    Customer Operations
    // Create a customer
    createCustomer(data: Partial<Customer>, context?: PaymentContext): Promise<Customer>
    
    // Update customer
    updateCustomer(customerId: string, data: Partial<Customer>, context?: PaymentContext): Promise<Customer>
    
    // Get customer
    getCustomer(customerId: string, context?: PaymentContext): Promise<Customer>
    
    // Delete customer
    deleteCustomer(customerId: string, context?: PaymentContext): Promise<boolean>
    Subscription Operations
    // Create subscription
    createSubscription(options: CreateSubscriptionOptions, context?: PaymentContext): Promise<Subscription>
    
    // Update subscription
    updateSubscription(subscriptionId: string, data: Partial<Subscription>, context?: PaymentContext): Promise<Subscription>
    
    // Cancel subscription
    cancelSubscription(subscriptionId: string, context?: PaymentContext): Promise<Subscription>
    
    // Get subscription
    getSubscription(subscriptionId: string, context?: PaymentContext): Promise<Subscription>
    
    // List customer subscriptions
    listCustomerSubscriptions(customerId: string, context?: PaymentContext): Promise<Subscription[]>

    CountryDetectionService

    Static service for geographic detection and provider recommendations.

    Methods

    // Detect country from IP address
    static detectCountryFromIP(ipAddress?: string): Promise<GeoLocation | null>
    
    // Detect country from browser
    static detectCountryFromBrowser(): GeoLocation | null
    
    // Get currency for country
    static getCurrencyForCountry(countryCode: string): string
    
    // Get preferred provider for country
    static getPreferredProvider(countryCode: string): 'stripe' | 'paystack'
    
    // Check if country supports Paystack
    static isPaystackCountry(countryCode: string): boolean
    
    // Get comprehensive country information
    static getCountryInfo(countryCode: string): CountryInfo

    Provider Classes

    StripeProvider

    interface StripeConfig {
      apiKey: string;
      webhookHandlers?: WebhookHandlerConfig;
    }
    
    const stripe = new StripeProvider(config);

    PaystackProvider

    interface PaystackConfig {
      secretKey: string;
      publicKey: string;
      webhookSecret?: string;
      testMode?: boolean;
    }
    
    const paystack = new PaystackProvider(config);

    Routing Logic

    The payment router uses the following logic to select providers:

    1. Country-based routing: If the customer's country is in the paystackCountries list, Paystack is preferred
    2. Currency-based routing: If the currency is NGN (Nigerian Naira), Paystack is preferred
    3. Default provider: Falls back to the configured default provider
    4. Retry logic: If the primary provider fails, retries with exponential backoff
    5. Fallback provider: If all retries fail, attempts with the fallback provider

    Supported Countries for Paystack

    • NG - Nigeria
    • GH - Ghana
    • ZA - South Africa
    • KE - Kenya

    Webhook Handling

    Setting up Webhooks

    // Stripe webhooks
    const stripeProvider = new StripeProvider({
      apiKey: process.env.STRIPE_SECRET_KEY!,
      webhookHandlers: {
        'payment_intent.succeeded': async (event) => {
          console.log('Stripe payment succeeded:', event.data.object);
        },
        'payment_intent.payment_failed': async (event) => {
          console.log('Stripe payment failed:', event.data.object);
        }
      }
    });
    
    // Paystack webhooks
    const paystackProvider = new PaystackProvider({
      secretKey: process.env.PAYSTACK_SECRET_KEY!,
      publicKey: process.env.PAYSTACK_PUBLIC_KEY!,
      webhookSecret: process.env.PAYSTACK_WEBHOOK_SECRET
    });

    Processing Webhooks

    // In your webhook endpoint
    app.post('/webhooks/:provider', async (req, res) => {
      const provider = req.params.provider as 'stripe' | 'paystack';
      const signature = req.headers['stripe-signature'] || req.headers['x-paystack-signature'];
      
      try {
        await paymentRouter.handleWebhook(provider, req.body, signature);
        res.json({ success: true });
      } catch (error) {
        res.status(400).json({ error: error.message });
      }
    });

    Error Handling

    The package includes comprehensive error handling:

    import { PaymentProviderError, ConfigurationError } from '@your-org/payments';
    
    try {
      const transaction = await paymentRouter.createPayment(options);
    } catch (error) {
      if (error instanceof PaymentProviderError) {
        console.error('Payment provider error:', error.code, error.message);
      } else if (error instanceof ConfigurationError) {
        console.error('Configuration error:', error.message);
      } else {
        console.error('Unknown error:', error);
      }
    }

    Environment Variables

    # Stripe
    STRIPE_SECRET_KEY=sk_test_...
    STRIPE_WEBHOOK_SECRET=whsec_...
    
    # Paystack
    PAYSTACK_SECRET_KEY=sk_test_...
    PAYSTACK_PUBLIC_KEY=pk_test_...
    
    # Environment
    NODE_ENV=development

    Examples

    See the usage examples for comprehensive implementation examples including:

    • Express.js integration
    • Next.js API routes
    • React hooks for frontend
    • Webhook handling
    • Error management

    Contributing

    1. Fork the repository
    2. Create a feature branch
    3. Make your changes
    4. Add tests
    5. Submit a pull request

    License

    MIT License - see LICENSE file for details.