react-native-fpay 0.4.20 → 0.4.22

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/lib/module/FountainPayProvider.js +55 -128
  2. package/lib/module/FountainPayProvider.js.map +1 -1
  3. package/lib/module/core/api/client.js +1 -1
  4. package/lib/module/core/api/index.js +16 -13
  5. package/lib/module/core/api/index.js.map +1 -1
  6. package/lib/module/core/types/index.js +1 -1
  7. package/lib/module/core/types/index.js.map +1 -1
  8. package/lib/module/engine/FPEngine.js +27 -17
  9. package/lib/module/engine/FPEngine.js.map +1 -1
  10. package/lib/module/store/FPStore.js +11 -4
  11. package/lib/module/store/FPStore.js.map +1 -1
  12. package/lib/module/ui/components/ConfirmScreen.js +2 -2
  13. package/lib/module/ui/components/ConfirmScreen.js.map +1 -1
  14. package/lib/module/ui/modals/FPCreatePin.js +234 -0
  15. package/lib/module/ui/modals/FPCreatePin.js.map +1 -0
  16. package/lib/module/ui/modals/FPShell.js +7 -3
  17. package/lib/module/ui/modals/FPShell.js.map +1 -1
  18. package/lib/module/ui/modals/FPValidateBvn.js +258 -0
  19. package/lib/module/ui/modals/FPValidateBvn.js.map +1 -0
  20. package/lib/module/ui/screens/ResultScreen.js +4 -17
  21. package/lib/module/ui/screens/ResultScreen.js.map +1 -1
  22. package/lib/module/ui/screens/SendScreen.js +24 -9
  23. package/lib/module/ui/screens/SendScreen.js.map +1 -1
  24. package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js +3 -3
  25. package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js.map +1 -1
  26. package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js +8 -1
  27. package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js.map +1 -1
  28. package/lib/typescript/src/FountainPayProvider.d.ts +3 -4
  29. package/lib/typescript/src/FountainPayProvider.d.ts.map +1 -1
  30. package/lib/typescript/src/core/api/index.d.ts +20 -21
  31. package/lib/typescript/src/core/api/index.d.ts.map +1 -1
  32. package/lib/typescript/src/core/types/index.d.ts +16 -6
  33. package/lib/typescript/src/core/types/index.d.ts.map +1 -1
  34. package/lib/typescript/src/engine/FPEngine.d.ts +3 -0
  35. package/lib/typescript/src/engine/FPEngine.d.ts.map +1 -1
  36. package/lib/typescript/src/store/FPStore.d.ts +8 -5
  37. package/lib/typescript/src/store/FPStore.d.ts.map +1 -1
  38. package/lib/typescript/src/ui/components/ConfirmScreen.d.ts +1 -2
  39. package/lib/typescript/src/ui/components/ConfirmScreen.d.ts.map +1 -1
  40. package/lib/typescript/src/ui/modals/FPCreatePin.d.ts +3 -0
  41. package/lib/typescript/src/ui/modals/FPCreatePin.d.ts.map +1 -0
  42. package/lib/typescript/src/ui/modals/FPShell.d.ts.map +1 -1
  43. package/lib/typescript/src/ui/modals/FPValidateBvn.d.ts +3 -0
  44. package/lib/typescript/src/ui/modals/FPValidateBvn.d.ts.map +1 -0
  45. package/lib/typescript/src/ui/screens/ResultScreen.d.ts.map +1 -1
  46. package/lib/typescript/src/ui/screens/SendScreen.d.ts.map +1 -1
  47. package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts.map +1 -1
  48. package/package.json +1 -1
  49. package/src/FountainPayProvider.tsx +63 -151
  50. package/src/core/api/client.ts +1 -1
  51. package/src/core/api/index.ts +54 -54
  52. package/src/core/types/index.ts +18 -5
  53. package/src/engine/FPEngine.ts +33 -20
  54. package/src/store/FPStore.ts +15 -8
  55. package/src/ui/components/ConfirmScreen.tsx +4 -3
  56. package/src/ui/modals/FPCreatePin.tsx +206 -0
  57. package/src/ui/modals/FPShell.tsx +16 -2
  58. package/src/ui/modals/FPValidateBvn.tsx +229 -0
  59. package/src/ui/screens/ResultScreen.tsx +6 -10
  60. package/src/ui/screens/SendScreen.tsx +60 -36
  61. package/src/ui/screens/sub/sendPayment/ProximitySubScreen.tsx +3 -3
  62. package/src/ui/screens/sub/sendPayment/TransferSubScreen.tsx +7 -1
