@flixora/airxpay-sdk-init-ui 1.0.0

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.
Files changed (62) hide show
  1. package/LICENSE.md +21 -0
  2. package/README.md +623 -0
  3. package/dist/api/client.d.ts +2 -0
  4. package/dist/api/client.js +78 -0
  5. package/dist/api/merchantProxy.d.ts +11 -0
  6. package/dist/api/merchantProxy.js +170 -0
  7. package/dist/assets/images/airxpay.png +0 -0
  8. package/dist/assets/images/flixora.png +0 -0
  9. package/dist/components/common/CountryDropdown.d.ts +17 -0
  10. package/dist/components/common/CountryDropdown.js +138 -0
  11. package/dist/components/common/FileUploader.d.ts +16 -0
  12. package/dist/components/common/FileUploader.js +219 -0
  13. package/dist/components/common/StepIndicator.d.ts +11 -0
  14. package/dist/components/common/StepIndicator.js +269 -0
  15. package/dist/components/steps/BankDetails.d.ts +10 -0
  16. package/dist/components/steps/BankDetails.js +630 -0
  17. package/dist/components/steps/BasicDetailsForm.d.ts +10 -0
  18. package/dist/components/steps/BasicDetailsForm.js +569 -0
  19. package/dist/components/steps/KYCVerification.d.ts +11 -0
  20. package/dist/components/steps/KYCVerification.js +867 -0
  21. package/dist/components/steps/OnboardingComplete.d.ts +8 -0
  22. package/dist/components/steps/OnboardingComplete.js +566 -0
  23. package/dist/components/steps/onboarding/FinalStepScreen.d.ts +10 -0
  24. package/dist/components/steps/onboarding/FinalStepScreen.js +455 -0
  25. package/dist/components/steps/onboarding/MerchantOnboarding.d.ts +4 -0
  26. package/dist/components/steps/onboarding/MerchantOnboarding.js +678 -0
  27. package/dist/contexts/AirXPayProvider.d.ts +21 -0
  28. package/dist/contexts/AirXPayProvider.js +116 -0
  29. package/dist/error/errorHandler.d.ts +10 -0
  30. package/dist/error/errorHandler.js +87 -0
  31. package/dist/etc/constants.d.ts +37 -0
  32. package/dist/etc/constants.js +41 -0
  33. package/dist/hooks/useAirXPaySheet.d.ts +3 -0
  34. package/dist/hooks/useAirXPaySheet.js +20 -0
  35. package/dist/hooks/useMerchantOnboarding.d.ts +15 -0
  36. package/dist/hooks/useMerchantOnboarding.js +108 -0
  37. package/dist/index.d.ts +13 -0
  38. package/dist/index.js +41 -0
  39. package/dist/options/configOptions.d.ts +28 -0
  40. package/dist/options/configOptions.js +56 -0
  41. package/dist/plugins/tokenRefreshPlugin.d.ts +10 -0
  42. package/dist/plugins/tokenRefreshPlugin.js +91 -0
  43. package/dist/schema/validators.d.ts +9 -0
  44. package/dist/schema/validators.js +57 -0
  45. package/dist/sdk/airxpay.d.ts +9 -0
  46. package/dist/sdk/airxpay.js +26 -0
  47. package/dist/services/apiService.d.ts +34 -0
  48. package/dist/services/apiService.js +133 -0
  49. package/dist/types/dev.d.ts +1 -0
  50. package/dist/types/dev.js +4 -0
  51. package/dist/types/dev.ts +2 -0
  52. package/dist/types/merchantTypes.d.ts +111 -0
  53. package/dist/types/merchantTypes.js +2 -0
  54. package/dist/types/merchantTypes.ts +116 -0
  55. package/dist/types/type.d.ts +8 -0
  56. package/dist/types/type.js +3 -0
  57. package/dist/types/type.ts +11 -0
  58. package/dist/utils/jwt.d.ts +10 -0
  59. package/dist/utils/jwt.js +28 -0
  60. package/dist/utils/tokenStorage.d.ts +5 -0
  61. package/dist/utils/tokenStorage.js +69 -0
  62. package/package.json +52 -0
