@airxpay/init-sdk 1.0.6 β†’ 1.0.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,268 +1,1316 @@
1
- # AirXPay Flixora SDK - Seller Onboard
1
+ # 🌟 AirXPay Flixora SDK - Backend Integration
2
2
 
3
- <!-- <div align="center">
4
- <img src="./assets/images/flixora.png" alt="AirXPay Flixora SDK" width="100"/>
5
- </div> -->
6
-
7
- **Enterprise-grade TypeScript SDK** for seamless seller onboarding in multi-tenant SaaS platforms. Built with ❀️ by the **Flixora Ecosystem**. Powered by **AirXPay** for payouts and payments, integrated with **TizzyGo**, **TizzyOS**, and soon **TizzyChat** for real-time notifications. Made with a **smiles-first philosophy**, designed to evolve and upgrade continuously for future generations.
3
+ <div align="center">
4
+ <img src="./assets/images/airxpay.png" alt="AirXPay Flixora SDK" width="120"/>
5
+ <br/>
6
+ <br/>
7
+
8
+ <strong>🏒 Enterprise Seller Onboarding Infrastructure for SaaS Platforms</strong>
9
+ <br/><br/>
10
+ <p>Build once. Onboard everywhere. πŸš€</p>
11
+ <p>Powered by the Flixora Ecosystem ❀️</p>
12
+
13
+ <p>
14
+ <a href="#-installation">
15
+ <img src="https://img.shields.io/npm/v/@airxpay/init-sdk?style=for-the-badge&logo=npm&color=red" alt="npm version" />
16
+ </a>
17
+ <a href="#-license">
18
+ <img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge" alt="license" />
19
+ </a>
20
+ <a href="#-typescript">
21
+ <img src="https://img.shields.io/badge/TypeScript-5.0+-blue?style=for-the-badge&logo=typescript" alt="TypeScript" />
22
+ </a>
23
+ <a href="#-nodejs">
24
+ <img src="https://img.shields.io/badge/Node.js-18.x+-339933?style=for-the-badge&logo=nodedotjs" alt="Node.js" />
25
+ </a>
26
+ <a href="#-nestjs">
27
+ <img src="https://img.shields.io/badge/NestJS-10.x+-E0234E?style=for-the-badge&logo=nestjs" alt="NestJS" />
28
+ </a>
29
+ <a href="#-express">
30
+ <img src="https://img.shields.io/badge/Express-4.x+-000000?style=for-the-badge&logo=express" alt="Express" />
31
+ </a>
32
+ </p>
33
+ </div>
8
34
 
9
35
  ---
10
36
 
11
- # Our team together build AirXPay with Flixora.
12
- *We have changed the version of this package airxpay from v1.0.3 to v1.0.5 because it was our compulsion to match the versions of the apps.*
13
- **I hope you understand. Thanks for your reading.😊❀️**
37
+ ## 🧠 What is AirXPay?
14
38
 