@@ -6,7 +6,7 @@
6
6
  // the SAME instance — no re-initialization, no prop drilling.
7
7
  //
8
8
  // Usage:
9
- // <FountainPayProvider apiKey="fp_live_...">
9
+ // <FountainPayProvider appId="...">
10
10
  // <YourApp />
11
11
  // </FountainPayProvider>
12
12
  // ─────────────────────────────────────────────────────────────────────────────
@@ -32,7 +32,7 @@ import type {
32
32
  FPAccount,
33
33
  FPBalance,
34
34
  } from './core/types';
35
- import { authenticateAPI, transferAPI } from './core/api';
35
+ import { accountAPI, authenticateAPI, transferAPI } from './core/api';
36
36
 
37
37
  // ── Context ───────────────────────────────────────────────────────────────────
38
38
 
@@ -54,26 +54,23 @@ export function useFountainPay(): FPInstance {
54
54
  if (!instance) {
55
55
  throw new Error(
56
56
  '[FountainPay] useFountainPay() must be called inside <FountainPayProvider>.\n' +
57
- 'Make sure you have wrapped your app root with <FountainPayProvider apiKey="...">.'
57
+ 'Make sure you have wrapped your app root with <FountainPayProvider appId="...">.'
58
58
  );
59
59
  }
60
60
  return instance;
61
61
  }
62
-
63
62
  // ── Provider ──────────────────────────────────────────────────────────────────
64
63
 
65
64
  interface ProviderProps {
66
- apiKey?: string;
67
- accessToken?: string;
65
+ appId: string;
68
66
  options?: FPSDKOptions;
69
67
  children: ReactNode;
70
- onAuthReady?: () => void;
68
+ onAuthReady?: (account?: any) => void;
71
69
  onAuthError?: (error: string) => void;
72
70
  }
73
71
 
