react-native-fpay 0.2.9 → 0.3.2

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 (120) hide show
  1. package/lib/module/FountainPayProvider.js +5 -1
  2. package/lib/module/FountainPayProvider.js.map +1 -1
  3. package/lib/module/core/api/index.js +22 -12
  4. package/lib/module/core/api/index.js.map +1 -1
  5. package/lib/module/engine/BLEReceiverService.js.map +1 -1
  6. package/lib/module/engine/FPEngine.js +24 -13
  7. package/lib/module/engine/FPEngine.js.map +1 -1
  8. package/lib/module/engine/useIsForeground.js +17 -0
  9. package/lib/module/engine/useIsForeground.js.map +1 -0
  10. package/lib/module/ui/components/AnimatedDots.js +68 -0
  11. package/lib/module/ui/components/AnimatedDots.js.map +1 -0
  12. package/lib/module/ui/components/ConfirmScreen.js +333 -0
  13. package/lib/module/ui/components/ConfirmScreen.js.map +1 -0
  14. package/lib/module/ui/modals/FPPaymentRequestModal.js +6 -8
  15. package/lib/module/ui/modals/FPPaymentRequestModal.js.map +1 -1
  16. package/lib/module/ui/modals/FPShell.js +7 -4
  17. package/lib/module/ui/modals/FPShell.js.map +1 -1
  18. package/lib/module/ui/screens/ReceiveScreen.js +379 -274
  19. package/lib/module/ui/screens/ReceiveScreen.js.map +1 -1
  20. package/lib/module/ui/screens/SendScreen.js +154 -45
  21. package/lib/module/ui/screens/SendScreen.js.map +1 -1
  22. package/lib/module/ui/screens/styles.js +89 -0
  23. package/lib/module/ui/screens/styles.js.map +1 -0
  24. package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js +361 -0
  25. package/lib/module/ui/screens/sub/receivePayment/Nfc/index.js.map +1 -0
  26. package/lib/module/ui/screens/sub/receivePayment/Qr/index.js +338 -0
  27. package/lib/module/ui/screens/sub/receivePayment/Qr/index.js.map +1 -0
  28. package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js +453 -0
  29. package/lib/module/ui/screens/sub/receivePayment/Transfer/index.js.map +1 -0
  30. package/lib/module/ui/screens/sub/{BluetoothSubScreen.js → sendPayment/BluetoothSubScreen.js} +25 -32
  31. package/lib/module/ui/screens/sub/sendPayment/BluetoothSubScreen.js.map +1 -0
  32. package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js +354 -0
  33. package/lib/module/ui/screens/sub/sendPayment/NFCSubScreen.js.map +1 -0
  34. package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js +440 -0
  35. package/lib/module/ui/screens/sub/sendPayment/NQRSubScreen.js.map +1 -0
  36. package/lib/module/ui/screens/sub/{ProximitySubScreen.js → sendPayment/ProximitySubScreen.js} +20 -111
  37. package/lib/module/ui/screens/sub/sendPayment/ProximitySubScreen.js.map +1 -0
  38. package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js +327 -0
  39. package/lib/module/ui/screens/sub/sendPayment/TransferSubScreen.js.map +1 -0
  40. package/lib/typescript/src/FountainPayProvider.d.ts.map +1 -1
  41. package/lib/typescript/src/core/api/index.d.ts +20 -27
  42. package/lib/typescript/src/core/api/index.d.ts.map +1 -1
  43. package/lib/typescript/src/core/types/index.d.ts +56 -13
  44. package/lib/typescript/src/core/types/index.d.ts.map +1 -1
  45. package/lib/typescript/src/engine/BLEReceiverService.d.ts +2 -0
  46. package/lib/typescript/src/engine/BLEReceiverService.d.ts.map +1 -1
  47. package/lib/typescript/src/engine/FPEngine.d.ts +3 -1
  48. package/lib/typescript/src/engine/FPEngine.d.ts.map +1 -1
  49. package/lib/typescript/src/engine/useIsForeground.d.ts +2 -0
  50. package/lib/typescript/src/engine/useIsForeground.d.ts.map +1 -0
  51. package/lib/typescript/src/ui/components/AnimatedDots.d.ts +2 -0
  52. package/lib/typescript/src/ui/components/AnimatedDots.d.ts.map +1 -0
  53. package/lib/typescript/src/ui/components/ConfirmScreen.d.ts +10 -0
  54. package/lib/typescript/src/ui/components/ConfirmScreen.d.ts.map +1 -0
  55. package/lib/typescript/src/ui/components/OtpInput/Styles.d.ts +3 -3
  56. package/lib/typescript/src/ui/modals/FPPaymentRequestModal.d.ts.map +1 -1
  57. package/lib/typescript/src/ui/modals/FPShell.d.ts.map +1 -1
  58. package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts +2 -9
  59. package/lib/typescript/src/ui/screens/ReceiveScreen.d.ts.map +1 -1
  60. package/lib/typescript/src/ui/screens/SendScreen.d.ts +4 -2
  61. package/lib/typescript/src/ui/screens/SendScreen.d.ts.map +1 -1
  62. package/lib/typescript/src/ui/screens/styles.d.ts +1390 -0
  63. package/lib/typescript/src/ui/screens/styles.d.ts.map +1 -0
  64. package/lib/typescript/src/ui/screens/sub/receivePayment/Nfc/index.d.ts +10 -0
  65. package/lib/typescript/src/ui/screens/sub/receivePayment/Nfc/index.d.ts.map +1 -0
  66. package/lib/typescript/src/ui/screens/sub/receivePayment/Qr/index.d.ts +10 -0
  67. package/lib/typescript/src/ui/screens/sub/receivePayment/Qr/index.d.ts.map +1 -0
  68. package/lib/typescript/src/ui/screens/sub/receivePayment/Transfer/index.d.ts +5 -0
  69. package/lib/typescript/src/ui/screens/sub/receivePayment/Transfer/index.d.ts.map +1 -0
  70. package/lib/typescript/src/ui/screens/sub/{BluetoothSubScreen.d.ts → sendPayment/BluetoothSubScreen.d.ts} +2 -11
  71. package/lib/typescript/src/ui/screens/sub/sendPayment/BluetoothSubScreen.d.ts.map +1 -0
  72. package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts +3 -0
  73. package/lib/typescript/src/ui/screens/sub/sendPayment/NFCSubScreen.d.ts.map +1 -0
  74. package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts +3 -0
  75. package/lib/typescript/src/ui/screens/sub/sendPayment/NQRSubScreen.d.ts.map +1 -0
  76. package/lib/typescript/src/ui/screens/sub/{ProximitySubScreen.d.ts → sendPayment/ProximitySubScreen.d.ts} +2 -10
  77. package/lib/typescript/src/ui/screens/sub/sendPayment/ProximitySubScreen.d.ts.map +1 -0
  78. package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts +3 -0
  79. package/lib/typescript/src/ui/screens/sub/sendPayment/TransferSubScreen.d.ts.map +1 -0
  80. package/package.json +1 -1
  81. package/src/FountainPayProvider.tsx +7 -1
  82. package/src/core/api/index.ts +34 -19
  83. package/src/core/types/index.ts +67 -13
  84. package/src/engine/BLEReceiverService.ts +2 -0
  85. package/src/engine/FPEngine.ts +29 -14
  86. package/src/engine/useIsForeground.ts +18 -0
  87. package/src/ui/components/AnimatedDots.tsx +81 -0
  88. package/src/ui/components/ConfirmScreen.tsx +421 -0
  89. package/src/ui/modals/FPPaymentRequestModal.tsx +7 -6
  90. package/src/ui/modals/FPShell.tsx +9 -9
  91. package/src/ui/screens/ReceiveScreen.tsx +266 -115
  92. package/src/ui/screens/SendScreen.tsx +141 -19
  93. package/src/ui/screens/styles.ts +101 -0
  94. package/src/ui/screens/sub/receivePayment/Nfc/index.tsx +418 -0
  95. package/src/ui/screens/sub/receivePayment/Qr/index.tsx +391 -0
  96. package/src/ui/screens/sub/receivePayment/Transfer/index.tsx +512 -0
  97. package/src/ui/screens/sub/{BluetoothSubScreen.tsx → sendPayment/BluetoothSubScreen.tsx} +27 -46
  98. package/src/ui/screens/sub/sendPayment/NFCSubScreen.tsx +302 -0
  99. package/src/ui/screens/sub/sendPayment/NQRSubScreen.tsx +490 -0
  100. package/src/ui/screens/sub/{ProximitySubScreen.tsx → sendPayment/ProximitySubScreen.tsx} +24 -44
  101. package/src/ui/screens/sub/sendPayment/TransferSubScreen.tsx +345 -0
  102. package/lib/module/ui/screens/sub/BluetoothSubScreen.js.map +0 -1
  103. package/lib/module/ui/screens/sub/NFCSubScreen.js +0 -164
  104. package/lib/module/ui/screens/sub/NFCSubScreen.js.map +0 -1
  105. package/lib/module/ui/screens/sub/NQRSubScreen.js +0 -131
  106. package/lib/module/ui/screens/sub/NQRSubScreen.js.map +0 -1
  107. package/lib/module/ui/screens/sub/ProximitySubScreen.js.map +0 -1
  108. package/lib/module/ui/screens/sub/TransferSubScreen.js +0 -353
  109. package/lib/module/ui/screens/sub/TransferSubScreen.js.map +0 -1
  110. package/lib/typescript/src/ui/screens/sub/BluetoothSubScreen.d.ts.map +0 -1
  111. package/lib/typescript/src/ui/screens/sub/NFCSubScreen.d.ts +0 -18
  112. package/lib/typescript/src/ui/screens/sub/NFCSubScreen.d.ts.map +0 -1
  113. package/lib/typescript/src/ui/screens/sub/NQRSubScreen.d.ts +0 -12
  114. package/lib/typescript/src/ui/screens/sub/NQRSubScreen.d.ts.map +0 -1
  115. package/lib/typescript/src/ui/screens/sub/ProximitySubScreen.d.ts.map +0 -1
  116. package/lib/typescript/src/ui/screens/sub/TransferSubScreen.d.ts +0 -11
  117. package/lib/typescript/src/ui/screens/sub/TransferSubScreen.d.ts.map +0 -1
  118. package/src/ui/screens/sub/NFCSubScreen.tsx +0 -86
  119. package/src/ui/screens/sub/NQRSubScreen.tsx +0 -62
  120. package/src/ui/screens/sub/TransferSubScreen.tsx +0 -147