package/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Tafseel Khan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,623 @@
1
+ # 🚀 @flixora/airxpay-sdk-init-ui
2
+
3
+ <div align="center">
4
+ <img src="./src/assets/images/airxpay.png" alt="AirXPay" width="120"/>
5
+ <h3>Complete Merchant Onboarding Solution for React Native</h3>
6
+ <p>Beautiful, production-ready UI components for seamless merchant onboarding</p>
7
+ </div>
8
+
9
+ ---
10
+
11
+ <p align="center">
12
+ <a href="#-typescript">
13
+ <img src="https://img.shields.io/badge/TypeScript-5.0+-blue?style=for-the-badge&logo=typescript" alt="TypeScript" />
14
+ </a>
15
+ <a href="#-react">
16
+ <img src="https://img.shields.io/badge/React-18.0+-61DAFB?style=for-the-badge&logo=react" alt="React" />
17
+ </a>
18
+ <a href="#-react-native">
19
+ <img src="https://img.shields.io/badge/React_Native-0.72+-61DAFB?style=for-the-badge&logo=react" alt="React Native" />
20
+ </a>
21
+ <a href="#-expo">
22
+ <img src="https://img.shields.io/badge/Expo-50+-000020?style=for-the-badge&logo=expo" alt="Expo" />
23
+ </a>
24
+ <a href="#-nextjs">
25
+ <img src="https://img.shields.io/badge/Next.js-14.0+-000000?style=for-the-badge&logo=next.js" alt="Next.js" />
26
+ </a>
27
+ <a href="#-javascript">
28
+ <img src="https://img.shields.io/badge/JavaScript-ES6+-F7DF1E?style=for-the-badge&logo=javascript" alt="JavaScript" />
29
+ </a>
30
+ <a href="#-typescript">
31
+ <img src="https://img.shields.io/badge/TypeScript-5.0+-3178C6?style=for-the-badge&logo=typescript" alt="TypeScript" />
32
+ </a>
33
+ <a href="#-mit-license">
34
+ <img src="https://img.shields.io/badge/License-MIT-yellow?style=for-the-badge&logo=open-source-initiative" alt="MIT License" />
35
+ </a>
36
+ </p>
37
+
38
+ ---
39
+
40
+ ## 📋 Table of Contents
41
+
42
+ - [Features](#-features)
43
+ - [Installation](#-installation)
44
+ - [Quick Start](#-quick-start)
45
+ - [Architecture](#-architecture)
46
+ - [Components](#-components)
47
+ - [API Reference](#-api-reference)
48
+ - [Hooks](#-hooks)
49
+ - [Types](#-types)
50
+ - [Backend Integration](#-backend-integration)
51
+ - [Examples](#-examples)
52
+ - [FAQ](#-faq)
53
+ - [Contributing](#-contributing)
54
+ - [License](#-license)
55
+
56
+ ---
57
+
58
+ ## ✨ Features
59
+
60
+ ✅ **Complete Onboarding Flow** - 5-step merchant onboarding process
61
+ ✅ **Beautiful UI** - Gradient designs, animations, and modern components
62
+ ✅ **Form Validation** - Real-time validation with error messages
63
+ ✅ **Document Upload** - File upload with progress indicators
64
+ ✅ **KYC Verification** - PAN, Aadhaar, GST validation
65
+ ✅ **Bank Details** - IFSC validation, account number masking
66
+ ✅ **Token Management** - Automatic token refresh and storage
67
+ ✅ **Error Handling** - Comprehensive error handling with user-friendly messages
68
+ ✅ **TypeScript** - Full type safety
69
+ ✅ **Modular Architecture** - Clean separation of concerns
70
+ ✅ **Production Ready** - Battle-tested code
71
+
72
+ ---
73
+
74
+ ## 📦 Installation
75
+
76
+ ```bash
77
+ npm install @flixora/airxpay-sdk-init-ui
78
+ # or
79
+ yarn add @flixora/airxpay-sdk-init-ui
80
+ ```
81
+
82
+ ### Peer Dependencies
83
+
84
+ ```bash
85
+ npm install react react-native react-native-paper @react-native-async-storage/async-storage expo-linear-gradient @react-native-community/datetimepicker
86
+ ```
87
+
88
+ ---
89
+
90
+ ## 🚀 Quick Start
91
+
92
+ ### 1. Wrap your app with Provider
93
+
94
+ ```tsx
95
+ // App.tsx
96
+ import { AirXPayProvider } from '@flixora/airxpay-sdk-init-ui';
97
+
98
+ const App = () => {
99
+ const config = {
100
+ publicKey: 'your_public_key_here',
101
+ environment: 'test', // or 'live'
102
+ enableLogging: __DEV__,
103
+ };
104
+
105
+ return (
106
+ <AirXPayProvider config={config}>
107
+ <YourApp />
108
+ </AirXPayProvider>
109
+ );
110
+ };
111
+ ```
112
+
113
+ ### 2. Use the Onboarding Component
114
+
115
+ ```tsx
116
+ // MerchantOnboardingScreen.tsx
117
+ import React from 'react';
118
+ import { MerchantOnboarding } from '@flixora/airxpay-sdk-init-ui';
119
+
120
+ const MerchantOnboardingScreen = () => {
121
+ const handleComplete = (merchantData) => {
122
+ console.log('Onboarding complete:', merchantData);
123
+ // Navigate to next screen
124
+ };
125
+
126
+ return (
127
+ <MerchantOnboarding
128
+ mode="test"
129
+ isKycCompleted={false}
130
+ isBankDetailsCompleted={false}
131
+ kycStatus="not_submitted"
132
+ status="pending"
133
+ onNext={(data, step) => console.log('Step:', step, data)}
134
+ onBack={(step) => console.log('Back to:', step)}
135
+ onComplete={handleComplete}
136
+ />
137
+ );
138
+ };
139
+ ```
140
+
141
+ ---
142
+
143
+ ## 🏗 Architecture
144
+
145
+ ```
146
+ @flixora/airxpay-sdk-init-ui/
147
+ ├── components/
148
+ │ ├── steps/
149
+ │ │ ├── BasicDetailsForm # Step 1: Basic Info
150
+ │ │ ├── KYCVerification # Step 2: KYC Documents
151
+ │ │ ├── BankDetails # Step 3: Bank Account
152
+ │ │ └── OnboardingComplete # Step 5: Success Screen
153
+ │ └── onboarding/
154
+ │ ├── FinalStepScreen # Step 4: Review & Submit
155
+ │ └── MerchantOnboarding # Main Container (5 steps)
156
+ ├── contexts/
157
+ │ └── AirXPayProvider # Global Context
158
+ ├── hooks/
159
+ │ └── useMerchantOnboarding # Custom Hook
160
+ ├── api/
161
+ │ ├── merchantProxy # API Proxy Functions
162
+ │ └── client # HTTP Client
163
+ ├── utils/
164
+ │ ├── tokenStorage # Token Management
165
+ │ └── jwt # JWT Utilities
166
+ ├── types/
167
+ │ └── merchantTypes # TypeScript Types
168
+ └── etc/
169
+ └── constants # App Constants
170
+ ```
171
+
172
+ ---
173
+
174
+ ## 🎨 Components
175
+
176
+ ### MerchantOnboarding (5-Step Flow)
177
+
178
+ The main container component that manages the entire onboarding flow.
179
+
180
+ ```tsx
181
+ <MerchantOnboarding
182
+ mode="test" // 'test' | 'live'
183
+ isKycCompleted={false} // Initial KYC status
184
+ isBankDetailsCompleted={false} // Initial bank status
185
+ kycStatus="not_submitted" // 'not_submitted' | 'pending' | 'verified' | 'rejected'
186
+ status="pending" // 'pending' | 'active' | 'suspended' | 'blocked'
187
+ onNext={(data, step) => {}} // Step completion callback
188
+ onBack={(step) => {}} // Back navigation callback
189
+ onComplete={(merchant) => {}} // Final completion callback
190
+ />
191
+ ```
192
+
193
+ #### Steps Overview
194
+
195
+ | Step | Name | Description |
196
+ |------|------|-------------|
197
+ | 1 | Basic Details | Name, email, phone, business type |
198
+ | 2 | KYC Verification | PAN, Aadhaar, document upload |
199
+ | 3 | Bank Details | Account number, IFSC, cancelled cheque |
200
+ | 4 | Final Review | Review & submit to backend |
201
+ | 5 | Complete | Success screen with merchant status |
202
+
203
+ ---
204
+
205
+ ### BasicDetailsForm
206
+
207
+ Collects basic merchant information.
208
+
209
+ **Props:**
210
+ ```tsx
211
+ interface BasicDetailsFormProps {
212
+ initialData: Partial<Merchant>;
213
+ onNext: (data: Partial<Merchant>) => void;
214
+ errors: FormErrors;
215
+ setErrors: (errors: FormErrors) => void;
216
+ }
217
+ ```
218
+
219
+ **Features:**
220
+ - ✅ Real-time validation
221
+ - ✅ Business type toggle (Individual/Company)
222
+ - ✅ Country dropdown
223
+ - ✅ Date of birth picker
224
+ - ✅ Category selection chips
225
+
226
+ ---
227
+
228
+ ### KYCVerification
229
+
230
+ Handles KYC document collection and verification.
231
+
232
+ **Props:**
233
+ ```tsx
234
+ interface KYCVerificationProps {
235
+ initialData: Partial<Merchant>;
236
+ mode: Mode;
237
+ kycStatus: KycStatus;
238
+ onNext: (data: Partial<Merchant>) => void;
239
+ onBack: () => void;
240
+ }
241
+ ```
242
+
243
+ **Documents Collected:**
244
+ - 📄 PAN Card
245
+ - 🆔 Aadhaar Card
246
+ - 📸 Selfie
247
+ - 🏠 Address Proof
248
+
249
+ **Features:**
250
+ - ✅ Document type validation
251
+ - ✅ Upload progress indicator
252
+ - ✅ Status badges
253
+ - ✅ Progress tracking
254
+
255
+ ---
256
+
257
+ ### BankDetails
258
+
259
+ Collects bank account information.
260
+
261
+ **Props:**
262
+ ```tsx
263
+ interface BankDetailsProps {
264
+ initialData: Partial<Merchant>;
265
+ mode: Mode;
266
+ onNext: (data: Partial<Merchant>) => void;
267
+ onBack: () => void;
268
+ }
269
+ ```
270
+
271
+ **Fields:**
272
+ - 👤 Account Holder Name
273
+ - 🏦 Bank Name
274
+ - 💳 Account Number (masked)
275
+ - 🔢 IFSC Code (with validation)
276
+ - 📱 UPI ID (optional)
277
+ - 📄 Cancelled Cheque Upload
278
+
279
+ **Features:**
280
+ - ✅ IFSC code validation
281
+ - ✅ Account number masking
282
+ - ✅ Real-time validation
283
+ - ✅ Test mode notice
284
+
285
+ ---
286
+
287
+ ### FinalStepScreen
288
+
289
+ Review and submit final merchant data.
290
+
291
+ **Props:**
292
+ ```tsx
293
+ interface FinalStepScreenProps {
294
+ publicKey: string;
295
+ onSuccess: (response: any) => void;
296
+ onError?: (error: any) => void;
297
+ initialData?: Partial<CreateMerchantPayload>;
298
+ }
299
+ ```
300
+
301
+ **Features:**
302
+ - ✅ Review all entered information
303
+ - ✅ Terms agreement checkbox
304
+ - ✅ Loading state during submission
305
+ - ✅ Error handling with alerts
306
+
307
+ ---
308
+
309
+ ### OnboardingCompleteScreen
310
+
311
+ Displays merchant status after successful creation.
312
+
313
+ **Props:**
314
+ ```tsx
315
+ interface OnboardingCompleteScreenProps {
316
+ onContinue?: () => void;
317
+ onLogout?: () => void;
318
+ autoFetch?: boolean;
319
+ }
320
+ ```
321
+
322
+ **Features:**
323
+ - ✅ Auto-fetch merchant status
324
+ - ✅ Status badges (Active/Suspended/Blocked)
325
+ - ✅ KYC status display
326
+ - ✅ Refresh button
327
+ - ✅ Continue & Logout buttons
328
+
329
+ ---
330
+
331
+ ## 🪝 Hooks
332
+
333
+ ### useMerchantOnboarding
334
+
335
+ ```tsx
336
+ const {
337
+ loading, // boolean - API call in progress
338
+ error, // AppError | null
339
+ merchantData, // MerchantCreateResponse | null
340
+ merchantStatus, // MerchantStatusResponse | null
341
+ initialize, // (publicKey: string) => void
342
+ createMerchant, // (payload) => Promise
343
+ fetchStatus, // () => Promise
344
+ clearError, // () => void
345
+ reset // () => void
346
+ } = useMerchantOnboarding();
347
+ ```
348
+
349
+ ### useAirXPay
350
+
351
+ ```tsx
352
+ const {
353
+ publicKey,
354
+ isValid,
355
+ loading,
356
+ merchantData,
357
+ hasToken,
358
+ merchantId,
359
+ logout
360
+ } = useAirXPay();
361
+ ```
362
+
363
+ ### useAirXPaySafe
364
+
365
+ Safe version that returns `null` instead of throwing error.
366
+
367
+ ### useProviderReady
368
+
369
+ Returns `boolean` indicating if provider is ready.
370
+
371
+ ---
372
+
373
+ ## 📚 API Reference
374
+
375
+ ### merchantProxy.ts
376
+
377
+ | Function | Description |
378
+ |----------|-------------|
379
+ | `initializeInternalApi(publicKey)` | Initialize SDK with public key |
380
+ | `createMerchantInternal(payload)` | Create merchant via backend proxy |
381
+ | `getMerchantStatusInternal()` | Fetch merchant status |
382
+ | `refreshMerchantTokenInternal()` | Refresh auth token |
383
+ | `verifyPublicKey(publicKey)` | Verify public key validity |
384
+
385
+ ### tokenStorage.ts
386
+
387
+ | Function | Description |
388
+ |----------|-------------|
389
+ | `getStoredToken()` | Get stored token |
390
+ | `setStoredToken(token)` | Store token |
391
+ | `clearStoredToken()` | Clear stored token |
392
+ | `storeMerchantData(data)` | Cache merchant data |
393
+ | `getStoredMerchantData()` | Get cached merchant data |
394
+
395
+ ### jwt.ts
396
+
397
+ | Function | Description |
398
+ |----------|-------------|
399
+ | `decodeJWT(token)` | Decode JWT payload |
400
+ | `getMerchantIdFromToken(token)` | Extract merchant ID |
401
+ | `isTokenExpired(token)` | Check token expiry |
402
+
403
+ ---
404
+
405
+ ## 📝 Types
406
+
407
+ ```tsx
408
+ type BusinessType = 'individual' | 'company';
409
+ type Mode = 'test' | 'live';
410
+ type MerchantStatus = 'active' | 'suspended' | 'blocked' | 'pending';
411
+ type KycStatus = 'not_submitted' | 'pending' | 'verified' | 'rejected';
412
+
413
+ interface Merchant {
414
+ merchantId: string;
415
+ merchantName: string;
416
+ merchantEmail: string;
417
+ merchantPhone?: string;
418
+ businessName?: string;
419
+ businessType?: BusinessType;
420
+ kycStatus: KycStatus;
421
+ status: MerchantStatus;
422
+ mode: Mode;
423
+ // ... more fields
424
+ }
425
+
426
+ interface CreateMerchantPayload {
427
+ merchantName: string;
428
+ merchantEmail: string;
429
+ merchantPhone?: string;
430
+ businessName?: string;
431
+ businessType?: BusinessType;
432
+ mode?: Mode;
433
+ // ... more fields
434
+ }
435
+ ```
436
+
437
+ ---
438
+
439
+ ## 🔧 Backend Integration
440
+
441
+ ### Required Backend Endpoints
442
+
443
+ ```tsx
444
+ // Your backend must implement these endpoints:
445
+ POST /api/merchant/create // Create merchant (uses secret key)
446
+ GET /api/merchant/status // Get merchant status
447
+ POST /api/merchant/refresh-token // Refresh token
448
+ POST /api/merchant/verify-public-key // Verify public key
449
+ ```
450
+
451
+ ### Backend Example (Node.js/Express)
452
+
453
+ ```tsx
454
+ // backend/routes/merchant.ts
455
+ import { initializeInternalApi, createMerchantInternal } from '@airxpay/internal-sdk';
456
+
457
+ // Initialize with SECRET KEY (server-side only!)
458
+ initializeInternalApi(process.env.AIRXPAY_SECRET_KEY);
459
+
460
+ router.post('/create', async (req, res) => {
461
+ try {
462
+ const { publicKey, ...payload } = req.body;
463
+
464
+ // Validate public key
465
+ if (!publicKey) {
466
+ return res.status(400).json({ error: 'Public key required' });
467
+ }
468
+
469
+ // Create merchant using secret key
470
+ const result = await createMerchantInternal(payload);
471
+
472
+ res.json(result);
473
+ } catch (error) {
474
+ res.status(500).json({ error: error.message });
475
+ }
476
+ });
477
+ ```
478
+
479
+ ---
480
+
481
+ ## 💡 Examples
482
+
483
+ ### Complete Implementation
484
+
485
+ ```tsx
486
+ // App.tsx
487
+ import React, { useState } from 'react';
488
+ import { SafeAreaView } from 'react-native';
489
+ import {
490
+ AirXPayProvider,
491
+ MerchantOnboarding,
492
+ OnboardingCompleteScreen
493
+ } from '@flixora/airxpay-sdk-init-ui';
494
+
495
+ export default function App() {
496
+ const [step, setStep] = useState<'onboarding' | 'complete'>('onboarding');
497
+ const [merchantData, setMerchantData] = useState(null);
498
+
499
+ const config = {
500
+ publicKey: 'pk_test_your_public_key',
501
+ environment: 'test',
502
+ };
503
+
504
+ const handleComplete = (data) => {
505
+ setMerchantData(data);
506
+ setStep('complete');
507
+ };
508
+
509
+ return (
510
+ <AirXPayProvider config={config}>
511
+ <SafeAreaView style={{ flex: 1 }}>
512
+ {step === 'onboarding' ? (
513
+ <MerchantOnboarding
514
+ mode="test"
515
+ isKycCompleted={false}
516
+ isBankDetailsCompleted={false}
517
+ kycStatus="not_submitted"
518
+ status="pending"
519
+ onNext={(data, step) => console.log('Step:', step)}
520
+ onBack={(step) => console.log('Back:', step)}
521
+ onComplete={handleComplete}
522
+ />
523
+ ) : (
524
+ <OnboardingCompleteScreen
525
+ onContinue={() => console.log('Navigate to dashboard')}
526
+ onLogout={() => {
527
+ setStep('onboarding');
528
+ setMerchantData(null);
529
+ }}
530
+ />
531
+ )}
532
+ </SafeAreaView>
533
+ </AirXPayProvider>
534
+ );
535
+ }
536
+ ```
537
+
538
+ ### Custom Navigation
539
+
540
+ ```tsx
541
+ const config = {
542
+ publicKey: 'pk_test_...',
543
+ customNavigation: {
544
+ buttonText: 'Go to Dashboard',
545
+ screenName: 'Dashboard'
546
+ }
547
+ };
548
+ ```
549
+
550
+ ---
551
+
552
+ ## ❓ FAQ
553
+
554
+ ### Q: Public key vs Secret key - where to use?
555
+
556
+ **A:**
557
+ - **Public Key** - Used on frontend (in `AirXPayProvider`)
558
+ - **Secret Key** - Used on backend only (never expose to frontend)
559
+
560
+ ### Q: How does token refresh work?
561
+
562
+ **A:** The SDK automatically:
563
+ 1. Checks token expiry before each request
564
+ 2. Queues requests during token refresh
565
+ 3. Retries failed requests with new token
566
+ 4. Logs out user if refresh fails
567
+
568
+ ### Q: Can I customize the UI?
569
+
570
+ **A:** Yes! All components accept custom styles via `style` props. You can also override colors by modifying the theme in `react-native-paper`.
571
+
572
+ ### Q: How do I handle errors?
573
+
574
+ **A:** The SDK provides comprehensive error handling:
575
+ ```tsx
576
+ try {
577
+ await createMerchant(payload);
578
+ } catch (error) {
579
+ // error.userMessage - User-friendly message
580
+ // error.message - Technical message
581
+ // error.code - Error code
582
+ Alert.alert('Error', error.userMessage);
583
+ }
584
+ ```
585
+
586
+ ### Q: Is Expo supported?
587
+
588
+ **A:** Yes! Fully compatible with Expo SDK 50+. Uses `expo-linear-gradient` and `@react-native-community/datetimepicker` which are Expo-compatible.
589
+
590
+ ---
591
+
592
+ ## 🤝 Contributing
593
+
594
+ We welcome contributions! Please follow these steps:
595
+
596
+ 1. Fork the repository
597
+ 2. Create your feature branch (`git checkout -b feature/amazing-feature`)
598
+ 3. Commit your changes (`git commit -m 'Add amazing feature'`)
599
+ 4. Push to the branch (`git push origin feature/amazing-feature`)
600
+ 5. Open a Pull Request
601
+
602
+ ### Development Setup
603
+
604
+ ```bash
605
+ git clone https://github.com/airxpay/sdk-init-ui.git
606
+ cd sdk-init-ui
607
+ npm install
608
+ npm run storybook # Run component library
609
+ ```
610
+
611
+ ---
612
+
613
+ ## 📄 License
614
+
615
+ MIT © [AirXPay](https://airxpay.com)
616
+
617
+ ---
618
+
619
+ <div align="center">
620
+ <sub>Built with ❤️ by the AirXPay Team</sub>
621
+ <br/>
622
+ <sub>© 2026 AirXPay. All rights reserved.</sub>
623
+ </div>
@@ -0,0 +1,2 @@
1
+ import { AxiosInstance } from 'axios';
2
+ export declare const createApiClient: (baseURL: string) => AxiosInstance;