fairsure-checkout-sdk 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 (40) hide show
  1. package/dist/components/CardPayment.d.ts +18 -0
  2. package/dist/components/CardPayment.js +302 -0
  3. package/dist/components/Checkout.d.ts +9 -0
  4. package/dist/components/Checkout.js +520 -0
  5. package/dist/components/OTPInput.d.ts +17 -0
  6. package/dist/components/OTPInput.js +132 -0
  7. package/dist/components/PaymentMethodSelector.d.ts +12 -0
  8. package/dist/components/PaymentMethodSelector.js +67 -0
  9. package/dist/components/PaystackCheckout.d.ts +13 -0
  10. package/dist/components/PaystackCheckout.js +385 -0
  11. package/dist/components/PurchaseModal.d.ts +17 -0
  12. package/dist/components/PurchaseModal.js +415 -0
  13. package/dist/components/TransferPayment.d.ts +16 -0
  14. package/dist/components/TransferPayment.js +311 -0
  15. package/dist/components/USSDPayment.d.ts +21 -0
  16. package/dist/components/USSDPayment.js +316 -0
  17. package/dist/components/usePaymentCheckout.d.ts +61 -0
  18. package/dist/components/usePaymentCheckout.js +398 -0
  19. package/dist/context/CheckoutProvider.d.ts +5 -0
  20. package/dist/context/CheckoutProvider.js +16 -0
  21. package/dist/hooks/useCheckout.d.ts +1 -0
  22. package/dist/hooks/useCheckout.js +8 -0
  23. package/dist/index.d.ts +2 -0
  24. package/dist/index.js +2 -0
  25. package/dist/types.d.ts +9 -0
  26. package/dist/types.js +1 -0
  27. package/fairsure-checkout-sdk-1.0.0.tgz +0 -0
  28. package/package.json +24 -0
  29. package/src/components/CardPayment.tsx +386 -0
  30. package/src/components/OTPInput.tsx +204 -0
  31. package/src/components/PaymentMethodSelector.tsx +99 -0
  32. package/src/components/PaystackCheckout.tsx +506 -0
  33. package/src/components/TransferPayment.tsx +372 -0
  34. package/src/components/USSDPayment.tsx +422 -0
  35. package/src/components/usePaymentCheckout.ts +441 -0
  36. package/src/context/CheckoutProvider.tsx +37 -0
  37. package/src/hooks/useCheckout.ts +11 -0
  38. package/src/index.ts +2 -0
  39. package/src/types.ts +9 -0
  40. package/tsconfig.json +22 -0