@@ -0,0 +1,512 @@
1
+ import React, { useState } from 'react';
2
+ import { Share, Clipboard, Alert } from 'react-native';
3
+ import styled from 'styled-components/native';
4
+ import { Buffer } from 'buffer';
5
+ import Ionicons from 'react-native-vector-icons/Ionicons';
6
+ import type { ReceiveTransferScreenProps } from '../../../../../core/types';
7
+
8
+
9
+ // Styled Components
10
+ const Container = styled.View`
11
+ flex: 1;
12
+ background-color: #f5f5f5;
13
+ padding-bottom: 60%;
14
+ `;
15
+
16
+ const Header = styled.View`
17
+ flex-direction: row;
18
+ align-items: center;
19
+ padding: 16px;
20
+ padding-top: 40px;
21
+ background-color: #ffffff;
22
+ border-bottom-width: 1px;
23
+ border-bottom-color: #e0e0e0;
24
+ `;
25
+
26
+ const BackButton = styled.TouchableOpacity`
27
+ padding: 8px;
28
+ `;
29
+
30
+ const BackIcon = styled.Text`
31
+ font-size: 24px;
32
+ color: #000000;
33
+ `;
34
+
35
+ const HeaderTitle = styled.Text`
36
+ flex: 1;
37
+ font-size: 18px;
38
+ font-weight: 600;
39
+ color: #000000;
40
+ text-align: center;
41
+ margin-right: 40px;
42
+ `;
43
+
44
+ const ScrollContainer = styled.ScrollView`
45
+ flex: 1;
46
+
47
+ `;
48
+
49
+ const ContentContainer = styled.View`
50
+ padding: 24px;
51
+ `;
52
+
53
+ const InfoBanner = styled.View`
54
+ background-color: #E8F5F1;
55
+ border-radius: 12px;
56
+ padding: 16px;
57
+ margin-bottom: 24px;
58
+ flex-direction: row;
59
+ align-items: flex-start;
60
+ `;
61
+
62
+ const InfoIcon = styled.Text`
63
+ font-size: 20px;
64
+ margin-right: 12px;
65
+ `;
66
+
67
+ const InfoText = styled.Text`
68
+ flex: 1;
69
+ font-size: 13px;
70
+ color: #00A876;
71
+ line-height: 20px;
72
+ `;
73
+
74
+ const AmountCard = styled.View`
75
+ background-color: #ffffff;
76
+ border-radius: 16px;
77
+ padding: 24px;
78
+ align-items: center;
79
+ margin-bottom: 24px;
80
+ shadow-color: #000;
81
+ shadow-offset: 0px 2px;
82
+ shadow-opacity: 0.05;
83
+ shadow-radius: 8px;
84
+ elevation: 3;
85
+ `;
86
+
87
+ const AmountLabel = styled.Text`
88
+ font-size: 14px;
89
+ color: #666666;
90
+ margin-bottom: 8px;
91
+ `;
92
+
93
+ const AmountText = styled.Text`
94
+ font-size: 42px;
95
+ font-weight: 700;
96
+ color: #0a3d2e;
97
+ margin-bottom: 8px;
98
+ `;
99
+
100
+ const DescriptionText = styled.Text`
101
+ font-size: 14px;
102
+ color: #999999;
103
+ font-style: italic;
104
+ `;
105
+
106
+ const SectionTitle = styled.Text`
107
+ font-size: 15px;
108
+ font-weight: 600;
109
+ color: #333333;
110
+ margin-bottom: 16px;
111
+ `;
112
+
113
+ const DetailsCard = styled.View`
114
+ background-color: #ffffff;
115
+ border-radius: 16px;
116
+ padding: 20px;
117
+ margin-bottom: 24px;
118
+ shadow-color: #000;
119
+ shadow-offset: 0px 2px;
120
+ shadow-opacity: 0.05;
121
+ shadow-radius: 8px;
122
+ elevation: 3;
123
+ `;
124
+
125
+ const DetailItem = styled.View`
126
+ margin-bottom: 20px;
127
+ `;
128
+
129
+ const DetailLabel = styled.Text`
130
+ font-size: 13px;
131
+ color: #999999;
132
+ margin-bottom: 8px;
133
+ `;
134
+
135
+ const DetailValueContainer = styled.View`
136
+ flex-direction: row;
137
+ align-items: center;
138
+ justify-content: space-between;
139
+ `;
140
+
141
+ const DetailValue = styled.Text`
142
+ font-size: 16px;
143
+ font-weight: 600;
144
+ color: #333333;
145
+ flex: 1;
146
+ `;
147
+
148
+ const CopyButton = styled.TouchableOpacity`
149
+ background-color: #E8F5F1;
150
+ border-radius: 20px;
151
+ padding: 8px 16px;
152
+ margin-left: 12px;
153
+ `;
154
+
155
+ const CopyButtonText = styled.Text`
156
+ font-size: 13px;
157
+ font-weight: 600;
158
+ color: #0a3d2e;
159
+ `;
160
+
161
+ const Divider = styled.View`
162
+ height: 1px;
163
+ background-color: #F0F0F0;
164
+ margin: 4px 0;
165
+ `;
166
+
167
+ const PaymentLinkCard = styled.View`
168
+ background-color: #FFF3E0;
169
+ border-radius: 12px;
170
+ padding: 16px;
171
+ margin-bottom: 24px;
172
+ `;
173
+
174
+ const PaymentLinkTitle = styled.Text`
175
+ font-size: 14px;
176
+ font-weight: 600;
177
+ color: #F57C00;
178
+ margin-bottom: 8px;
179
+ `;
180
+
181
+ const PaymentLinkText = styled.Text`
182
+ font-size: 12px;
183
+ color: #F57C00;
184
+ margin-bottom: 12px;
185
+ `;
186
+
187
+ const PaymentLinkContainer = styled.View`
188
+ background-color: #ffffff;
189
+ border-radius: 8px;
190
+ padding: 12px;
191
+ margin-bottom: 12px;
192
+ `;
193
+
194
+ const PaymentLinkUrl = styled.Text`
195
+ font-size: 12px;
196
+ color: #666666;
197
+ font-family: monospace;
198
+ `;
199
+
200
+ const LinkButtonRow = styled.View`
201
+ flex-direction: row;
202
+ gap: 8px;
203
+ `;
204
+
205
+ const SmallButton = styled.TouchableOpacity`
206
+ flex: 1;
207
+ background-color: #ffffff;
208
+ border: 1px solid #F57C00;
209
+ border-radius: 20px;
210
+ padding: 10px;
211
+ align-items: center;
212
+ `;
213
+
214
+ const SmallButtonText = styled.Text`
215
+ font-size: 13px;
216
+ font-weight: 600;
217
+ color: #F57C00;
218
+ `;
219
+
220
+ const ButtonContainer = styled.View`
221
+ gap: 12px;
222
+ `;
223
+
224
+ const PrimaryButton = styled.TouchableOpacity`
225
+ background-color: #0a3d2e;
226
+ border-radius: 28px;
227
+ padding: 16px;
228
+ align-items: center;
229
+ `;
230
+
231
+ const PrimaryButtonText = styled.Text`
232
+ font-size: 15px;
233
+ font-weight: 600;
234
+ color: #ffffff;
235
+ `;
236
+
237
+ const OutlineButton = styled.TouchableOpacity`
238
+ background-color: #ffffff;
239
+ border: 1.5px solid #0a3d2e;
240
+ border-radius: 28px;
241
+ padding: 16px;
242
+ align-items: center;
243
+ `;
244
+
245
+ const OutlineButtonText = styled.Text`
246
+ font-size: 15px;
247
+ font-weight: 600;
248
+ color: #0a3d2e;
249
+ `;
250
+
251
+ const SecondaryButton = styled.TouchableOpacity`
252
+ background-color: #ffffff;
253
+ border: 1.5px solid #E0E0E0;
254
+ border-radius: 28px;
255
+ padding: 16px;
256
+ align-items: center;
257
+ `;
258
+
259
+ const SecondaryButtonText = styled.Text`
260
+ font-size: 15px;
261
+ font-weight: 600;
262
+ color: #666666;
263
+ `;
264
+
265
+ const Footer = styled.View`
266
+ padding: 16px 24px 24px;
267
+ `;
268
+
269
+ const FooterText = styled.Text`
270
+ font-size: 12px;
271
+ color: #999999;
272
+ text-align: center;
273
+ line-height: 18px;
274
+ `;
275
+
276
+ // Main Component
277
+
278
+
279
+ const Transfer: React.FC<ReceiveTransferScreenProps> = ({
280
+ amount = 0,
281
+ description = '',
282
+ user,
283
+ recipient,
284
+ onClose,
285
+ onPaymentReceived,
286
+ }) => {
287
+ const [copiedField, setCopiedField] = useState<string | null>(null);
288
+
289
+ const formatAmount = (value: number): string => {
290
+ return value.toLocaleString('en-NG', {
291
+ minimumFractionDigits: 2,
292
+ maximumFractionDigits: 2,
293
+ });
294
+ };
295
+
296
+ const handleCopy = async (text: string, fieldName: string) => {
297
+ try {
298
+ await Clipboard.setString(text);
299
+ setCopiedField(fieldName);
300
+
301
+ // Reset copied state after 2 seconds
302
+ setTimeout(() => {
303
+ setCopiedField(null);
304
+ }, 2000);
305
+ } catch (error) {
306
+ console.error('Failed to copy:', error);
307
+ }
308
+ };
309
+
310
+ const generatePaymentLink = (): string => {
311
+ // Generate a payment link (in production, this would be a real URL)
312
+ const base64 = Buffer.from(JSON.stringify({
313
+ account: recipient.accountNumber,
314
+ recipient: recipient.accountName,
315
+ })).toString('base64');
316
+
317
+
318
+ return `https://tapit.app/pay/${base64}`;
319
+ };
320
+
321
+ const handleShareDetails = async () => {
322
+ //Please send ₦${formatAmount(amount)} to:
323
+ const message = `
324
+
325
+
326
+ Account Number: ${recipient.accountNumber}
327
+ Account Name: ${recipient.accountName}
328
+ Bank: ${recipient.bankName}
329
+ ${description ? `Payment for: ${description}` : ''}
330
+
331
+ Thank you!
332
+ `.trim();
333
+
334
+ try {
335
+ await Share.share({
336
+ message,
337
+ title: 'Payment Details',
338
+ });
339
+ } catch (error) {
340
+ console.error('Error sharing:', error);
341
+ }
342
+ };
343
+
344
+ const handleShareLink = async () => {
345
+ const link = generatePaymentLink();
346
+ try {
347
+ await Share.share({
348
+ message: `Pay send money via this link: ${link}`,
349
+ title: 'Payment Link',
350
+ });
351
+ } catch (error) {
352
+ console.error('Error sharing link:', error);
353
+ }
354
+ };
355
+
356
+ const handleCopyLink = async () => {
357
+ const link = generatePaymentLink();
358
+ await handleCopy(link, 'link');
359
+ };
360
+
361
+ const handleCopyAll = async () => {
362
+ const allDetails = `Account: ${recipient?.accountNumber}\nName: ${recipient?.accountName}\nBank: ${recipient?.bankName}}`; //\nAmount: ₦${formatAmount(amount)
363
+ await handleCopy(allDetails, 'all');
364
+ };
365
+
366
+ return (
367
+ <Container>
368
+ {/* Header */}
369
+ <Header>
370
+ <BackButton onPress={onClose}>
371
+ <Ionicons name="close" size={24} />
372
+ </BackButton>
373
+ <HeaderTitle>Receive via Transfer</HeaderTitle>
374
+ </Header>
375
+
376
+ {/* Content */}
377
+ <ScrollContainer showsVerticalScrollIndicator={false}>
378
+ <ContentContainer>
379
+ {/* Info Banner */}
380
+ <InfoBanner>
381
+ <InfoIcon>ℹ️</InfoIcon>
382
+ <InfoText>
383
+ Share your account details below with the payer. You'll be
384
+ notified when the payment is received.
385
+ </InfoText>
386
+ </InfoBanner>
387
+
388
+ {/* Amount Display */}
389
+ {amount > 0 && (<AmountCard>
390
+ <AmountLabel>Expected Amount</AmountLabel>
391
+ <AmountText>₦{formatAmount(amount)}</AmountText>
392
+ {description && <DescriptionText>{description}</DescriptionText>}
393
+ </AmountCard>)}
394
+
395
+ {/* Account Details */}
396
+ <SectionTitle>Send money to this account</SectionTitle>
397
+ <DetailsCard>
398
+ <DetailItem>
399
+ <DetailLabel>Account Number</DetailLabel>
400
+ <DetailValueContainer>
401
+ <DetailValue>{recipient.accountNumber}</DetailValue>
402
+ <CopyButton
403
+ onPress={() => handleCopy(recipient.accountNumber, 'account')}
404
+ >
405
+ <CopyButtonText>
406
+ {copiedField === 'account' ? 'Copied!' : 'Copy'}
407
+ </CopyButtonText>
408
+ </CopyButton>
409
+ </DetailValueContainer>
410
+ </DetailItem>
411
+
412
+ <Divider />
413
+
414
+ <DetailItem>
415
+ <DetailLabel>Account Name</DetailLabel>
416
+ <DetailValueContainer>
417
+ <DetailValue>{recipient.accountName}</DetailValue>
418
+ <CopyButton onPress={() => handleCopy(recipient.accountName, 'name')}>
419
+ <CopyButtonText>
420
+ {copiedField === 'name' ? 'Copied!' : 'Copy'}
421
+ </CopyButtonText>
422
+ </CopyButton>
423
+ </DetailValueContainer>
424
+ </DetailItem>
425
+
426
+ <Divider />
427
+
428
+ <DetailItem>
429
+ <DetailLabel>Bank</DetailLabel>
430
+ <DetailValueContainer>
431
+ <DetailValue>{recipient.bankName}</DetailValue>
432
+ <CopyButton onPress={() => handleCopy(recipient.bankName, 'bank')}>
433
+ <CopyButtonText>
434
+ {copiedField === 'bank' ? 'Copied!' : 'Copy'}
435
+ </CopyButtonText>
436
+ </CopyButton>
437
+ </DetailValueContainer>
438
+ </DetailItem>
439
+
440
+ <Divider />
441
+
442
+ {amount > 0 && (
443
+ <DetailItem style={{ marginBottom: 0 }}>
444
+ <DetailLabel>Amount</DetailLabel>
445
+ <DetailValueContainer>
446
+ <DetailValue>₦{formatAmount(amount)}</DetailValue>
447
+ <CopyButton
448
+ onPress={() => handleCopy(amount.toString(), 'amount')}
449
+ >
450
+ <CopyButtonText>
451
+ {copiedField === 'amount' ? 'Copied!' : 'Copy'}
452
+ </CopyButtonText>
453
+ </CopyButton>
454
+ </DetailValueContainer>
455
+ </DetailItem>
456
+ )}
457
+ </DetailsCard>
458
+
459
+ {/* Payment Link */}
460
+ <PaymentLinkCard>
461
+ <PaymentLinkTitle>📎 Quick Payment Link</PaymentLinkTitle>
462
+ <PaymentLinkText>
463
+ Share this link with anyone to receive payment instantly
464
+ </PaymentLinkText>
465
+ <PaymentLinkContainer>
466
+ <PaymentLinkUrl numberOfLines={1} ellipsizeMode="middle">
467
+ {generatePaymentLink()}
468
+ </PaymentLinkUrl>
469
+ </PaymentLinkContainer>
470
+ <LinkButtonRow>
471
+ <SmallButton onPress={handleCopyLink}>
472
+ <SmallButtonText>
473
+ {copiedField === 'link' ? '✓ Copied' : 'Copy Link'}
474
+ </SmallButtonText>
475
+ </SmallButton>
476
+ <SmallButton onPress={handleShareLink}>
477
+ <SmallButtonText>Share Link</SmallButtonText>
478
+ </SmallButton>
479
+ </LinkButtonRow>
480
+ </PaymentLinkCard>
481
+
482
+ {/* Action Buttons */}
483
+ <ButtonContainer>
484
+ <PrimaryButton onPress={handleShareDetails}>
485
+ <PrimaryButtonText>Share All Details</PrimaryButtonText>
486
+ </PrimaryButton>
487
+
488
+ <OutlineButton onPress={handleCopyAll}>
489
+ <OutlineButtonText>
490
+ {copiedField === 'all' ? '✓ All Details Copied' : 'Copy All Details'}
491
+ </OutlineButtonText>
492
+ </OutlineButton>
493
+
494
+ <SecondaryButton onPress={onClose}>
495
+ <SecondaryButtonText>Done</SecondaryButtonText>
496
+ </SecondaryButton>
497
+ </ButtonContainer>
498
+ </ContentContainer>
499
+
500
+ {/* Footer */}
501
+ <Footer>
502
+ <FooterText>
503
+ You will receive a notification once the payment is confirmed in
504
+ your account. Please allow 1-5 minutes for bank transfers.
505
+ </FooterText>
506
+ </Footer>
507
+ </ScrollContainer>
508
+ </Container>
509
+ );
510
+ };
511
+
512
+ export default Transfer;
@@ -17,15 +17,15 @@ import styled from 'styled-components/native';
17
17
  import Svg, { Path } from 'react-native-svg';