74
72
  export function FountainPayProvider({
75
- apiKey,
76
- accessToken,
73
+ appId,
77
74
  options,
78
75
  children,
79
76
  onAuthReady,
@@ -89,9 +86,8 @@ export function FountainPayProvider({
89
86
  const account = useFPStore((s) => s.account);
90
87
  const user = useFPStore((s) => s.user);
91
88
  const balance = useFPStore((s) => s.balance);
92
- // const resetToken = useFPStore((s) => s.clearAccessToken);
93
- // const clearUser = useFPStore((s) => s.clearUser);
94
-
89
+ const resetToken = useFPStore((s) => s.clearAccessToken);
90
+ const clearUser = useFPStore((s) => s.clearUser);
95
91
 
96
92
 
97
93
  useEffect(() => {
@@ -100,11 +96,8 @@ export function FountainPayProvider({
100
96
  // Make sure client is initialized before any API call
101
97
  console.log('[FountainPay] Provider mounted. HTTP client ready.', options);
102
98
  if (!clientBooted.current) {
103
- if (options?.userType === 'AGENT' && accessToken) {
104
- getFPStore().setAccessToken(accessToken);
105
- }
106
- if (apiKey) {
107
- getFPStore().setApiKey(apiKey); // ← store it
99
+ if (appId) {
100
+ getFPStore().setAppId(appId); // ← store it
108
101
  }
109
102
 
110
103
  initClient({
@@ -118,109 +111,59 @@ export function FountainPayProvider({
118
111
  const authenticate = async () => {
119
112
  // await resetToken();
120
113
  // await clearUser();
121
- const userType = options?.userType ?? 'USER';
122
-
123
- // ── AGENT mode ────────────────────────────────────────
124
- if (userType === 'AGENT') {
125
- if (!accessToken) {
126
- onAuthError?.('accessToken is required for AGENT mode');
127
- return;
128
- }
129
-
130
- try {
131
- console.log('[FountainPay] Agent mode — validating token...');
132
-
133
- // Store the token first so the HTTP interceptor picks it up
134
- getFPStore().setAccessToken(accessToken);
135
-
136
- // Fetch agent profile from backend
137
- const response = await authenticateAPI.validateToken();
138
- if (cancelled) return;
139
-
140
- if (response.status) {
141
- const agent = response.payload;
142
-
143
- // Build FPUserInfo from agent model
144
- const user: FPUserInfo = {
145
- firstName: agent.firstName,
146
- lastName: agent.lastName,
147
- email: agent.email,
148
- phone: agent.phone ?? '',
149
- bvn: agent.bvn,
150
- userId: agent.id,
151
- };
152
-
153
- // Build FPAccount from agent model
154
- const account: FPAccount = {
155
- id: agent.id,
156
- firstName: agent.firstName,
157
- lastName: agent.lastName,
158
- phone: agent.phone,
159
- accountName: `${agent.firstName} ${agent.lastName}`.toUpperCase(),
160
- accountNumber: agent.accountNumber,
161
- bankName: agent.bankName,
162
- bankCode: agent.bankCode, // populate if backend returns it
163
- };
164
-
165
- // Store everything — no need to call _resolveAccount
166
- getFPStore().setUser(user);
167
- getFPStore().setPsspId(agent.id);
168
- getFPStore().setAccount(account);
169
-
170
- await getFPStore().setAccessToken(accessToken, 86400);
171
-
172
- const banks: any = await transferAPI.getBanks();
173
- if (banks.status) {
174
- getFPStore().setBanks(banks.payload);
175
- console.log('[FountainPay] Banks cached:', banks.payload.length);
176
- }
177
-
178
- setAuthenticated(true);
179
- console.log('[FountainPay] Agent validated:', agent.firstName, agent.lastName);
180
-
181
- onAuthReady?.();
182
- } else {
183
- getFPStore().clearAccessToken();
184
- setAuthenticated(false, response.message);
185
- onAuthError?.(response.message);
186
- }
187
- } catch (err: any) {
188
- if (cancelled) return;
189
- getFPStore().clearAccessToken();
190
- setAuthenticated(false, err.message);
191
- onAuthError?.(err.message);
192
- }
193
-
194
- return; // ← don't fall through to PSSP auth
195
- }
196
-
197
- if (isTokenValid()) {
198
- console.log('[FountainPay] Valid token found — skipping auth.');
199
- setAuthenticated(true);
200
- onAuthReady?.();
114
+ if (!appId) {
115
+ console.log('[FountainPay] No appId — new user flow. Waiting for initializeSDK.');
116
+ // Boot client without token — initializeSDK will handle everything
117
+ setAuthenticated(false);
118
+ onAuthReady?.(null);
201
119
  return;
202
120
  }
203
121
 
204
122
  try {
205
123
  console.log('[FountainPay] Verifying API key...');
206
- const response = await authenticateAPI.login(apiKey || "");
124
+ const response = await authenticateAPI.login(appId);
207
125
  if (cancelled) return;
208
126
 
209
127
  if (response.status) {
210
128
  console.log('[FountainPay] Auth successful.');
211
- if (response.payload?.access_token) {
212
- getFPStore().setAccessToken(
213
- response.payload.access_token,
214
- response.payload.expires_in
215
- );
129
+ const { access_token, expires_in } = response.payload;
216
130
 
217
- const banks: any = await transferAPI.getBanks();
218
- if (banks.status) {
219
- getFPStore().setBanks(banks.payload);
220
- }
131
+ // Store token
132
+ getFPStore().setAccessToken(access_token, expires_in ?? 86400);
133
+
134
+ const agentDetails = await authenticateAPI.profile();
135
+ if (agentDetails.status) {
136
+
221
137
  }
138
+
139
+
140
+ // Build and store user
141
+ const user: any = agentDetails;
142
+ getFPStore().setUser(user);
143
+ getFPStore().setPsspId(agentDetails.uuid);
144
+
145
+ const agentAccount: any = await accountAPI.getAccount();
146
+ // Build and store account
147
+ const account: FPAccount = {
148
+ id: agentAccount.uuid,
149
+ ownerId: agentAccount.ownerId,
150
+ ownerType: agentAccount.ownerType,
151
+ accountName: agentAccount.accountName,
152
+ accountNumber: agentAccount.accountNumber,
153
+ bankName: agentAccount.bankName,
154
+ bankCode: agentAccount.bankCode,
155
+ currency: agentAccount.currency
156
+ };
157
+ getFPStore().setAccount(account);
158
+
159
+ try {
160
+ const banks: any = await transferAPI.getBanks();
161
+ if (banks.status) getFPStore().setBanks(banks.payload);
162
+ } catch { /* non-fatal */ }
163
+
164
+
222
165
  setAuthenticated(true);
223
- onAuthReady?.();
166
+ onAuthReady?.(account);
224
167
  } else {
225
168
  console.error('[FountainPay] Auth failed:', response.message);
226
169
  setAuthenticated(false, response.message);
@@ -234,64 +177,33 @@ export function FountainPayProvider({
234
177
  }
235
178
  };
236
179
 
237
- console.log('Calling authentication');
180
+ console.log('Calling authentication with appId:', appId);
238
181
  authenticate();
239
182
  return () => {
240
183
  cancelled = true;
241
184
  };
242
- }, [apiKey, accessToken]);
185
+ }, [appId]);
243
186
 
244
- useEffect(() => {
245
- if (options?.userType !== 'AGENT') return;
246
- if (!isAuthenticated) return;
247
-
248
- const autoInitialize = async () => {
249
- const store = getFPStore();
250
- if (!store.user || !store.account) return;
251
-
252
- console.log('[FountainPay] Agent mode — auto-initializing from stored data...');
253
- await FPEngine.initialize(
254
- store.user,
255
- options ?? {},
256
- {} // empty callbacks — host app sets these via initializeSDK if they want
257
- );
258
- console.log('[FountainPay] Agent auto-initialized.');
259
- };
260
187
 
261
- autoInitialize();
262
- }, [isAuthenticated, options?.userType]);
263
-
264
- // Build the instance once per provider lifetime.
265
- // All components that call useFountainPay() share this exact object.
266
188
  const instance = useMemo<FPInstance>(() => {
267
189
  console.log(
268
- '[FountainPay] Creating shared FPInstance for apiKey:',
269
- apiKey?.toString().slice(0, 8) + '...'
190
+ '[FountainPay] Creating shared FPInstance for appId:',
191
+ appId?.toString().slice(0, 8) + '...'
270
192
  );
271
193
 
272
194
  return {
273
- /**
274
- * Call once after the user logs in.
275
- * Starts BLE advertising, proximity broadcast, and the payment listener.
276
- */
195
+
277
196
  async initializeSDK(
278
- user: FPUserInfo,
197
+ userObj: FPUserInfo | null,
279
198
  callbacks?: FPCallbacks
280
199
  ): Promise<void> {
281
- console.log(
282
- '[FountainPay] initializeSDK() called for user:',
283
- user.firstName
284
- );
200
+ console.log( '[FountainPay] initializeSDK() called for user:', user?.firstName);
285
201
 
286
- if (options?.userType === 'AGENT') {
287
- if (callbacks) {
288
- FPEngine.updateCallbacks(callbacks); // just register callbacks
289
- }
290
- console.log('[FountainPay] Agent already initialized — callbacks updated.');
291
- return;
292
- }
202
+
293
203
  try {
294
-
204
+ if(!userObj){
205
+ userObj = user;
206
+ }
295
207
  await FPEngine.initialize(user, options ?? {}, {
296
208
  ...callbacks,
297
209
  onPaymentSent: async (tx) => {
@@ -390,7 +302,7 @@ export function FountainPayProvider({
390
302
  return balance;
391
303
  },
392
304
  };
393
- }, [apiKey, isAuthenticated, authError, account, user, balance]);
305
+ }, [appId, isAuthenticated, authError, account, user, balance]);
394
306
 
395
307
  return (
396
308
  <FountainPayContext.Provider value={instance}>
@@ -7,7 +7,7 @@ import type { FPError } from '../types';
7
7
  import { getFPStore } from '../../store/FPStore';
8
8
 
9
9
  const DEFAULT_BASE_URL =
10
- 'https://kenisha-happiest-nan.ngrok-free.dev/modal/sdk/v1/fpip/';
10
+ 'https://kenisha-happiest-nan.ngrok-free.dev/modal/sdk/v1/fpay/';
11
11
 
12
12
  let _client: AxiosInstance | null = null;
13
13
  let _isRefreshing = false;
@@ -1,17 +1,19 @@
1
1
  // FountainPay SDK — All API calls
2
2
  import { http } from './client';
3
- import type {
4
- FPBankItem,
5
- FPTransaction,
6
- FPNQRData,
7
- FPTxStatus,
8
- FPProximityPeer,
9
- FPSendPaymentRequest,
10
- FPUserInfo,
11
- FPAccount,
12
- FPSendWalletPaymentRequest,
13
- FPTransactionResponse,
14
- FPBalance,
3
+ import {
4
+ type FPBankItem,
5
+ type FPTransaction,
6
+ type FPNQRData,
7
+ type FPTxStatus,
8
+ type FPProximityPeer,
9
+ type FPSendPaymentRequest,
10
+ type FPUserInfo,
11
+ type FPAccount,
12
+ type FPSendWalletPaymentRequest,
13
+ type FPTransactionResponse,
14
+ type FPBalance,
15
+ type HttpCallResponseFormat,
16
+ BUSINESSID,
15
17
  } from '../types';
16
18
 
17
19
  export const healthAPI = {
@@ -22,15 +24,15 @@ export const healthAPI = {
22
24
  };
23
25
 
24
26
  export const authenticateAPI = {
25
- login: (apiKey: string) =>
27
+ login: (appId: string) =>
26
28
  http()
27
- .post('/auth', { api_key: apiKey })
29
+ .post('/auth', { user_id: appId })
28
30
  .then((r) => r.data),
29
31
 
30
- profile: (userId: string) =>
32
+ profile: () =>
31
33
  http()
32
- .get(`/get-user-details/${userId}`)
33
- .then((r) => r.data),
34
+ .get(`/get-user-details`)
35
+ .then((r) => r.data.payload),
34
36
 
35
37
  logout: () =>
36
38
  http()
@@ -43,28 +45,38 @@ export const authenticateAPI = {
43
45
  .then((r) => r.data),
44
46
 
45
47
  validateToken: () =>
46
- http().get<{
47
- status: boolean;
48
- message: string;
49
- payload: {
50
- id: string;
51
- firstName: string;
52
- lastName: string;
53
- email: string;
54
- phone: string;
55
- bvn?: string;
56
- accountNumber: string;
57
- bankName: string;
58
- bankCode?: string;
59
- tradeName?: string;
60
- };
61
- }>('/auth/agent/validate-token').then(r => r.data),
48
+ http().get<{response: HttpCallResponseFormat}>('/auth/agent/validate-token').then(r => r.data),
49
+
50
+ sendSmsOtp: async(payload: any)=>
51
+ http()
52
+ .post<{
53
+ status: boolean;
54
+ message: string;
55
+ payload:any
56
+ }>("shared/send-sms-otp", payload)
57
+ .then((r)=>r.data),
58
+
59
+ verifyBvn: async() =>
60
+ http()
61
+ .get<{response: HttpCallResponseFormat}>("verify-bvn")
62
+ .then((r)=>r.data),
63
+
64
+ verifySms: async(payload: any)=>
65
+ http()
66
+ .post<{response: HttpCallResponseFormat}>("verify-bvn", payload)
67
+ .then((r)=>r.data),
68
+
69
+ updateProfile: async(payload: any)=>
70
+ http()
71
+ .put<{response: HttpCallResponseFormat}>("update-user-agent", payload)
72
+ .then((r)=>r.data),
62
73
  };
63
74
 
64
75
  export const accountAPI = {
65
76
  generate: (user: FPUserInfo) =>
66
77
  http()
67
- .post<{ payload: FPAccount }>('/generate-virtual-account', {
78
+ .post<{ payload: FPAccount }>('/auth/create-agent', {
79
+ business_id: BUSINESSID,
68
80
  first_name: user.firstName,
69
81
  last_name: user.lastName,
70
82
  phone_no: user.phone,
@@ -75,29 +87,16 @@ export const accountAPI = {
75
87
  })
76
88
  .then((r) => r.data.payload),
77
89
 
78
- // Get user profile using PSSP id
79
- getUser: (psspId: string) =>
80
- http()
81
- .get<{ payload: FPAccount }>(`/get-user-details/${psspId}`)
82
- .then((r) => r.data.payload),
83
-
84
90
  // Get account details using PSSP id
85
- getAccount: (psspId: string) =>
91
+ getAccount: () =>
86
92
  http()
87
- .get<{ payload: FPAccount }>(`/get-accounts-details/${psspId}`)
93
+ .get<{ payload: FPAccount }>(`/get-accounts-details`)
88
94
  .then((r) => r.data.payload),
89
95
 
90
- getAgentBalance: (psspId: string) =>
91
- http().get<{ payload: FPBalance }>(`/get-agent-balance/${psspId}`)
96
+ getAgentBalance: () =>
97
+ http().get<{ payload: FPBalance }>(`/get-balance`)
92
98
  .then(r => r.data.payload),
93
99
 
94
- // Get balance using PSSP id
95
- getBalance: (psspId: string) =>
96
- http()
97
- .get<{ payload: FPBalance }>(
98
- `/get-balance/${psspId}`
99
- )
100
- .then((r) => r.data.payload as FPBalance),
101
100
  };
102
101
 
103
102
  export const transferAPI = {
@@ -129,15 +128,16 @@ export const transferAPI = {
129
128
  }>('/wallet-name-enquiry', { account_number: accountNumber })
130
129
  .then((r) => r.data),
131
130
 
132
- validateTransfer: (pin: string, userId: string) =>
131
+ validateTransfer: (pin: string, userId: string, receiverId: string) =>
133
132
  http()
134
133
  .post<{ status: boolean; message: string }>('/validate-transaction', {
135
134
  pin,
136
- user_id: userId,
135
+ sender_type: 'AGENT',
136
+ receiver_id: receiverId,
137
137
  })
138
138
  .then((r) => r.data),
139
139
 
140
- sendToWallet: (payload: FPSendWalletPaymentRequest, temptId: string) =>
140
+ sendToWallet: (payload: any, temptId: string) =>
141
141
  http()
142
142
  .post<{ payload: FPTransactionResponse }>('/wallet-transfer-funds', {
143
143
  ...payload,
@@ -2,6 +2,8 @@
2
2
 
3
3
  import type { Device } from 'react-native-ble-plx';
4
4
 
5
+ export const BUSINESSID = "1678aa7d-741a-4a4b-98dd-2fb406a3df3d";
6
+
5
7
  export type FPCurrency = 'NGN' | 'USD' | 'GBP' | 'EUR' | string;
6
8
  export type FPChannel = 'transfer' | 'nqr' | 'proximity' | 'bluetooth' | 'nfc';
7
9
  export type FPTxStatus =
@@ -21,6 +23,7 @@ export interface FPUserInfo {
21
23
  nin?: string;
22
24
  dateOfBirth?: string;
23
25
  userId: string;
26
+ terminalId?: string;
24
27
  }
25
28
 
26
29
  export interface FPSDKOptions {
@@ -31,10 +34,15 @@ export interface FPSDKOptions {
31
34
  userType?: 'USER' | 'AGENT';
32
35
  }
33
36
 
37
+ export interface FPInternalTransferRecipient {
38
+ id: string;
39
+ type: 'AGENT' | 'TERMINAL';
40
+ }
41
+
34
42
  export interface FPTransferRecipient {
35
43
  accountNumber: string;
36
44
  accountName: string;
37
- bankCode: string;
45
+ bankCode?: string;
38
46
  bankName: string;
39
47
  }
40
48
 
@@ -84,6 +92,7 @@ export interface FPSendPaymentRequest {
84
92
  channel: 'transfer' | 'proximity' | 'bluetooth' | 'nfc' | 'nqr';
85
93
  currency?: string;
86
94
  recipient:
95
+ | FPInternalTransferRecipient
87
96
  | FPTransferRecipient
88
97
  | FPNfcRecipient
89
98
  | FPNqrRecipient
@@ -110,6 +119,11 @@ export interface FPNfcTransfer {
110
119
  channel: 'nfc';
111
120
  }
112
121
 
122
+ export interface HttpCallResponseFormat {
123
+ status: string;
124
+ message: string;
125
+ payload: any;
126
+ }
113
127
  export interface FPTransactionResponse {
114
128
  status: string;
115
129
  message: string;
@@ -167,11 +181,10 @@ export interface FPBankItem {
167
181
 
168
182
  export interface FPAccount {
169
183
  id: string; // PSSP-assigned — stored internally, host app never needs this
184
+ ownerId: string;
185
+ ownerType: string;
170
186
  accountNumber: string;
171
187
  accountName: string;
172
- firstName: string;
173
- lastName?: string;
174
- phone: string;
175
188
  bankName?: string;
176
189
  bankCode?: string;
177
190
  balance?: FPBalance | null;
@@ -184,7 +197,7 @@ export interface FPCallbacks {
184
197
  onPaymentDeclined?: (request: FPBluetoothPaymentRequest) => void;
185
198
  onPaymentSent?: (transaction: FPTransaction) => void;
186
199
  onError?: (error: FPError) => void;
187
- onAccountReady?: (account: FPAccount) => void;
200
+ onAccountReady?: (account: any) => void;
188
201
  onAccountError?: (error: FPError, user: FPUserInfo) => void;
189
202
  }
190
203
 
@@ -11,7 +11,7 @@ import {
11
11
  import AsyncStorage from '@react-native-async-storage/async-storage';
12
12
  import Geolocation from '@react-native-community/geolocation';
13
13
  import { initClient } from '../core/api/client';
14
- import { proximityAPI, accountAPI } from '../core/api';
14
+ import { proximityAPI, accountAPI, authenticateAPI } from '../core/api';
15
15
  import type {
16
16
  FPUserInfo,
17
17
  FPSDKOptions,
@@ -124,7 +124,7 @@ async function _startProximityBroadcast(): Promise<void> {
124
124
  const session = await proximityAPI.broadcast(psspId, {
125
125
  latitude: loc.lat,
126
126
  longitude: loc.lng,
127
- user_type: 'VIRTUAL_ACCOUNT_USER',
127
+ user_type: 'AGENT',
128
128
  });
129
129
 
130
130
  // Save new position to store
@@ -161,7 +161,7 @@ async function _startProximityBroadcast(): Promise<void> {
161
161
  await proximityAPI.broadcast(psspId, {
162
162
  latitude: current.lat,
163
163
  longitude: current.lng,
164
- user_type: 'VIRTUAL_ACCOUNT_USER',
164
+ user_type: 'AGENT',
165
165
  });
166
166
  getFPStore().setLastBroadcastPosition({
167
167
  latitude: current.lat,
@@ -307,15 +307,20 @@ async function _resolveAccount(
307
307
 
308
308
  console.log('[FPay Engine] _resolveAccount callbacks:',
309
309
  'onAccountReady:', !!callbacks.onAccountReady,
310
- 'onAccountError:', !!callbacks.onAccountError
310
+ 'onAccountError:', !!callbacks.onAccountError,
311
+ 'user: ', user,
312
+ 'psspId:', psspId,
313
+ 'user.userId:', user.userId,
314
+ 'store.psspId:', store.psspId
311
315
  );
312
316
 
313
317
  try {
314
318
  if (psspId) {
315
319
  // ← use the saved value, not store.psspId
320
+
316
321
  console.log('[FPay Engine] Existing PSSP id found — fetching account...');
317
322
  try {
318
- const account = await accountAPI.getAccount(psspId);
323
+ const account = await accountAPI.getAccount();
319
324
  store.setAccount(account);
320
325
  store.setUser(user);
321
326
  console.log('[FPay Engine] Account loaded:', account);
@@ -332,7 +337,7 @@ async function _resolveAccount(
332
337
  // Create new account
333
338
  const account: any = await accountAPI.generate(user);
334
339
  console.log('[FPay Engine] Account creation response:', account);
335
- if (account) {
340
+ if (account) {
336
341
  store.setPsspId(account.id);
337
342
  store.setAccount(account);
338
343
  store.setUser(user);
@@ -356,10 +361,7 @@ async function _fetchBalance(): Promise<void> {
356
361
  }
357
362
 
358
363
  try {
359
- const userType = _options.userType ?? 'USER';
360
- const balance: FPBalance = userType === 'AGENT'
361
- ? await accountAPI.getAgentBalance(psspId)
362
- : await accountAPI.getBalance(psspId);
364
+ const balance: FPBalance = await accountAPI.getAgentBalance();
363
365
 
364
366
  getFPStore().setBalance(balance);
365
367
  console.log('[FPay Engine] Balance fetched:', balance);
@@ -437,16 +439,6 @@ export const FPEngine = {
437
439
  _isReady = true;
438
440
  console.log('[FPay Engine] Initialized. Advertising as:', displayName);
439
441
 
440
- // AGENT — account already stored by provider, skip resolve
441
- if (options.userType === 'AGENT') {
442
- const account = getFPStore().account;
443
- if (account) {
444
- callbacks.onAccountReady?.(account);
445
- _fetchBalance();
446
- }
447
- return;
448
- }
449
-
450
442
  // Resolve account first — sets psspId in store
451
443
  // Then broadcast proximity — needs psspId to be set
452
444
  await _resolveAccount(user, callbacks);
@@ -591,6 +583,27 @@ export const FPEngine = {
591
583
  await _fetchBalance();
592
584
  },
593
585
 
586
+ async verifyBvn(): Promise<void> {
587
+ const response: any = await authenticateAPI.verifyBvn();
588
+ getFPStore().setTempId(response?.payload?.temp_id);
589
+ },
590
+
591
+ async verifySmsOtp(payload: any): Promise<void> {
592
+ const response: any = await authenticateAPI.verifySms(payload);
593
+ if(response.status){
594
+ await authenticateAPI.updateProfile({verifyBvn: true});
595
+ const profile = await authenticateAPI.profile();
596
+ getFPStore().setUser(profile);
597
+ getFPStore().clearTempId();
598
+ }
599
+ },
600
+
601
+ async createUserTransactionPin(payload: any): Promise<void> {
602
+ await authenticateAPI.updateProfile(payload);
603
+ const profile = await authenticateAPI.profile();
604
+ getFPStore().setUser(profile);
605
+ },
606
+
594
607
  closeSend(): void {
595
608
  _emitEvent('close_send');
596
609
  },