@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.
- package/LICENSE.md +21 -0
- package/README.md +623 -0
- package/dist/api/client.d.ts +2 -0
- package/dist/api/client.js +78 -0
- package/dist/api/merchantProxy.d.ts +11 -0
- package/dist/api/merchantProxy.js +170 -0
- package/dist/assets/images/airxpay.png +0 -0
- package/dist/assets/images/flixora.png +0 -0
- package/dist/components/common/CountryDropdown.d.ts +17 -0
- package/dist/components/common/CountryDropdown.js +138 -0
- package/dist/components/common/FileUploader.d.ts +16 -0
- package/dist/components/common/FileUploader.js +219 -0
- package/dist/components/common/StepIndicator.d.ts +11 -0
- package/dist/components/common/StepIndicator.js +269 -0
- package/dist/components/steps/BankDetails.d.ts +10 -0
- package/dist/components/steps/BankDetails.js +630 -0
- package/dist/components/steps/BasicDetailsForm.d.ts +10 -0
- package/dist/components/steps/BasicDetailsForm.js +569 -0
- package/dist/components/steps/KYCVerification.d.ts +11 -0
- package/dist/components/steps/KYCVerification.js +867 -0
- package/dist/components/steps/OnboardingComplete.d.ts +8 -0
- package/dist/components/steps/OnboardingComplete.js +566 -0
- package/dist/components/steps/onboarding/FinalStepScreen.d.ts +10 -0
- package/dist/components/steps/onboarding/FinalStepScreen.js +455 -0
- package/dist/components/steps/onboarding/MerchantOnboarding.d.ts +4 -0
- package/dist/components/steps/onboarding/MerchantOnboarding.js +678 -0
- package/dist/contexts/AirXPayProvider.d.ts +21 -0
- package/dist/contexts/AirXPayProvider.js +116 -0
- package/dist/error/errorHandler.d.ts +10 -0
- package/dist/error/errorHandler.js +87 -0
- package/dist/etc/constants.d.ts +37 -0
- package/dist/etc/constants.js +41 -0
- package/dist/hooks/useAirXPaySheet.d.ts +3 -0
- package/dist/hooks/useAirXPaySheet.js +20 -0
- package/dist/hooks/useMerchantOnboarding.d.ts +15 -0
- package/dist/hooks/useMerchantOnboarding.js +108 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.js +41 -0
- package/dist/options/configOptions.d.ts +28 -0
- package/dist/options/configOptions.js +56 -0
- package/dist/plugins/tokenRefreshPlugin.d.ts +10 -0
- package/dist/plugins/tokenRefreshPlugin.js +91 -0
- package/dist/schema/validators.d.ts +9 -0
- package/dist/schema/validators.js +57 -0
- package/dist/sdk/airxpay.d.ts +9 -0
- package/dist/sdk/airxpay.js +26 -0
- package/dist/services/apiService.d.ts +34 -0
- package/dist/services/apiService.js +133 -0
- package/dist/types/dev.d.ts +1 -0
- package/dist/types/dev.js +4 -0
- package/dist/types/dev.ts +2 -0
- package/dist/types/merchantTypes.d.ts +111 -0
- package/dist/types/merchantTypes.js +2 -0
- package/dist/types/merchantTypes.ts +116 -0
- package/dist/types/type.d.ts +8 -0
- package/dist/types/type.js +3 -0
- package/dist/types/type.ts +11 -0
- package/dist/utils/jwt.d.ts +10 -0
- package/dist/utils/jwt.js +28 -0
- package/dist/utils/tokenStorage.d.ts +5 -0
- package/dist/utils/tokenStorage.js +69 -0
- 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>
|