18
18
  import Ionicons from 'react-native-vector-icons/Ionicons';
19
19
 
20
- import { transferAPI } from '../../../core/api';
21
- import { FPButton } from '../../components/FPButton';
22
- import { C, R, S, F, shadow } from '../../theme';
23
- import type { FPCurrency, FPError, FPTransaction, FintechDevice } from '../../../core/types';
20
+ import { transferAPI } from '../../../../core/api';
21
+ import { FPButton } from '../../../components/FPButton';
22
+ import { C, R, S, F, shadow } from '../../../theme';
23
+ import type { FPCurrency, FPError, FPSendPaymentRequest, FPTransaction, FintechDevice, Props } from '../../../../core/types';
24
24
 
25
- import { FPEngine } from '../../../engine/FPEngine';
25
+ import { FPEngine } from '../../../../engine/FPEngine';
26
26
 
27
- import { PulseAnimation } from '../../components/PulseAnimation';
28
- import InLoading from '../../components/LoadingAnimation/InLoading';
27
+ import { PulseAnimation } from '../../../components/PulseAnimation';
28
+ import InLoading from '../../../components/LoadingAnimation/InLoading';
29
29
 
30
30
 
31
31
  const Container = styled(View)`
@@ -195,29 +195,17 @@ const PHASE_LABEL: Record<Phase, string> = {
195
195
  error: 'Something went wrong',
196
196
  };
197
197
 
198
- interface Props {
199
- mode: 'send' | 'receive';
200
- amount: number;
201
- currency: FPCurrency;
202
- onDone: () => void;
203
- onSuccess?: (tx: FPTransaction) => void;
204
- onError?: (err: FPError) => void;
205
- }
206
-
207
198
  export function BluetoothSubScreen({
208
- mode,
209
199
  amount,
210
200
  currency,
211
- onDone,
212
- onSuccess,
201
+ onClose,
202
+ onProcessTransaction,
213
203
  onError,
214
204
  }: Props) {
215
205
  const [devices, setDevices] = useState<FintechDevice[]>([]);
216
206
  const [scanning, setScanning] = useState(false);
217
207
  const [status, setStatus] = useState('Ready to scan');
218
208
  const [currentDevice, setCurrentDevice] = useState<FintechDevice | null>(null);
219
-
220
-
221
209
 
222
210
  // ── 1. Scan ───────────────────────────────────────────────
223
211
 
@@ -263,14 +251,14 @@ export function BluetoothSubScreen({
263
251
  },
264
252
  {
265
253
  text: `Continue`,
266
- onPress: () => initiatePayment(device, 50),
254
+ onPress: () => initiatePayment(device),
267
255
  },
268
256
  ]
269
257
  );
270
258
  };
271
259
 
272
260
 
273
- const initiatePayment = async (device: FintechDevice, amount: number) => {
261
+ const initiatePayment = async (device: FintechDevice) => {
274
262
  try {
275
263
  setCurrentDevice(device);
276
264
  // Connect to the device
@@ -281,8 +269,10 @@ export function BluetoothSubScreen({
281
269
  const request: any = {
282
270
  amount,
283
271
  currency,
284
- senderId: user?.userId ?? user?.accountNumber ?? 'unknown',
285
- senderName: user?.accountName ?? 'FountainPay User',
272
+ senderId: user?.userId ?? 'unknown',
273
+ senderName: user?.name ?? 'FountainPay User',
274
+ senderPhone: user?.phone ?? 'unknown',
275
+ senderEmail: user?.email ?? 'unknown',
286
276
  timestamp: Date.now(),
287
277
  };
288
278
 
@@ -311,29 +301,17 @@ export function BluetoothSubScreen({
311
301
  } as FPError;
312
302
  }
313
303
 
314
- const result = await transferAPI.send({
315
- accountNumber: response.accountDetails.accountNumber,
316
- bankCode: response.accountDetails.bankCode,
317
- amount: amount * 100,
318
- narration: `Bluetooth payment to ${response.accountDetails.accountName}`,
319
- reference: response.transactionId,
320
- });
321
-
322
- const tx: FPTransaction = {
323
- id: result.reference,
324
- reference: result.reference,
325
- type: 'debit',
326
- channel: 'bluetooth',
327
- amount: result.amount,
328
- currency: result.currency,
329
- status: result.status,
330
- recipient: { accountName: response.accountDetails.accountName },
331
- createdAt: result.createdAt,
332
- };
304
+ const payload: FPSendPaymentRequest = {
305
+ amount: amount,
306
+ currency: currency,
307
+ channel: 'bluetooth',
308
+ narration: `Send ${currency}${amount} to ${response.accountDetails.accountName}`,
309
+ recipient: response.accountDetails
310
+ }
333
311
 
334
- onSuccess?.(tx);
312
+ onProcessTransaction?.(payload);
335
313
  setCurrentDevice(null);
336
- setStatus('Waiting for response...');
314
+ setStatus('Payment sent!');
337
315
  } catch (error: any) {
338
316
  const fp = error as FPError;
339
317
  setCurrentDevice(null);
@@ -356,6 +334,9 @@ export function BluetoothSubScreen({
356
334
  {/* Status Bar */}
357
335
 
358
336
  <Header>
337
+ <HeaderButton onPress={onClose}>
338
+ <Ionicons name="close" size={24} />
339
+ </HeaderButton>
359
340
  <HeaderCenter>
360
341
  <Text style={{ fontWeight: 'bold', fontSize: 16, color:'#FFF' }}>Bluetooth</Text>
361
342
  <Text style={{ fontSize: 10, color: '#FFF' }}>Transfer</Text>