@@ -0,0 +1,422 @@
1
+ import { Ionicons } from "@expo/vector-icons";
2
+ import {
3
+ ActivityIndicator,
4
+ ScrollView,
5
+ StyleSheet,
6
+ Text,
7
+ TouchableOpacity,
8
+ View,
9
+ } from "react-native";
10
+
11
+ type UssdBank = {
12
+ name: string;
13
+ code: string;
14
+ };
15
+
16
+ type USSDPaymentProps = {
17
+ selectedBank: UssdBank | null;
18
+ setSelectedBank: (bank: UssdBank) => void;
19
+ ussString: { ussdString: string; codeRef: string; amount: string };
20
+ showBankDropdown: boolean;
21
+ setShowBankDropdown: (show: boolean) => void;
22
+ ussdBanks: UssdBank[];
23
+ loading: boolean;
24
+ copied: boolean;
25
+ handleCopy: (text: string) => void;
26
+ };
27
+
28
+ export default function USSDPayment({
29
+ selectedBank,
30
+ setSelectedBank,
31
+ showBankDropdown,
32
+ ussString,
33
+ setShowBankDropdown,
34
+ ussdBanks,
35
+ loading,
36
+ copied,
37
+ handleCopy,
38
+ }: USSDPaymentProps) {
39
+ // console.log("USSSSSS", ussdBanks);
40
+
41
+ return (
42
+ <View>
43
+ <View style={styles.inputGroup}>
44
+ <Text style={styles.inputLabel}>Select Your Bank</Text>
45
+ <TouchableOpacity
46
+ onPress={() => setShowBankDropdown(!showBankDropdown)}
47
+ style={styles.dropdown}
48
+ >
49
+ <Text
50
+ style={
51
+ selectedBank ? styles.dropdownText : styles.dropdownPlaceholder
52
+ }
53
+ >
54
+ {selectedBank?.name || "Choose your bank"}
55
+ </Text>
56
+ <Ionicons name="chevron-down" size={20} color="#9CA3AF" />
57
+ </TouchableOpacity>
58
+
59
+ {showBankDropdown && (
60
+ <BankDropdown
61
+ ussdBanks={ussdBanks}
62
+ loading={loading}
63
+ onSelectBank={(bank) => {
64
+ setSelectedBank(bank);
65
+ setShowBankDropdown(false);
66
+ }}
67
+ />
68
+ )}
69
+ </View>
70
+
71
+ {selectedBank && (
72
+ <USSDInstructions
73
+ ussdCode={ussString.ussdString}
74
+ copied={copied}
75
+ loading={loading}
76
+ handleCopy={handleCopy}
77
+ />
78
+ )}
79
+ </View>
80
+ );
81
+ }
82
+
83
+ function BankDropdown({
84
+ ussdBanks,
85
+ loading,
86
+ onSelectBank,
87
+ }: {
88
+ ussdBanks: UssdBank[];
89
+ loading: boolean;
90
+ onSelectBank: (bank: UssdBank) => void;
91
+ }) {
92
+ return (
93
+ <View style={styles.dropdownList}>
94
+ <ScrollView
95
+ style={{ maxHeight: 240 }}
96
+ nestedScrollEnabled
97
+ keyboardShouldPersistTaps="handled"
98
+ showsVerticalScrollIndicator
99
+ >
100
+ {loading ? (
101
+ <ActivityIndicator size="large" color="#4F46E5" />
102
+ ) : ussdBanks.length === 0 ? (
103
+ <Text style={styles.dropdownPlaceholder}>No banks available</Text>
104
+ ) : (
105
+ ussdBanks.map((bank) => (
106
+ <TouchableOpacity
107
+ key={bank.code}
108
+ onPress={() => onSelectBank(bank)}
109
+ style={styles.dropdownItem}
110
+ >
111
+ <Text style={styles.dropdownItemText}>{bank.name}</Text>
112
+ </TouchableOpacity>
113
+ ))
114
+ )}
115
+ </ScrollView>
116
+ </View>
117
+ );
118
+ }
119
+
120
+ function USSDInstructions({
121
+ ussdCode,
122
+ copied,
123
+ handleCopy,
124
+ loading,
125
+ }: {
126
+ ussdCode: string;
127
+ copied: boolean;
128
+ loading: boolean;
129
+ handleCopy: (text: string) => void;
130
+ }) {
131
+ return (
132
+ <View style={styles.ussdContainer}>
133
+ <Text style={styles.ussdTitle}>
134
+ Dial the code below to complete payment
135
+ </Text>
136
+
137
+ <View style={styles.ussdCodeContainer}>
138
+ <View style={styles.row}>
139
+ <Text style={styles.ussdCodeText}>{ussdCode}</Text>
140
+ <TouchableOpacity onPress={() => handleCopy(ussdCode)}>
141
+ <Ionicons
142
+ name={copied ? "checkmark" : "copy-outline"}
143
+ size={20}
144
+ color="#4F46E5"
145
+ />
146
+ </TouchableOpacity>
147
+ {loading && <ActivityIndicator size="small" color="#4F46E5" />}
148
+ </View>
149
+ </View>
150
+
151
+ <View>
152
+ <Text style={styles.ussdCodeText}>Steps:</Text>
153
+ <Text style={styles.ussdStepsText}>
154
+ 1. Dial the USSD code on your phone{"\n"}
155
+ 2. Follow the prompts on your screen{"\n"}
156
+ 3. Authorize payment with your bank PIN
157
+ </Text>
158
+ </View>
159
+ </View>
160
+ );
161
+ }
162
+ const styles = StyleSheet.create({
163
+ overlay: {
164
+ flex: 1,
165
+ backgroundColor: "rgba(0,0,0,0.5)",
166
+ justifyContent: "center",
167
+ },
168
+ modalContainer: {
169
+ position: "relative",
170
+ width: "90%",
171
+ alignSelf: "center",
172
+ borderRadius: 20,
173
+ height: "80%",
174
+ backgroundColor: "white",
175
+ },
176
+
177
+ otpContainer: {
178
+ width: "100%",
179
+ marginHorizontal: "auto",
180
+ marginTop: 20,
181
+ marginBottom: 40,
182
+ },
183
+ header: {
184
+ backgroundColor: "#6B21A8",
185
+ padding: 16,
186
+ borderTopLeftRadius: 20,
187
+ borderTopRightRadius: 20,
188
+ },
189
+ pinWrapper: {
190
+ flexDirection: "row",
191
+ alignItems: "center",
192
+ },
193
+ eyeButton: {
194
+ paddingHorizontal: 10,
195
+ },
196
+ eyeText: {
197
+ color: "#007AFF",
198
+ },
199
+
200
+ headerTop: {
201
+ flexDirection: "row",
202
+ justifyContent: "space-between",
203
+ alignItems: "flex-start",
204
+ marginBottom: 16,
205
+ },
206
+ headerTitle: { color: "white", fontSize: 24, fontWeight: "bold" },
207
+ headerSubtitle: { color: "#E0E7FF", fontSize: 14, marginTop: 4 },
208
+ closeBtn: {
209
+ backgroundColor: "rgba(255,255,255,0.2)",
210
+ borderRadius: 999,
211
+ padding: 8,
212
+ },
213
+ amountBox: {
214
+ backgroundColor: "rgba(255,255,255,0.2)",
215
+ borderRadius: 12,
216
+ padding: 8,
217
+ },
218
+ amountLabel: { color: "#E0E7FF", fontSize: 12, marginBottom: 4 },
219
+ amountText: { color: "white", fontSize: 20, fontWeight: "bold" },
220
+ scrollContainer: { flex: 1, marginBottom: 16 },
221
+ body: {
222
+ padding: 24,
223
+ backgroundColor: "white",
224
+ borderBottomLeftRadius: 20,
225
+ borderBottomRightRadius: 20,
226
+ },
227
+ paymentMethodsContainer: {
228
+ flexDirection: "row",
229
+ marginBottom: 24,
230
+ backgroundColor: "#F3F4F6",
231
+ padding: 4,
232
+ borderRadius: 12,
233
+ },
234
+ paymentMethod: {
235
+ flex: 1,
236
+ flexDirection: "row",
237
+ alignItems: "center",
238
+ justifyContent: "center",
239
+ paddingVertical: 12,
240
+ borderRadius: 12,
241
+ marginHorizontal: 4,
242
+ },
243
+ paymentMethodSelected: { backgroundColor: "white" },
244
+ paymentMethodText: { fontSize: 14, color: "#4B5563", marginLeft: 8 },
245
+ paymentMethodTextSelected: { color: "#4F46E5", fontWeight: "600" },
246
+ inputGroup: { marginBottom: 16 },
247
+ inputLabel: {
248
+ fontSize: 14,
249
+ fontWeight: "500",
250
+ color: "#374151",
251
+ marginBottom: 4,
252
+ },
253
+ inputWrapper: { position: "relative" },
254
+ input: {
255
+ width: "100%",
256
+ paddingHorizontal: 16,
257
+ paddingVertical: 12,
258
+ borderWidth: 1,
259
+ borderColor: "#D1D5DB",
260
+ borderRadius: 12,
261
+ backgroundColor: "white",
262
+ },
263
+ inputIcon: { position: "absolute", right: 16, top: 14 },
264
+ row: { flexDirection: "row", backgroundColor: "white", marginBottom: 12 },
265
+ flex1: { flex: 1 },
266
+ secureBox: {
267
+ flexDirection: "row",
268
+ alignItems: "center",
269
+ backgroundColor: "#F9FAFB",
270
+ padding: 12,
271
+ borderRadius: 12,
272
+ gap: 8,
273
+ marginBottom: 16,
274
+ },
275
+ secureText: { fontSize: 12, color: "#4B5563", flex: 1 },
276
+ transferBox: {
277
+ backgroundColor: "#EFF6FF",
278
+ borderWidth: 1,
279
+ borderColor: "#BFDBFE",
280
+ borderRadius: 12,
281
+ padding: 8,
282
+ marginBottom: 8,
283
+ },
284
+ transferText: {
285
+ fontSize: 14,
286
+ color: "#1E3A8A",
287
+ fontWeight: "500",
288
+ marginBottom: 12,
289
+ },
290
+ transferDetail: {
291
+ backgroundColor: "white",
292
+ borderRadius: 12,
293
+ padding: 8,
294
+ marginBottom: 12,
295
+ },
296
+ transferLabel: { fontSize: 10, color: "#4B5563", marginBottom: 4 },
297
+ transferValue: { fontWeight: "600", color: "#111827" },
298
+ accountNumber: {
299
+ fontWeight: "600",
300
+ color: "#111827",
301
+ fontSize: 16,
302
+ letterSpacing: 2,
303
+ flex: 1,
304
+ },
305
+ transferNote: {
306
+ backgroundColor: "#FEF3C7",
307
+ borderWidth: 1,
308
+ borderColor: "#FDE68A",
309
+ borderRadius: 12,
310
+ padding: 8,
311
+ },
312
+ transferNoteText: { fontSize: 14, color: "#78350F" },
313
+ dropdown: {
314
+ width: "100%",
315
+ paddingHorizontal: 16,
316
+ paddingVertical: 12,
317
+ borderWidth: 1,
318
+ borderColor: "#D1D5DB",
319
+ borderRadius: 12,
320
+ flexDirection: "row",
321
+ justifyContent: "space-between",
322
+ alignItems: "center",
323
+ },
324
+ dropdownText: { color: "#111827" },
325
+ dropdownPlaceholder: { color: "#9CA3AF" },
326
+ dropdownList: {
327
+ marginTop: 8,
328
+ backgroundColor: "white",
329
+ borderWidth: 1,
330
+ borderColor: "#E5E7EB",
331
+ borderRadius: 12,
332
+ overflow: "hidden",
333
+ maxHeight: 240,
334
+ },
335
+ dropdownItem: {
336
+ paddingVertical: 12,
337
+ paddingHorizontal: 16,
338
+ borderBottomWidth: 1,
339
+ borderBottomColor: "#F3F4F6",
340
+ },
341
+ dropdownItemText: { color: "#111827" },
342
+
343
+ ussdContainer: {
344
+ backgroundColor: "#E0E7FF", // bg-indigo-50
345
+ borderWidth: 1,
346
+ borderColor: "#C7D2FE", // border-indigo-200
347
+ borderRadius: 12, // rounded-xl
348
+ padding: 16, // p-4
349
+ marginBottom: 16,
350
+ },
351
+ ussdTitle: {
352
+ fontSize: 14, // text-sm
353
+ color: "#1E3A8A", // text-indigo-900
354
+ fontWeight: "500", // font-medium
355
+ marginBottom: 12, // mb-3
356
+ },
357
+ ussdCodeContainer: {
358
+ backgroundColor: "white", // bg-white
359
+ borderRadius: 12, // rounded-xl
360
+ padding: 12, // p-4
361
+ marginBottom: 12, // mb-3
362
+ },
363
+ ussdCodeRow: {
364
+ flexDirection: "row",
365
+ justifyContent: "space-between",
366
+ alignItems: "center",
367
+ },
368
+ ussdCodeText: {
369
+ fontFamily: "monospace", // font-mono
370
+ fontSize: 16, // text-base
371
+ fontWeight: "700", // font-bold
372
+ color: "#111827", // text-gray-900
373
+ flex: 1,
374
+ },
375
+ ussdCopyBtn: {
376
+ padding: 8, // p-2
377
+ },
378
+ ussdStepsLabel: {
379
+ fontSize: 14, // text-sm
380
+ color: "#1E3A8A", // text-indigo-900
381
+ fontWeight: "600", // font-semibold
382
+ marginBottom: 8, // mb-2
383
+ },
384
+ ussdStepsText: {
385
+ fontSize: 14, // text-sm
386
+ color: "#1E40AF", // text-indigo-800
387
+ },
388
+ payButton: {
389
+ display: "flex",
390
+ flexDirection: "row",
391
+ justifyContent: "center",
392
+ gap: 8,
393
+ width: "100%",
394
+ paddingVertical: 16, // py-4
395
+ borderRadius: 12, // rounded-xl
396
+ marginTop: 8, // mt-2
397
+ alignItems: "center",
398
+ },
399
+ payButtonActive: {
400
+ backgroundColor: "#4F46E5", // bg-indigo-600
401
+ },
402
+ payButtonDisabled: {
403
+ backgroundColor: "#D1D5DB", // bg-gray-300
404
+ },
405
+ payButtonText: {
406
+ color: "white",
407
+ fontWeight: "600",
408
+ fontSize: 18, // text-lg
409
+ textAlign: "center",
410
+ },
411
+ footer: {
412
+ flexDirection: "row",
413
+ justifyContent: "center",
414
+ alignItems: "center",
415
+ marginTop: 8, // mt-2
416
+ gap: 8, // supported in RN 0.71+, acts like Tailwind gap-2
417
+ },
418
+ footerText: {
419
+ fontSize: 14, // text-sm
420
+ color: "#6B7280", // text-gray-500
421
+ },
422
+ });