UNPKG

kotanipay-sdk

Version:

Official Kotani Pay SDK for Node.js and Browser

581 lines (467 loc) 15 kB
# KotaniPay TypeScript/JavaScript SDK Official TypeScript/JavaScript SDK for the KotaniPay API. Simplify crypto-to-mobile money transactions across Africa. ## Features - 🚀 **TypeScript Support** - Full type definitions included - 🔐 **Authentication Management** - Magic link login flow with JWT and API key support - 📱 **Mobile Money** - Create and manage mobile money customers across 13+ African countries - 💰 **Wallet Management** - Create and manage fiat wallets for multiple currencies - 💸 **Deposits** - Handle mobile money deposits with real-time status tracking - 🔄 **Onramp** - Convert fiat to cryptocurrency through mobile money - 🏢 **Integrator Management** - Create and manage integrator accounts - 🛡️ **Error Handling** - Comprehensive error types and validation - 🌍 **Multi-Environment** - Sandbox and production support ## Installation ```bash npm install kotanipay-sdk ``` ```bash yarn add kotanipay-sdk ``` ## Quick Start ```typescript import { KotaniPayClient } from 'kotanipay-sdk'; // Initialize client const client = new KotaniPayClient({ environment: 'sandbox' // or 'production' }); // Create integrator (no auth required) const integrator = await client.integrator.create({ organization: 'My Company', product_name: 'My Product', first_name: 'John', last_name: 'Doe', email: 'john@company.com', phone: '+1234567890', country_code: 'US' }); // Start authentication flow await client.auth.login('john@company.com'); // User receives magic link in email... // After user clicks magic link, set session client.initializeWithSession(sessionData); // Generate API key const apiKey = await client.auth.generateApiKey(); client.initializeWithApiKey(apiKey.key); // Create fiat wallet const wallet = await client.wallet.create({ name: 'My USD Wallet', currency: 'USD' }); // Create mobile money customer const customer = await client.mobileMoney.createCustomer({ phone_number: '+254700123456', country_code: 'KEN', network: 'MPESA', account_name: 'John Doe' }); // Create deposit const deposit = await client.mobileMoneyDeposit.createDeposit({ amount: 100.00, wallet_id: wallet.data.id, customer_key: customer.id }); ``` ## Authentication Flow KotaniPay uses a magic link authentication system: 1. **Send Magic Link**: Call `client.auth.login(email)` 2. **User Action**: User clicks verification link in email 3. **Get Session Data**: Copy JSON response from browser 4. **Initialize Session**: Call `client.initializeWithSession(sessionData)` 5. **Generate API Key**: Call `client.auth.generateApiKey()` 6. **Ready**: Use authenticated endpoints ### Example Session Data When user clicks the magic link, they'll see JSON like this: ```json { "success": true, "message": "ok", "data": { "user_id": "66262fda6c7024bcf925636f", "session_id": "8d1d3429b8075d53993c58a3a1b3bcec", "token_id": "PrsCEicJ", "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...", "refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." } } ``` Pass the `data` object to `initializeWithSession()`. ## API Reference ### Client Initialization ```typescript const client = new KotaniPayClient({ environment: 'sandbox' | 'production', timeout?: number, apiKey?: string, // Optional: for direct API key usage baseUrl?: string // Optional: custom base URL }); // Utility methods const health = await client.healthCheck(); const config = client.getConfig(); const version = client.getVersion(); const isAuth = client.isAuthenticated(); const authStatus = client.getAuthStatus(); ``` ### Integrator Management ```typescript // Create integrator (no auth required) await client.integrator.create({ organization: string, product_name: string, first_name: string, last_name: string, email: string, phone: string, country_code: string }); // Get all integrators (requires auth) // CLIENT HAS TO BE INITIALIZED WITH AN API KEY await client.integrator.getIntegratorInfo(); // Get integrator by ID (requires auth) await client.integrator.getById(id); ``` ### Authentication ```typescript // Send magic link await client.auth.login(email); // Set session after magic link click client.initializeWithSession(sessionData); // Generate API key await client.auth.generateApiKey(); // Set API key directly client.initializeWithApiKey(apiKey); // Refresh JWT token await client.auth.refreshToken(); // Get current session client.auth.getSession(); // Get token info client.auth.getTokenInfo(); // Check authentication status client.isAuthenticated(); // Logout and clear session client.auth.logout(); ``` ### Mobile Money ```typescript // Create customer (requires auth) await client.mobileMoney.createCustomer({ phone_number: string, country_code: 'GHA' | 'KEN' | 'ZAC' | 'CIV' | 'ZMB' | 'CMR' | 'COD' | 'SEN' | 'TZM' | 'MWI' | 'UGA' | 'ETH' | 'GRW', network?: 'MPESA' | 'MTN' | 'AIRTEL' | 'VODAFONE' | 'TIGO' | 'ORANGE' | 'VODACOM' | 'NOT_SUPPORTED' | 'ZAMTEL' | 'CHECKOUT' | 'BKTRX' | 'CRDTRX' | 'MOOV' | 'TMONEY' | 'FREE' | 'EXPRESSO' | 'HALOPESA', account_name?: string }); // Get all customers (requires auth) await client.mobileMoney.getAllCustomers(); // Get customer by ID (requires auth) await client.mobileMoney.getCustomerById(customerId); // Get customers by customer key (requires auth) await client.mobileMoney.getCustomersByKey(customerKey); // Get customers by phone number (requires auth) await client.mobileMoney.getCustomersByPhoneNumber(phoneNumber); ``` ### Wallet Management ```typescript // Create fiat wallet (requires auth) await client.wallet.create({ name: string, currency: 'USD' | 'EUR' | 'GBP' | 'GHS' | 'KES' | 'ZAR' | 'NGN' | 'TZS' | 'UGX' | 'RWF' | 'MWK' | 'ZMW' }); // Get all fiat wallets (requires auth) await client.wallet.getIntegratorFiatWallets(); // Get wallet by ID (requires auth) await client.wallet.getIntegratorFiatWalletById(walletId); // Get wallets by currency (requires auth) await client.wallet.getIntegratorFiatWalletsByCurrency(currency); ``` ### Mobile Money Deposits ```typescript // Create deposit (requires auth) await client.mobileMoneyDeposit.createDeposit({ amount: number, wallet_id: string, customer_key: string, callback_url?: string, reference_id?: string }); // Get deposit transaction status (requires auth) await client.mobileMoneyDeposit.getDepositTransactionStatus(reference_id); ``` ### Onramp (Fiat to Crypto) ```typescript // Initiate onramp (requires auth) await client.onramp.iniatiateOnramp({ mobileMoney: { phoneNumber: string, accountName: string, providerNetwork: string }, fiatAmount: number, currency: string, chain: string, token: string, receiverAddress: string, referenceId: string, callbackUrl: string, rateId: string }); // Get onramp transaction status (requires auth) await client.onramp.getOnRampTransactionStatus(referenceId); ``` ## Supported Countries & Networks ### Countries - 🇬🇭 Ghana (GHA) - MTN, VODAFONE, AIRTEL - 🇰🇪 Kenya (KEN) - MPESA, AIRTEL - 🇿🇦 South Africa (ZAC) - MTN, VODACOM - 🇨🇮 Ivory Coast (CIV) - MTN, ORANGE, MOOV - 🇿🇲 Zambia (ZMB) - MTN, AIRTEL, ZAMTEL - 🇨🇲 Cameroon (CMR) - MTN, ORANGE - 🇨🇩 Congo DRC (COD) - VODACOM, AIRTEL - 🇸🇳 Senegal (SEN) - ORANGE, FREE, EXPRESSO - 🇹🇿 Tanzania (TZM) - VODACOM, AIRTEL, TIGO, HALOPESA - 🇲🇼 Malawi (MWI) - AIRTEL - 🇺🇬 Uganda (UGA) - MTN, AIRTEL - 🇪🇹 Ethiopia (ETH) - 🇬🇼 Guinea-Bissau (GRW) ### Networks - M-Pesa - MTN Mobile Money - Airtel Money - Vodafone Cash - Tigo Pesa - Orange Money - And more... ### Supported Currencies **Fiat Wallets**: USD, EUR, GBP, GHS, KES, ZAR, NGN, TZS, UGX, RWF, MWK, ZMW ### Transaction Statuses **Deposit/Onramp**: PENDING, INITIATED, SUCCESSFUL, FAILED, EXPIRED, CANCELLED, DECLINED, REVERSED, IN_PROGRESS, DUPLICATE, ERROR_OCCURRED, REQUIRE_REVIEW, SUCCESS, RETRY ## Error Handling ```typescript import { ValidationException, AuthenticationException, KotaniPayException } from 'kotanipay-sdk'; try { await client.mobileMoney.createCustomer(customerData); } catch (error) { if (error instanceof ValidationException) { console.log('Validation error:', error.message); console.log('Details:', error.details); } else if (error instanceof AuthenticationException) { console.log('Auth error:', error.message); } else if (error instanceof KotaniPayException) { console.log('API error:', error.message); console.log('Status:', error.status); console.log('Error code:', error.errorCode); } } ``` ## Environment Variables For server-side usage, you can set: ```bash KOTANIPAY_API_KEY=your-api-key KOTANIPAY_ENVIRONMENT=sandbox ``` ## Examples ### Complete Integration Flow ```typescript import { KotaniPayClient } from 'kotanipay-sdk'; async function completeFlow() { const client = new KotaniPayClient({ environment: 'sandbox' }); try { // 1. Create integrator const integrator = await client.integrator.create({ organization: 'My Company', product_name: 'My App', first_name: 'John', last_name: 'Doe', email: 'john@mycompany.com', phone: '+1234567890', country_code: 'US' }); // 2. Login and authenticate await client.auth.login('john@mycompany.com'); // User clicks email link, you get session data client.initializeWithSession(sessionData); // 3. Generate API key const apiKey = await client.auth.generateApiKey(); // 4. Create a wallet const wallet = await client.wallet.create({ name: 'My USD Wallet', currency: 'USD' }); // 5. Create mobile money customer const customer = await client.mobileMoney.createCustomer({ phone_number: '+254712345678', country_code: 'KEN', network: 'MPESA' }); // 6. Create deposit const deposit = await client.mobileMoneyDeposit.createDeposit({ amount: 100.00, wallet_id: wallet.data.id, customer_key: customer.id }); console.log('Integration flow completed successfully'); } catch (error) { console.error('Integration flow failed:', error); } } ``` ### React Integration ```typescript import React, { useState } from 'react'; import { KotaniPayClient } from 'kotanipay-sdk'; function PaymentComponent() { const [client] = useState(() => new KotaniPayClient({ environment: 'sandbox' })); const [authStatus, setAuthStatus] = useState('idle'); const handleLogin = async (email: string) => { try { setAuthStatus('sending'); await client.auth.login(email); setAuthStatus('waiting'); // Wait for user to click magic link } catch (error) { setAuthStatus('error'); } }; const handleSessionData = async (sessionData: any) => { try { client.initializeWithSession(sessionData); const apiKey = await client.auth.generateApiKey(); client.initializeWithApiKey(apiKey.key); setAuthStatus('authenticated'); } catch (error) { setAuthStatus('error'); } }; const createWalletAndCustomer = async () => { try { const wallet = await client.wallet.create({ name: 'Payment Wallet', currency: 'KES' }); const customer = await client.mobileMoney.createCustomer({ phone_number: '+254700123456', country_code: 'KEN', network: 'MPESA' }); console.log('Wallet and customer created successfully'); } catch (error) { console.error('Creation failed:', error); } }; return ( <div> {authStatus === 'idle' && ( <button onClick={() => handleLogin('user@example.com')}> Login with Email </button> )} {authStatus === 'waiting' && ( <div> <p>Magic link sent! Check your email.</p> <textarea placeholder="Paste session data here..." onChange={(e) => { try { const data = JSON.parse(e.target.value); handleSessionData(data.data); } catch {} }} /> </div> )} {authStatus === 'authenticated' && ( <div> <p>Ready to make payments!</p> <button onClick={createWalletAndCustomer}> Create Wallet & Customer </button> </div> )} </div> ); } ``` ### Node.js Integration ```typescript import { KotaniPayClient } from 'kotanipay-sdk'; const client = new KotaniPayClient({ environment: 'sandbox', apiKey: process.env.KOTANIPAY_API_KEY // If you already have an API key }); async function processPayment() { try { // Create wallet const wallet = await client.wallet.create({ name: 'Business Wallet', currency: 'KES' }); // Create customer const customer = await client.mobileMoney.createCustomer({ phone_number: '+254700123456', country_code: 'KEN', network: 'MPESA' }); // Create deposit const deposit = await client.mobileMoneyDeposit.createDeposit({ amount: 1000, wallet_id: wallet.data.id, customer_key: customer.id, callback_url: 'https://myapp.com/webhook' }); console.log('Payment initiated:', deposit); return deposit; } catch (error) { console.error('Payment failed:', error); throw error; } } ``` ### Onramp Example ```typescript async function initiateOnramp() { try { const onramp = await client.onramp.iniatiateOnramp({ mobileMoney: { phoneNumber: '+254700123456', accountName: 'John Doe', providerNetwork: 'MPESA' }, fiatAmount: 100, currency: 'KES', chain: 'ethereum', token: 'USDC', receiverAddress: '0x1234567890123456789012345678901234567890', referenceId: 'my-ref-' + Date.now(), callbackUrl: 'https://myapp.com/webhook', rateId: 'rate-id-from-quote' }); console.log('Onramp initiated:', onramp); } catch (error) { console.error('Onramp failed:', error); } } ``` ## Contributing 1. Fork the repository 2. Create your feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add some amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request ## License This project is licensed under the MIT License - see the LICENSE file for details. ## Support - 📧 **Email**: support@kotanipay.com - 📖 **Documentation**: https://docs.kotanipay.com - 🐛 **Issues**: https://github.com/kotanipay/sdk-typescript/issues ## Changelog ### v1.0.0 - Initial release - Magic link authentication with JWT and API key support - Integrator management - Mobile money customer management across 13+ African countries - Fiat wallet creation and management - Mobile money deposit handling with status tracking - Onramp functionality for fiat-to-crypto conversion - Comprehensive error handling and validation - TypeScript supportcd ..