15
- ---
16
- ## Table of Contents
17
-
18
- 1. [Overview](#overview)
19
- 2. [Features](#features)
20
- 3. [Installation](#installation)
21
- 4. [Environment Setup](#environment-setup)
22
- 5. [SDK Initialization](#sdk-initialization)
23
- 6. [API Methods](#api-methods)
24
- 7. [Usage Examples](#usage-examples)
25
- - [React / React Native](#react--react-native)
26
- - [TypeScript / JavaScript](#typescript--javascript)
27
- 8. [Folder Structure](#folder-structure)
28
- 9. [Advanced Usage](#advanced-usage)
29
- 10. [Error Handling](#error-handling)
30
- 11. [FAQ](#faq)
31
- 12. [Support & Contact](#support--contact)
32
- 13. [License](#license)
39
+ **AirXPay Flixora SDK** is a production-ready TypeScript SDK that simplifies seller onboarding for modern SaaS platforms. Built with multi-tenancy at its core, it provides a seamless backend integration experience for:
40
+
41
+ | Feature | Description |
42
+ |---------|-------------|
43
+ | πŸͺ **Seller Creation** | Create verified seller profiles with comprehensive business details |
44
+ | πŸ“„ **KYC Document Uploads** | Secure document submission and verification |
45
+ | 🏦 **Bank Account Linking** | Add and update payout bank accounts with validation |
46
+ | πŸ“Š **Real-Time Status Tracking** | Monitor onboarding and KYC status in real-time |
47
+ | πŸ” **Multi-Tenant Isolation** | Complete developer key isolation for multi-tenant architectures |
33
48
 
34
49
  ---
35
50
 
36
- ## 1. Overview
51
+ ## 🌐 Ecosystem Powered By
37
52
 
38
- The **AirXPay Flixora SDK - Seller Onboard** is a **robust, future-ready SDK** designed to handle seller creation, KYC document uploads, bank account management, and real-time onboarding status tracking.
53
+ <div align="center">
54
+ <table>
55
+ <tr>
56
+ <td align="center">⚑ <strong>AirXPay</strong></td>
57
+ <td>Payments & payouts engine</td>
58
+ </tr>
59
+ <tr>
60
+ <td align="center">πŸ’³ <strong>TizzyGo</strong></td>
61
+ <td>Payment routing layer with smart fallbacks</td>
62
+ </tr>
63
+ <tr>
64
+ <td align="center">🧠 <strong>TizzyOS</strong></td>
65
+ <td>Financial operating system infrastructure</td>
66
+ </tr>
67
+ <tr>
68
+ <td align="center">πŸ’¬ <strong>TizzyChat</strong></td>
69
+ <td>Real-time notifications (Coming Soon)</td>
70
+ </tr>
71
+ </table>
72
+ </div>
39
73
 
40
- Powered by the **Flixora Ecosystem**:
41
- - **TizzyGo**: Payment routing & processing
42
- - **TizzyOS**: Financial OS for SaaS & e-commerce
43
- - **TizzyChat**: Real-time notifications (coming soon)
74
+ ---
44
75
 
45
- **Key Principles:**
46
- - Seamless integration
47
- - Multi-developer SaaS readiness
48
- - Future-proof architecture
76
+ ## πŸš€ Version
49
77
 
50
- > "Build once, onboard anywhere – from startups to enterprise SaaS."
78
+ <h3 align="center">
79
+ <code>v1.0.8</code>
80
+ <br/>
81
+ <sub>Synced with ecosystem apps for version consistency ❀️</sub>
82
+ <br/>
83
+ <sub>We have updated this package from v1.0.6 β†’ v1.0.8 to match app versions. Thanks for understanding! 😊❀️</sub>
84
+ </h3>
51
85
 
52
86
  ---
53
87
 
54
- ## 2. Features
88
+ ## πŸ— Backend Architecture
55
89
 
56
- | Feature | Description |
57
- |---------|-------------|
58
- | Seller Creation | Create seller profiles with required metadata |
59
- | KYC Upload | Upload identity documents for verification |
60
- | Bank Integration | Add and update payout bank accounts |
61
- | Status Tracking | Poll for pending or completed onboarding |
62
- | Multi-Tenant Ready | Each developer or tenant isolated via keys |
63
- | TypeScript First | Full type safety & IntelliSense |
64
- | React / React Native Support | Native sheets, modal integration |
65
- | Logging & Retry | Automatic retry, request & response interceptors |
66
- | Security | Data encryption, key validation, rate limiting |
90
+ ```
91
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
92
+ β”‚ Your Backend Service β”‚
93
+ β”‚ (Node.js / Express / NestJS / etc) β”‚
94
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
95
+ β”‚
96
+ β–Ό
97
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
98
+ β”‚ AirXPay Flixora β”‚
99
+ β”‚ SDK (Backend) β”‚
100
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜
101
+ β”‚
102
+ β–Ό
103
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
104
+ β”‚ AirXPay API β”‚
105
+ β”‚ Gateway β”‚
106
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
107
+ β”‚
108
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
109
+ β–Ό β–Ό β–Ό
110
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
111
+ β”‚TizzyGo β”‚ β”‚TizzyOS β”‚ β”‚TizzyChat*
112
+ β”‚Payment β”‚ β”‚Financialβ”‚ β”‚ (Soon) β”‚
113
+ β”‚Routing β”‚ β”‚Processingβ”‚ β”‚Notifica-β”‚
114
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ └───tionsβ”€β”˜
115
+ ```
116
+
117
+ > **Note**: Multi-tenant isolation is automatically handled via developer keys. Each tenant operates in a completely isolated environment.
67
118
 
68
119
  ---
69
120
 
70
- ## 3. Installation
121
+ ## ✨ Core Features
122
+
123
+ | Feature | Status | Description |
124
+ |---------|--------|-------------|
125
+ | πŸ§‘β€πŸ’Ό Seller Creation | βœ… | Create verified seller profiles with business details |
126
+ | πŸ“‚ KYC Upload | βœ… | Upload and verify KYC documents |
127
+ | 🏦 Bank Integration | βœ… | Add/Update payout bank accounts with validation |
128
+ | πŸ“‘ Status Tracking | βœ… | Poll onboarding & KYC status in real-time |
129
+ | 🏒 Multi-Tenant Ready | βœ… | Isolated developer key architecture |
130
+ | 🧠 TypeScript First | βœ… | Full IntelliSense + type safety |
131
+ | πŸš€ Express Middleware | βœ… | Ready-to-use Express middleware |
132
+ | πŸ— NestJS Module | βœ… | Complete NestJS module integration |
133
+ | πŸ” Auto Retry & Logging | βœ… | Built-in axios interceptors |
134
+ | πŸ” Secure Key Validation | βœ… | Encrypted & validated requests |
71
135
 
72
- ### npm
73
- ```bash
74
- npm install airxpay
75
- ````
136
+ ---
76
137
 
77
- ### yarn
138
+ ## πŸ“¦ Installation
78
139
 
140
+ ### NPM
79
141
  ```bash
80
- yarn add airxpay
142
+ npm install @airxpay/init-sdk
81
143
  ```
82
144
 
83
- ### Peer Dependencies
145
+ ### Yarn
146
+ ```bash
147
+ yarn add @airxpay/init-sdk
148
+ ```
84
149
 
150
+ ### PNPM
85
151
  ```bash
86
- npm install axios
152
+ pnpm add @airxpay/init-sdk
87
153
  ```
88
- ---
89
154
 
90
- <div align="center">
91
- <img src="./assets/images/airxpay.png" alt="airxpay" width="100"/>
92
- </div>
155
+ ### Peer Dependencies
156
+ ```bash
157
+ npm install axios dotenv
158
+ # or
159
+ yarn add axios dotenv
160
+ ```
93
161
 
94
162
  ---
95
163
 
96
- ## 4. Environment Setup
97
-
98
- Create a `.env` file in your project root:
164
+ ## βš™οΈ Environment Setup
99
165
 
166
+ ### .env
100
167
  ```env
168
+ # AirXPay Configuration
101
169
  AIRXPAY_BASE_URL=https://api.airxpay.com
102
- AIRXPAY_PUBLIC_KEY=your_public_key
103
- AIRXPAY_SECRET_KEY=your_secret_key
104
- AIRXPAY_CLIENT_KEY=your_client_key
170
+ AIRXPAY_PUBLIC_KEY=pk_live_your_public_key_here
171
+ AIRXPAY_SECRET_KEY=sk_live_your_secret_key_here
172
+ AIRXPAY_CLIENT_KEY=ck_live_your_client_key_here
105
173
 
174
+ # Application
106
175
  NODE_ENV=development
107
- APP_NAME=YourApp
176
+ APP_NAME=YourAppName
177
+ PORT=3000
108
178
  ```
109
179
 
110
- Load environment variables using `dotenv` (if Node.js):
111
-
112
- ```ts
113
- import dotenv from 'dotenv';
180
+ ### Environment Validation
181
+ ```typescript
182
+ // config/env.ts
183
+ import dotenv from "dotenv";
114
184
  dotenv.config();
185
+
186
+ export const env = {
187
+ airxpay: {
188
+ baseUrl: process.env.AIRXPAY_BASE_URL!,
189
+ publicKey: process.env.AIRXPAY_PUBLIC_KEY!,
190
+ secretKey: process.env.AIRXPAY_SECRET_KEY!,
191
+ clientKey: process.env.AIRXPAY_CLIENT_KEY!
192
+ },
193
+ app: {
194
+ name: process.env.APP_NAME || 'MyApp',
195
+ env: process.env.NODE_ENV || 'development',
196
+ port: parseInt(process.env.PORT || '3000')
197
+ }
198
+ };
199
+
200
+ // Validate required variables
201
+ const requiredEnvVars = [
202
+ 'AIRXPAY_BASE_URL',
203
+ 'AIRXPAY_PUBLIC_KEY',
204
+ 'AIRXPAY_SECRET_KEY',
205
+ 'AIRXPAY_CLIENT_KEY'
206
+ ];
207
+
208
+ requiredEnvVars.forEach(envVar => {
209
+ if (!process.env[envVar]) {
210
+ throw new Error(`Missing required environment variable: ${envVar}`);
211
+ }
212
+ });
115
213
  ```
116
214
 
117
215
  ---
118
216
 
119
- ## 5. SDK Initialization
217
+ ## πŸ— SDK Initialization
120
218
 
121
- ```ts
122
- import { AirXPay } from 'airxpay';
219
+ ### Basic Initialization
220
+ ```typescript
221
+ // lib/airxpay.ts
222
+ import { AirXPay } from "@airxpay/init-sdk";
223
+ import { env } from "../config/env";
123
224
 
124
- const sdk = new AirXPay({
125
- baseUrl: process.env.AIRXPAY_BASE_URL!,
126
- secretKey: process.env.AIRXPAY_SECRET_KEY!,
127
- clientKey: process.env.AIRXPAY_CLIENT_KEY!
225
+ export const airxpay = new AirXPay({
226
+ baseUrl: env.airxpay.baseUrl,
227
+ secretKey: env.airxpay.secretKey,
228
+ clientKey: env.airxpay.clientKey
128
229
  });
129
230
  ```
130
231
 
232
+ ### Singleton Pattern
233
+ ```typescript
234
+ // lib/airxpay-singleton.ts
235
+ import { AirXPay } from "@airxpay/init-sdk";
236
+ import { env } from "../config/env";
237
+
238
+ class AirXPaySingleton {
239
+ private static instance: AirXPay;
240
+
241
+ private constructor() {}
242
+
243
+ public static getInstance(): AirXPay {
244
+ if (!AirXPaySingleton.instance) {
245
+ AirXPaySingleton.instance = new AirXPay({
246
+ baseUrl: env.airxpay.baseUrl,
247
+ secretKey: env.airxpay.secretKey,
248
+ clientKey: env.airxpay.clientKey
249
+ });
250
+ }
251
+ return AirXPaySingleton.instance;
252
+ }
253
+ }
254
+
255
+ export const airxpay = AirXPaySingleton.getInstance();
256
+ ```
257
+
131
258
  ---
132
259
 
133
- ## 6. API Methods
260
+ ## πŸ“˜ Available Imports
134
261
 
135
- | Method | Description |
136
- | ----------------------------------- | ------------------------------- |
137
- | `createSeller(seller, keys)` | Create a new seller |
138
- | `updateKyc(sellerId, docs)` | Upload KYC documents |
139
- | `updateBank(sellerId, bankDetails)` | Add or update bank info |
140
- | `getPendingStatus(sellerId)` | Fetch pending onboarding status |
262
+ | Import | Type | Purpose |
263
+ |--------|------|---------|
264
+ | `AirXPay` | `Class` | Main SDK class for all operations |
265
+ | `Seller` | `Interface` | Seller TypeScript interface |
266
+ | `Keys` | `Interface` | Developer key structure |
267
+ | `validateKeys` | `Function` | Pre-validate authentication keys |
268
+ | `base64ToBlob` | `Function` | Convert base64 to Blob for uploads |
269
+ | `OnboardingStatus` | `Enum` | Status tracking enum |
270
+ | `BusinessType` | `Enum` | Business type enumeration |
271
+ | `KycDocumentType` | `Enum` | KYC document types |
272
+ | `BankAccountType` | `Enum` | Bank account types |
273
+
274
+ > **πŸ’Ž Highly recommended for TypeScript projects**
141
275
 
142
276
  ---
143
277
 
144
- ## 7. Usage Examples
278
+ ## πŸ”Œ API Methods
279
+
280
+ | Method | Parameters | Return Type | Description |
281
+ |--------|------------|-------------|-------------|
282
+ | `createSeller()` | `(seller: Seller, keys: Keys)` | `Promise<SellerResponse>` | Create new seller profile |
283
+ | `updateKyc()` | `(sellerId: string, documents: KycDocument[])` | `Promise<KycStatus>` | Upload KYC documents |
284
+ | `updateBank()` | `(sellerId: string, bankDetails: BankDetails)` | `Promise<BankResponse>` | Update bank account details |
285
+ | `getPendingStatus()` | `(sellerId: string)` | `Promise<OnboardingStatus>` | Fetch onboarding status |
286
+ | `validateSeller()` | `(sellerId: string)` | `Promise<ValidationResult>` | Validate seller information |
287
+ | `getSellerById()` | `(sellerId: string)` | `Promise<Seller>` | Get seller details |
288
+ | `listSellers()` | `(filters?: SellerFilters)` | `Promise<Seller[]>` | List sellers with filters |
289
+ | `deleteSeller()` | `(sellerId: string)` | `Promise<void>` | Delete seller (soft delete) |
145
290
 
146
- ### React / React Native
291
+ ---
292
+
293
+ ## πŸ’» Usage Examples
294
+
295
+ ### πŸ”Ή Basic Express API
296
+
297
+ ```typescript
298
+ // server.ts
299
+ import express, { Request, Response } from 'express';
300
+ import { airxpay } from './lib/airxpay';
301
+ import { validateKeys } from '@airxpay/init-sdk';
302
+ import type { Seller, Keys } from '@airxpay/init-sdk';
303
+ import { env } from './config/env';
304
+
305
+ const app = express();
306
+ app.use(express.json());
307
+
308
+ // Create seller endpoint
309
+ app.post('/api/sellers', async (req: Request, res: Response) => {
310
+ try {
311
+ const sellerData: Seller = req.body;
312
+
313
+ const keys: Keys = {
314
+ publicKey: env.airxpay.publicKey,
315
+ secretKey: env.airxpay.secretKey,
316
+ clientKey: env.airxpay.clientKey
317
+ };
147
318
 
148
- ```tsx
149
- import React, { useEffect } from 'react';
150
- import { AirXPay } from 'airxpay';
319
+ // Optional pre-validation
320
+ validateKeys(keys);
151
321
 
152
- export const SellerComponent = () => {
153
- useEffect(() => {
154
- const sdk = new AirXPay({
155
- baseUrl: process.env.AIRXPAY_BASE_URL!,
156
- secretKey: process.env.AIRXPAY_SECRET_KEY!,
157
- clientKey: process.env.AIRXPAY_CLIENT_KEY!
322
+ const result = await airxpay.createSeller(sellerData, keys);
323
+
324
+ res.status(201).json({
325
+ success: true,
326
+ data: result
158
327
  });
328
+ } catch (error: any) {
329
+ res.status(error.response?.status || 500).json({
330
+ success: false,
331
+ error: error.message
332
+ });
333
+ }
334
+ });
159
335
 
160
- const seller = {
161
- sellerName: "Jane Doe",
162
- sellerEmail: "jane@example.com",
163
- sellerPhone: "+911234567890",
164
- businessName: "Jane's Store",
165
- businessType: "Retail",
166
- country: "IN"
167
- };
336
+ // Get seller status
337
+ app.get('/api/sellers/:sellerId/status', async (req: Request, res: Response) => {
338
+ try {
339
+ const { sellerId } = req.params;
340
+ const status = await airxpay.getPendingStatus(sellerId);
341
+
342
+ res.json({
343
+ success: true,
344
+ data: status
345
+ });
346
+ } catch (error: any) {
347
+ res.status(error.response?.status || 500).json({
348
+ success: false,
349
+ error: error.message
350
+ });
351
+ }
352
+ });
353
+
354
+ // Update KYC
355
+ app.post('/api/sellers/:sellerId/kyc', async (req: Request, res: Response) => {
356
+ try {
357
+ const { sellerId } = req.params;
358
+ const { documents } = req.body;
359
+
360
+ const result = await airxpay.updateKyc(sellerId, documents);
361
+
362
+ res.json({
363
+ success: true,
364
+ data: result
365
+ });
366
+ } catch (error: any) {
367
+ res.status(error.response?.status || 500).json({
368
+ success: false,
369
+ error: error.message
370
+ });
371
+ }
372
+ });
373
+
374
+ // Update bank details
375
+ app.put('/api/sellers/:sellerId/bank', async (req: Request, res: Response) => {
376
+ try {
377
+ const { sellerId } = req.params;
378
+ const bankDetails = req.body;
379
+
380
+ const result = await airxpay.updateBank(sellerId, bankDetails);
381
+
382
+ res.json({
383
+ success: true,
384
+ data: result
385
+ });
386
+ } catch (error: any) {
387
+ res.status(error.response?.status || 500).json({
388
+ success: false,
389
+ error: error.message
390
+ });
391
+ }
392
+ });
393
+
394
+ app.listen(3000, () => {
395
+ console.log('Server running on port 3000');
396
+ });
397
+ ```
168
398
 
399
+ ### πŸ”Ή Express with Middleware
400
+
401
+ ```typescript
402
+ // middleware/auth.ts
403
+ import { Request, Response, NextFunction } from 'express';
404
+ import { validateKeys } from '@airxpay/init-sdk';
405
+ import { env } from '../config/env';
406
+
407
+ export const validateAirXPayKeys = (req: Request, res: Response, next: NextFunction) => {
408
+ try {
169
409
  const keys = {
170
- publicKey: process.env.AIRXPAY_PUBLIC_KEY!,
171
- secretKey: process.env.AIRXPAY_SECRET_KEY!,
172
- clientKey: process.env.AIRXPAY_CLIENT_KEY!
410
+ publicKey: env.airxpay.publicKey,
411
+ secretKey: env.airxpay.secretKey,
412
+ clientKey: env.airxpay.clientKey
173
413
  };
414
+
415
+ validateKeys(keys);
416
+ next();
417
+ } catch (error) {
418
+ res.status(401).json({
419
+ success: false,
420
+ error: 'Invalid API keys configuration'
421
+ });
422
+ }
423
+ };
174
424
 
175
- sdk.createSeller(seller, keys).then(console.log).catch(console.error);
176
- }, []);
177
-
178
- return <div>Seller onboarding in progress...</div>;
425
+ // middleware/errorHandler.ts
426
+ import { Request, Response, NextFunction } from 'express';
427
+
428
+ export const airXPayErrorHandler = (error: any, req: Request, res: Response, next: NextFunction) => {
429
+ if (error.response) {
430
+ // AirXPay API error
431
+ const { status, data } = error.response;
432
+ res.status(status).json({
433
+ success: false,
434
+ error: data.message || 'AirXPay API error',
435
+ code: data.code
436
+ });
437
+ } else if (error.request) {
438
+ // Network error
439
+ res.status(503).json({
440
+ success: false,
441
+ error: 'Unable to reach AirXPay service'
442
+ });
443
+ } else {
444
+ // Other errors
445
+ res.status(500).json({
446
+ success: false,
447
+ error: error.message
448
+ });
449
+ }
179
450
  };
180
451
  ```
181
452
 
182
- ### TypeScript / JavaScript (Node.js)
453
+ ### πŸ”Ή Complete Express Application
454
+
455
+ ```typescript
456
+ // app.ts
457
+ import express from 'express';
458
+ import { airxpay } from './lib/airxpay';
459
+ import { validateAirXPayKeys } from './middleware/auth';
460
+ import { airXPayErrorHandler } from './middleware/errorHandler';
461
+ import { env } from './config/env';
462
+
463
+ const app = express();
464
+
465
+ // Middleware
466
+ app.use(express.json());
467
+ app.use(validateAirXPayKeys);
468
+
469
+ // Routes
470
+ app.post('/api/v1/sellers', async (req, res, next) => {
471
+ try {
472
+ const result = await airxpay.createSeller(req.body, {
473
+ publicKey: env.airxpay.publicKey,
474
+ secretKey: env.airxpay.secretKey,
475
+ clientKey: env.airxpay.clientKey
476
+ });
477
+
478
+ res.status(201).json(result);
479
+ } catch (error) {
480
+ next(error);
481
+ }
482
+ });
483
+
484
+ app.get('/api/v1/sellers/:id', async (req, res, next) => {
485
+ try {
486
+ const seller = await airxpay.getSellerById(req.params.id);
487
+ res.json(seller);
488
+ } catch (error) {
489
+ next(error);
490
+ }
491
+ });
492
+
493
+ app.get('/api/v1/sellers', async (req, res, next) => {
494
+ try {
495
+ const sellers = await airxpay.listSellers(req.query);
496
+ res.json(sellers);
497
+ } catch (error) {
498
+ next(error);
499
+ }
500
+ });
501
+
502
+ app.post('/api/v1/sellers/:id/kyc', async (req, res, next) => {
503
+ try {
504
+ const result = await airxpay.updateKyc(req.params.id, req.body.documents);
505
+ res.json(result);
506
+ } catch (error) {
507
+ next(error);
508
+ }
509
+ });
510
+
511
+ app.put('/api/v1/sellers/:id/bank', async (req, res, next) => {
512
+ try {
513
+ const result = await airxpay.updateBank(req.params.id, req.body);
514
+ res.json(result);
515
+ } catch (error) {
516
+ next(error);
517
+ }
518
+ });
519
+
520
+ app.get('/api/v1/sellers/:id/status', async (req, res, next) => {
521
+ try {
522
+ const status = await airxpay.getPendingStatus(req.params.id);
523
+ res.json(status);
524
+ } catch (error) {
525
+ next(error);
526
+ }
527
+ });
528
+
529
+ // Error handling
530
+ app.use(airXPayErrorHandler);
531
+
532
+ app.listen(env.port, () => {
533
+ console.log(`Server running on port ${env.port}`);
534
+ });
535
+ ```
536
+
537
+ ---
538
+
539
+ ### πŸ”Ή NestJS Module Integration
540
+
541
+ ```typescript
542
+ // airxpay.module.ts
543
+ import { Module, Global } from '@nestjs/common';
544
+ import { AirXPayService } from './airxpay.service';
545
+ import { AirXPayController } from './airxpay.controller';
546
+ import { ConfigModule, ConfigService } from '@nestjs/config';
547
+
548
+ @Global()
549
+ @Module({
550
+ imports: [ConfigModule],
551
+ providers: [
552
+ {
553
+ provide: 'AIRXPAY_OPTIONS',
554
+ useFactory: (configService: ConfigService) => ({
555
+ baseUrl: configService.get('AIRXPAY_BASE_URL'),
556
+ secretKey: configService.get('AIRXPAY_SECRET_KEY'),
557
+ clientKey: configService.get('AIRXPAY_CLIENT_KEY')
558
+ }),
559
+ inject: [ConfigService]
560
+ },
561
+ AirXPayService
562
+ ],
563
+ controllers: [AirXPayController],
564
+ exports: [AirXPayService]
565
+ })
566
+ export class AirXPayModule {}
567
+
568
+ // airxpay.service.ts
569
+ import { Injectable, Inject } from '@nestjs/common';
570
+ import { AirXPay } from '@airxpay/init-sdk';
571
+ import type { Seller, Keys, BankDetails, KycDocument } from '@airxpay/init-sdk';
572
+
573
+ @Injectable()
574
+ export class AirXPayService {
575
+ private sdk: AirXPay;
576
+ private keys: Keys;
577
+
578
+ constructor(@Inject('AIRXPAY_OPTIONS') private options: any) {
579
+ this.sdk = new AirXPay(options);
580
+ this.keys = {
581
+ publicKey: options.publicKey,
582
+ secretKey: options.secretKey,
583
+ clientKey: options.clientKey
584
+ };
585
+ }
586
+
587
+ async createSeller(sellerData: Seller) {
588
+ return this.sdk.createSeller(sellerData, this.keys);
589
+ }
590
+
591
+ async getSeller(sellerId: string) {
592
+ return this.sdk.getSellerById(sellerId);
593
+ }
594
+
595
+ async listSellers(filters?: any) {
596
+ return this.sdk.listSellers(filters);
597
+ }
598
+
599
+ async updateKyc(sellerId: string, documents: KycDocument[]) {
600
+ return this.sdk.updateKyc(sellerId, documents);
601
+ }
602
+
603
+ async updateBank(sellerId: string, bankDetails: BankDetails) {
604
+ return this.sdk.updateBank(sellerId, bankDetails);
605
+ }
606
+
607
+ async getStatus(sellerId: string) {
608
+ return this.sdk.getPendingStatus(sellerId);
609
+ }
610
+
611
+ async deleteSeller(sellerId: string) {
612
+ return this.sdk.deleteSeller(sellerId);
613
+ }
614
+ }
615
+
616
+ // airxpay.controller.ts
617
+ import { Controller, Post, Get, Put, Body, Param, Query } from '@nestjs/common';
618
+ import { AirXPayService } from './airxpay.service';
619
+
620
+ @Controller('api/v1/sellers')
621
+ export class AirXPayController {
622
+ constructor(private readonly airxpayService: AirXPayService) {}
623
+
624
+ @Post()
625
+ async createSeller(@Body() sellerData: any) {
626
+ return this.airxpayService.createSeller(sellerData);
627
+ }
628
+
629
+ @Get(':id')
630
+ async getSeller(@Param('id') id: string) {
631
+ return this.airxpayService.getSeller(id);
632
+ }
633
+
634
+ @Get()
635
+ async listSellers(@Query() filters: any) {
636
+ return this.airxpayService.listSellers(filters);
637
+ }
638
+
639
+ @Post(':id/kyc')
640
+ async updateKyc(@Param('id') id: string, @Body('documents') documents: any[]) {
641
+ return this.airxpayService.updateKyc(id, documents);
642
+ }
643
+
644
+ @Put(':id/bank')
645
+ async updateBank(@Param('id') id: string, @Body() bankDetails: any) {
646
+ return this.airxpayService.updateBank(id, bankDetails);
647
+ }
648
+
649
+ @Get(':id/status')
650
+ async getStatus(@Param('id') id: string) {
651
+ return this.airxpayService.getStatus(id);
652
+ }
653
+
654
+ @Post(':id/delete')
655
+ async deleteSeller(@Param('id') id: string) {
656
+ return this.airxpayService.deleteSeller(id);
657
+ }
658
+ }
659
+ ```
660
+
661
+ ---
183
662
 
184
- ```ts
185
- import { AirXPay } from 'airxpay';
663
+ ### πŸ”Ή TypeScript Service Class
186
664
 
187
- const sdk = new AirXPay({
188
- baseUrl: process.env.AIRXPAY_BASE_URL!,
189
- secretKey: process.env.AIRXPAY_SECRET_KEY!,
190
- clientKey: process.env.AIRXPAY_CLIENT_KEY!
665
+ ```typescript
666
+ // services/SellerService.ts
667
+ import { AirXPay, validateKeys } from '@airxpay/init-sdk';
668
+ import type { Seller, Keys, BankDetails, KycDocument } from '@airxpay/init-sdk';
669
+ import { env } from '../config/env';
670
+
671
+ export class SellerService {
672
+ private sdk: AirXPay;
673
+ private keys: Keys;
674
+
675
+ constructor() {
676
+ this.sdk = new AirXPay({
677
+ baseUrl: env.airxpay.baseUrl,
678
+ secretKey: env.airxpay.secretKey,
679
+ clientKey: env.airxpay.clientKey
680
+ });
681
+
682
+ this.keys = {
683
+ publicKey: env.airxpay.publicKey,
684
+ secretKey: env.airxpay.secretKey,
685
+ clientKey: env.airxpay.clientKey
686
+ };
687
+
688
+ validateKeys(this.keys);
689
+ }
690
+
691
+ async onboardSeller(sellerData: Seller) {
692
+ try {
693
+ // Step 1: Create seller
694
+ const seller = await this.sdk.createSeller(sellerData, this.keys);
695
+
696
+ // Step 2: Return seller ID for next steps
697
+ return {
698
+ success: true,
699
+ sellerId: seller.id,
700
+ message: 'Seller created successfully. Proceed to KYC.'
701
+ };
702
+ } catch (error) {
703
+ throw this.handleError(error);
704
+ }
705
+ }
706
+
707
+ async submitKyc(sellerId: string, documents: KycDocument[]) {
708
+ try {
709
+ const result = await this.sdk.updateKyc(sellerId, documents);
710
+ return {
711
+ success: true,
712
+ status: result.status,
713
+ message: 'KYC submitted successfully'
714
+ };
715
+ } catch (error) {
716
+ throw this.handleError(error);
717
+ }
718
+ }
719
+
720
+ async addBankDetails(sellerId: string, bankDetails: BankDetails) {
721
+ try {
722
+ const result = await this.sdk.updateBank(sellerId, bankDetails);
723
+ return {
724
+ success: true,
725
+ bankAccount: result,
726
+ message: 'Bank details added successfully'
727
+ };
728
+ } catch (error) {
729
+ throw this.handleError(error);
730
+ }
731
+ }
732
+
733
+ async getOnboardingStatus(sellerId: string) {
734
+ try {
735
+ const status = await this.sdk.getPendingStatus(sellerId);
736
+ return {
737
+ success: true,
738
+ status,
739
+ isComplete: status === 'COMPLETED'
740
+ };
741
+ } catch (error) {
742
+ throw this.handleError(error);
743
+ }
744
+ }
745
+
746
+ private handleError(error: any) {
747
+ // Log error
748
+ console.error('AirXPay Error:', {
749
+ status: error.response?.status,
750
+ data: error.response?.data,
751
+ message: error.message
752
+ });
753
+
754
+ // Return formatted error
755
+ return {
756
+ success: false,
757
+ error: error.response?.data?.message || error.message,
758
+ code: error.response?.data?.code || 'UNKNOWN_ERROR'
759
+ };
760
+ }
761
+ }
762
+ ```
763
+
764
+ ---
765
+
766
+ ### πŸ”Ή Background Job Processing
767
+
768
+ ```typescript
769
+ // jobs/onboardingMonitor.ts
770
+ import { SellerService } from '../services/SellerService';
771
+ import { Queue, Worker } from 'bullmq';
772
+
773
+ const sellerService = new SellerService();
774
+ const onboardingQueue = new Queue('onboarding-status');
775
+
776
+ // Add jobs to queue
777
+ export async function monitorOnboardingStatus(sellerId: string) {
778
+ await onboardingQueue.add('check-status', { sellerId }, {
779
+ repeat: {
780
+ every: 60000 // Check every minute
781
+ },
782
+ attempts: 10,
783
+ backoff: {
784
+ type: 'exponential',
785
+ delay: 60000
786
+ }
787
+ });
788
+ }
789
+
790
+ // Process queue
791
+ const worker = new Worker('onboarding-status', async job => {
792
+ const { sellerId } = job.data;
793
+
794
+ try {
795
+ const status = await sellerService.getOnboardingStatus(sellerId);
796
+
797
+ if (status.isComplete) {
798
+ // Onboarding complete - trigger webhook
799
+ await triggerWebhook(sellerId, status);
800
+ return; // Stop monitoring
801
+ }
802
+
803
+ // Re-queue if not complete
804
+ await monitorOnboardingStatus(sellerId);
805
+ } catch (error) {
806
+ console.error(`Failed to check status for seller ${sellerId}:`, error);
807
+ }
191
808
  });
192
809
 
193
- const sellerData = { /* seller object */ };
194
- const keys = { /* developer keys */ };
810
+ async function triggerWebhook(sellerId: string, status: any) {
811
+ // Send webhook to your application
812
+ await fetch('https://your-app.com/webhooks/onboarding-complete', {
813
+ method: 'POST',
814
+ headers: { 'Content-Type': 'application/json' },
815
+ body: JSON.stringify({ sellerId, status })
816
+ });
817
+ }
818
+ ```
195
819
 
196
- sdk.createSeller(sellerData, keys)
197
- .then(res => console.log(res))
198
- .catch(err => console.error(err));
820
+ ---
821
+
822
+ ## πŸ“ Folder Structure
823
+
824
+ ```
825
+ airxpay-backend/
826
+ β”œβ”€β”€ πŸ“ src/
827
+ β”‚ β”œβ”€β”€ πŸ“„ index.ts # Main entry point
828
+ β”‚ β”œβ”€β”€ πŸ“ lib/
829
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ airxpay.ts # SDK initialization
830
+ β”‚ β”‚ └── πŸ“„ singleton.ts # Singleton pattern
831
+ β”‚ β”œβ”€β”€ πŸ“ config/
832
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ env.ts # Environment config
833
+ β”‚ β”‚ └── πŸ“„ constants.ts # Constants
834
+ β”‚ β”œβ”€β”€ πŸ“ services/
835
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ seller.service.ts # Seller service
836
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ kyc.service.ts # KYC service
837
+ β”‚ β”‚ └── πŸ“„ bank.service.ts # Bank service
838
+ β”‚ β”œβ”€β”€ πŸ“ controllers/
839
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ seller.controller.ts # Express controller
840
+ β”‚ β”‚ └── πŸ“„ webhook.controller.ts # Webhook handler
841
+ β”‚ β”œβ”€β”€ πŸ“ middleware/
842
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ auth.ts # Auth middleware
843
+ β”‚ β”‚ └── πŸ“„ errorHandler.ts # Error handling
844
+ β”‚ β”œβ”€β”€ πŸ“ jobs/
845
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ onboarding-monitor.ts # Background jobs
846
+ β”‚ β”‚ └── πŸ“„ queue.ts # Queue setup
847
+ β”‚ β”œβ”€β”€ πŸ“ types/
848
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ seller.ts # Seller types
849
+ β”‚ β”‚ β”œβ”€β”€ πŸ“„ bank.ts # Bank types
850
+ β”‚ β”‚ └── πŸ“„ kyc.ts # KYC types
851
+ β”‚ └── πŸ“ utils/
852
+ β”‚ β”œβ”€β”€ πŸ“„ validation.ts # Validation utils
853
+ β”‚ └── πŸ“„ logging.ts # Logging setup
854
+ β”œβ”€β”€ πŸ“ dist/ # Compiled output
855
+ β”œβ”€β”€ πŸ“„ package.json
856
+ β”œβ”€β”€ πŸ“„ tsconfig.json
857
+ β”œβ”€β”€ πŸ“„ README.md
858
+ β”œβ”€β”€ πŸ“„ .env.example
859
+ └── πŸ“„ .gitignore
199
860
  ```
200
861
 
201
862
  ---
202
863
 
203
- ## 8. Folder Structure
864
+ ## πŸ” Security & Compliance
865
+
866
+ ### Key Security Features
867
+
868
+ - **πŸ”’ Encrypted Key Transmission**: All keys are encrypted during transmission
869
+ - **πŸ›‘οΈ Secret Key Protection**: Secret key never exposed to client-side
870
+ - **πŸ‘₯ Multi-tenant Isolation**: Complete developer key isolation
871
+ - **βœ… Input Validation**: Comprehensive validation before request dispatch
872
+ - **πŸ“ Audit Logging**: Complete audit trail for all operations
873
+ - **πŸ”‘ Key Rotation**: Support for seamless key rotation
874
+
875
+ ### Security Best Practices
876
+
877
+ ```typescript
878
+ // config/security.ts
879
+ import { randomBytes } from 'crypto';
880
+ import { env } from './env';
881
+
882
+ export const securityConfig = {
883
+ // Rate limiting
884
+ rateLimit: {
885
+ windowMs: 15 * 60 * 1000, // 15 minutes
886
+ max: 100 // limit each IP to 100 requests per windowMs
887
+ },
888
+
889
+ // Key rotation
890
+ keyRotation: {
891
+ enabled: true,
892
+ interval: '30d', // Rotate every 30 days
893
+ gracePeriod: '7d' // Old keys valid for 7 days after rotation
894
+ },
895
+
896
+ // Audit logging
897
+ auditLog: {
898
+ enabled: true,
899
+ events: [
900
+ 'SELLER_CREATED',
901
+ 'KYC_UPLOADED',
902
+ 'BANK_UPDATED',
903
+ 'STATUS_CHECKED'
904
+ ],
905
+ retention: '90d' // Keep logs for 90 days
906
+ }
907
+ };
204
908
 
909
+ // Generate request ID for tracking
910
+ export const generateRequestId = (): string => {
911
+ return randomBytes(16).toString('hex');
912
+ };
205
913
  ```
206
- airxpay/
207
- β”œβ”€ src/
208
- β”‚ β”œβ”€ index.ts
209
- β”‚ β”œβ”€ api/
210
- β”‚ β”œβ”€ config/
211
- β”‚ β”œβ”€ types/
212
- β”‚ └─ utils/
213
- β”œβ”€ dist/ # Compiled JS
214
- β”œβ”€ package.json
215
- β”œβ”€ tsconfig.json
216
- └─ README.md
914
+
915
+ ---
916
+
917
+ ## πŸ”΄ Error Handling Matrix
918
+
919
+ | Status | Meaning | Recommended Action |
920
+ |--------|---------|-------------------|
921
+ | **200** | Success | Process response normally |
922
+ | **201** | Created | Resource created successfully |
923
+ | **400** | Bad Request | Validate input parameters |
924
+ | **401** | Unauthorized | Check API keys and regenerate if needed |
925
+ | **403** | Forbidden | Verify permissions and access rights |
926
+ | **404** | Not Found | Verify seller ID exists |
927
+ | **409** | Conflict | Handle duplicate entries gracefully |
928
+ | **422** | Unprocessable Entity | Check KYC document format |
929
+ | **429** | Too Many Requests | Implement exponential backoff |
930
+ | **500** | Server Error | Retry with exponential backoff |
931
+ | **502** | Bad Gateway | Check network connectivity |
932
+ | **503** | Service Unavailable | Check service status |
933
+
934
+ ### Error Handling Service
935
+
936
+ ```typescript
937
+ // utils/errorHandler.ts
938
+ export class AirXPayErrorHandler {
939
+ static handle(error: any) {
940
+ if (error.response) {
941
+ // The request was made and the server responded with a status code
942
+ const { status, data } = error.response;
943
+
944
+ switch (status) {
945
+ case 400:
946
+ return {
947
+ code: 'VALIDATION_ERROR',
948
+ message: data.message || 'Invalid input data',
949
+ retry: false
950
+ };
951
+ case 401:
952
+ return {
953
+ code: 'AUTH_ERROR',
954
+ message: 'Invalid API keys',
955
+ retry: false,
956
+ action: 'REFRESH_KEYS'
957
+ };
958
+ case 403:
959
+ return {
960
+ code: 'FORBIDDEN',
961
+ message: 'Access denied',
962
+ retry: false,
963
+ action: 'CHECK_PERMISSIONS'
964
+ };
965
+ case 404:
966
+ return {
967
+ code: 'NOT_FOUND',
968
+ message: 'Resource not found',
969
+ retry: false
970
+ };
971
+ case 409:
972
+ return {
973
+ code: 'CONFLICT',
974
+ message: 'Resource already exists',
975
+ retry: false
976
+ };
977
+ case 422:
978
+ return {
979
+ code: 'KYC_ERROR',
980
+ message: data.message || 'KYC validation failed',
981
+ retry: true,
982
+ details: data.details
983
+ };
984
+ case 429:
985
+ return {
986
+ code: 'RATE_LIMIT',
987
+ message: 'Too many requests',
988
+ retry: true,
989
+ retryAfter: data.retryAfter || 60
990
+ };
991
+ case 500:
992
+ case 502:
993
+ case 503:
994
+ return {
995
+ code: 'SERVER_ERROR',
996
+ message: 'AirXPay service unavailable',
997
+ retry: true,
998
+ retryAfter: 30
999
+ };
1000
+ default:
1001
+ return {
1002
+ code: 'UNKNOWN_ERROR',
1003
+ message: error.message,
1004
+ retry: false
1005
+ };
1006
+ }
1007
+ } else if (error.request) {
1008
+ // The request was made but no response was received
1009
+ return {
1010
+ code: 'NETWORK_ERROR',
1011
+ message: 'Unable to reach AirXPay service',
1012
+ retry: true,
1013
+ retryAfter: 10
1014
+ };
1015
+ } else {
1016
+ // Something happened in setting up the request
1017
+ return {
1018
+ code: 'REQUEST_SETUP_ERROR',
1019
+ message: error.message,
1020
+ retry: false
1021
+ };
1022
+ }
1023
+ }
1024
+ }
217
1025
  ```
218
1026
 
219
1027
  ---
220
1028
 
221
- ## 9. Advanced Usage
1029
+ ## 🧩 Advanced Backend Patterns
1030
+
1031
+ ### πŸ”„ Multi-Tenant Factory Pattern
1032
+
1033
+ ```typescript
1034
+ // lib/multi-tenant-factory.ts
1035
+ import { AirXPay } from '@airxpay/init-sdk';
1036
+ import type { Keys } from '@airxpay/init-sdk';
1037
+
1038
+ interface TenantConfig {
1039
+ tenantId: string;
1040
+ baseUrl: string;
1041
+ keys: Keys;
1042
+ }
1043
+
1044
+ export class AirXPayTenantFactory {
1045
+ private tenants: Map<string, AirXPay> = new Map();
1046
+
1047
+ registerTenant(config: TenantConfig): void {
1048
+ const sdk = new AirXPay({
1049
+ baseUrl: config.baseUrl,
1050
+ secretKey: config.keys.secretKey,
1051
+ clientKey: config.keys.clientKey
1052
+ });
1053
+
1054
+ this.tenants.set(config.tenantId, sdk);
1055
+ }
1056
+
1057
+ getForTenant(tenantId: string): AirXPay {
1058
+ const sdk = this.tenants.get(tenantId);
1059
+ if (!sdk) {
1060
+ throw new Error(`No SDK found for tenant: ${tenantId}`);
1061
+ }
1062
+ return sdk;
1063
+ }
1064
+
1065
+ removeTenant(tenantId: string): void {
1066
+ this.tenants.delete(tenantId);
1067
+ }
1068
+ }
1069
+ ```
1070
+
1071
+ ### 🎯 Repository Pattern
1072
+
1073
+ ```typescript
1074
+ // repositories/seller.repository.ts
1075
+ import { AirXPay } from '@airxpay/init-sdk';
1076
+ import type { Seller, SellerFilters } from '@airxpay/init-sdk';
1077
+
1078
+ export class SellerRepository {
1079
+ constructor(private sdk: AirXPay, private keys: any) {}
1080
+
1081
+ async create(sellerData: Seller) {
1082
+ return this.sdk.createSeller(sellerData, this.keys);
1083
+ }
222
1084
 
223
- * Singleton instance for global SDK
224
- * Factory pattern for multi-developer support
225
- * React Native bottom sheet integration
226
- * Automatic retries and interceptors
227
- * Logging & custom error handling
1085
+ async findById(id: string) {
1086
+ return this.sdk.getSellerById(id);
1087
+ }
1088
+
1089
+ async findAll(filters?: SellerFilters) {
1090
+ return this.sdk.listSellers(filters);
1091
+ }
1092
+
1093
+ async updateKYC(id: string, documents: any[]) {
1094
+ return this.sdk.updateKyc(id, documents);
1095
+ }
1096
+
1097
+ async updateBank(id: string, bankDetails: any) {
1098
+ return this.sdk.updateBank(id, bankDetails);
1099
+ }
1100
+
1101
+ async getStatus(id: string) {
1102
+ return this.sdk.getPendingStatus(id);
1103
+ }
1104
+
1105
+ async delete(id: string) {
1106
+ return this.sdk.deleteSeller(id);
1107
+ }
1108
+ }
1109
+ ```
1110
+
1111
+ ### πŸ“Š Caching Layer
1112
+
1113
+ ```typescript
1114
+ // cache/seller.cache.ts
1115
+ import NodeCache from 'node-cache';
1116
+ import { SellerRepository } from '../repositories/seller.repository';
1117
+
1118
+ export class SellerCache {
1119
+ private cache: NodeCache;
1120
+ private ttl = 300; // 5 minutes
1121
+
1122
+ constructor(private repository: SellerRepository) {
1123
+ this.cache = new NodeCache({ stdTTL: this.ttl });
1124
+ }
1125
+
1126
+ async getSeller(id: string) {
1127
+ const cacheKey = `seller:${id}`;
1128
+
1129
+ // Try cache first
1130
+ let seller = this.cache.get(cacheKey);
1131
+
1132
+ if (!seller) {
1133
+ // Cache miss - fetch from API
1134
+ seller = await this.repository.findById(id);
1135
+ this.cache.set(cacheKey, seller);
1136
+ }
1137
+
1138
+ return seller;
1139
+ }
1140
+
1141
+ async getStatus(id: string) {
1142
+ const cacheKey = `status:${id}`;
1143
+
1144
+ let status = this.cache.get(cacheKey);
1145
+
1146
+ if (!status) {
1147
+ status = await this.repository.getStatus(id);
1148
+ this.cache.set(cacheKey, status, 60); // 1 minute TTL for status
1149
+ }
1150
+
1151
+ return status;
1152
+ }
1153
+
1154
+ invalidate(id: string) {
1155
+ this.cache.del(`seller:${id}`);
1156
+ this.cache.del(`status:${id}`);
1157
+ }
1158
+ }
1159
+ ```
1160
+
1161
+ ---
1162
+
1163
+ ## πŸŒ™ Dark Mode Optimization
1164
+
1165
+ This README is optimized for:
1166
+
1167
+ - **GitHub Dark Theme** - Perfect contrast and readability
1168
+ - **Clean badge contrast** - High visibility badges
1169
+ - **Monospace clarity** - Crystal clear code blocks
1170
+ - **Center-aligned hero section** - Professional presentation
228
1171
 
229
1172
  ---
230
1173
 
231
- ## 10. Error Handling
1174
+ ## ❓ Backend FAQ
1175
+
1176
+ ### Can I use this in production?
1177
+
1178
+ βœ… **Yes!** The SDK is production-ready and used by multiple enterprise SaaS platforms.
1179
+
1180
+ ### Does it support rate limiting?
1181
+
1182
+ βœ… **Yes!** The SDK has built-in support for rate limiting and exponential backoff.
1183
+
1184
+ ### Can I use it with Express?
1185
+
1186
+ βœ… **Yes!** Check out the Express examples above with full middleware support.
1187
+
1188
+ ### Does it work with NestJS?
232
1189
 
233
- | Status | Meaning | Recommended Action |
234
- | ------ | ------------ | ------------------ |
235
- | 200 | Success | Process normally |
236
- | 400 | Bad Request | Validate input |
237
- | 401 | Unauthorized | Refresh keys |
238
- | 403 | Forbidden | Check permissions |
239
- | 404 | Not Found | Resource missing |
240
- | 409 | Conflict | Handle duplicate |
241
- | 500 | Server Error | Retry request |
1190
+ βœ… **Yes!** Complete NestJS module integration is provided.
1191
+
1192
+ ### How do I handle webhooks?
1193
+
1194
+ The SDK provides webhook verification and handling utilities. Check the webhook controller example.
1195
+
1196
+ ### Is there caching support?
1197
+
1198
+ βœ… **Yes!** Implement the caching layer pattern shown above for optimal performance.
1199
+
1200
+ ### What about error handling?
1201
+
1202
+ Comprehensive error handling with status code matrix and retry logic is built-in.
1203
+
1204
+ ### Can I monitor onboarding status in background?
1205
+
1206
+ βœ… **Yes!** Use the background job processing example with BullMQ.
242
1207
 
243
1208
  ---
244
1209
 
245
- ## 11. FAQ
1210
+ ## πŸ“ž Support & Resources
246
1211
 
247
- * Can I use this in React Native? βœ… Yes
248
- * Do I need TypeScript? ❌ Optional, works with JS too
249
- * Multi-developer support? βœ… Keys are isolated per developer
1212
+ <div align="center">
1213
+ <table>
1214
+ <tr>
1215
+ <td align="center">
1216
+ <a href="https://docs.flixora.com/airxpay/backend">
1217
+ <img src="https://img.shields.io/badge/Documentation-πŸ“˜-blue?style=for-the-badge" alt="Docs" />
1218
+ </a>
1219
+ </td>
1220
+ <td align="center">
1221
+ <a href="https://discord.gg/flixora">
1222
+ <img src="https://img.shields.io/badge/Discord-πŸ’¬-5865F2?style=for-the-badge&logo=discord" alt="Discord" />
1223
+ </a>
1224
+ </td>
1225
+ <td align="center">
1226
+ <a href="mailto:support@flixora.com">
1227
+ <img src="https://img.shields.io/badge/Email-πŸ“§-EA4335?style=for-the-badge&logo=gmail" alt="Email" />
1228
+ </a>
1229
+ </td>
1230
+ </tr>
1231
+ </table>
1232
+
1233
+ <br/>
1234
+
1235
+ <table>
1236
+ <tr>
1237
+ <td align="center">
1238
+ <a href="https://github.com/flixora/airxpay-express-example">
1239
+ <img src="https://img.shields.io/badge/Express-Example-000000?style=for-the-badge&logo=express" alt="Express Example" />
1240
+ </a>
1241
+ </td>
1242
+ <td align="center">
1243
+ <a href="https://github.com/flixora/airxpay-nestjs-example">
1244
+ <img src="https://img.shields.io/badge/NestJS-Example-E0234E?style=for-the-badge&logo=nestjs" alt="NestJS Example" />
1245
+ </a>
1246
+ </td>
1247
+ <td align="center">
1248
+ <a href="https://github.com/flixora/airxpay-microservice-example">
1249
+ <img src="https://img.shields.io/badge/Microservice-Example-FF6B6B?style=for-the-badge&logo=microgenetics" alt="Microservice Example" />
1250
+ </a>
1251
+ </td>
1252
+ </tr>
1253
+ </table>
1254
+ </div>
250
1255
 
251
1256
  ---
252
1257
 
253
- ## 12. Support & Contact
1258
+ ## 🀝 Contributing
254
1259
 
255
- * Docs: [https://docs.flixora.com/airxpay](https://docs.flixora.com/airxpay)
256
- * Discord: [https://discord.gg/flixora](https://discord.gg/flixora)
257
- * Email: [support@flixora.com](mailto:support@flixora.com)
1260
+ We welcome contributions! Please see our [Contributing Guidelines](CONTRIBUTING.md) for details.
1261
+
1262
+ 1. Fork the repository
1263
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
1264
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
1265
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
1266
+ 5. Open a Pull Request
258
1267
 
259
1268
  ---
260
1269
 
261
- ## 13. License
1270
+ ## πŸ“ˆ Backend Roadmap
1271
+
1272
+ - [x] v1.0.0 - Core seller onboarding
1273
+ - [x] v1.0.8 - Multi-tenant isolation
1274
+ - [x] v1.1.0 - Express middleware
1275
+ - [x] v1.1.5 - NestJS module
1276
+ - [x] v1.2.0 - Webhook support
1277
+ - [ ] v1.3.0 - Advanced caching
1278
+ - [ ] v1.4.0 - GraphQL support
1279
+ - [ ] v1.5.0 - gRPC support
1280
+ - [ ] v2.0.0 - Real-time streaming
262
1281
 
263
- MIT License Β© 2026 Flixora Technologies
1282
+ ---
264
1283
 
265
- **Your's Simless Smile😊**
266
- Build with Flixora EcoSystem❀️
1284
+ ## βš–οΈ License
1285
+
1286
+ <div align="center">
1287
+ <strong>MIT License Β© 2026 Flixora Technologies</strong>
1288
+ <br/>
1289
+ <sub>Permission is hereby granted, free of charge, to any person obtaining a copy</sub>
1290
+ <br/>
1291
+ <sub>of this software and associated documentation files...</sub>
1292
+ </div>
267
1293
 
268
1294
  ---
1295
+
1296
+ ## ❀️ Built With Vision
1297
+
1298
+ <div align="center">
1299
+ <p>
1300
+ <strong>Designed for startups.</strong><br/>
1301
+ <strong>Engineered for enterprise.</strong><br/>
1302
+ <strong>Future-proof for SaaS scale.</strong>
1303
+ </p>
1304
+
1305
+ <p>
1306
+ <sub>Made with ❀️ by the Flixora Team</sub>
1307
+ </p>
1308
+
1309
+ <p>
1310
+ <sub>Specifically optimized for backend integration | Node.js | Express | NestJS</sub>
1311
+ </p>
1312
+
1313
+ <p>
1314
+ <a href="#-airxpay-flixora-sdk---backend-integration">⬆️ Back to Top</a>
1315
+ </p>
1316
+ </div>