fairsure-checkout-sdk 1.0.8 → 1.0.10

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.
@@ -8,6 +8,8 @@ type CheckoutProps = {
8
8
  merchantName?: string;
9
9
  onClose: () => void;
10
10
  onSuccess?: (reference: string) => void;
11
+ onPending?: (result: any) => void;
12
+ onError?: (error: any) => void;
11
13
  };
12
- export default function Checkout({ requestId, customerEmail, customerName, customerPhone, amount, merchantName, onClose, onSuccess, }: CheckoutProps): import("react").JSX.Element;
14
+ export default function Checkout({ requestId, customerEmail, customerName, customerPhone, amount, merchantName, onClose, onSuccess, onPending, onError, }: CheckoutProps): import("react").JSX.Element;
13
15
  export {};
@@ -10,10 +10,16 @@ const paymentMethods = [
10
10
  { id: "transfer", name: "Transfer", icon: "business-outline" },
11
11
  { id: "ussd", name: "USSD", icon: "phone-portrait-outline" },
12
12
  ];
13
- export default function Checkout({ requestId, customerEmail, customerName, customerPhone, amount, merchantName = "Merchant", onClose, onSuccess, }) {
13
+ export default function Checkout({ requestId, customerEmail, customerName, customerPhone, amount, merchantName = "Merchant", onClose, onSuccess, onPending, onError, }) {
14
14
  const checkout = usePaymentCheckout(amount, requestId, customerEmail, customerName, customerPhone, (reference) => {
15
15
  onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(reference);
16
16
  handleClose();
17
+ }, (result) => {
18
+ onPending === null || onPending === void 0 ? void 0 : onPending(result);
19
+ handleClose();
20
+ }, (error) => {
21
+ onError === null || onError === void 0 ? void 0 : onError(error);
22
+ handleClose();
17
23
  });
18
24
  const handleClose = () => {
19
25
  checkout.resetForm();
@@ -93,9 +99,11 @@ export default function Checkout({ requestId, customerEmail, customerName, custo
93
99
  <Text style={styles.payButtonText}>{getButtonText()}</Text>
94
100
  {checkout.loading && (<ActivityIndicator size="small" color="white"/>)}
95
101
  </TouchableOpacity>
96
- {!checkout.loading && checkout.timeLeft <= 0 && (<TouchableOpacity>
97
- <Text>Resend</Text>
98
- </TouchableOpacity>)}
102
+ {/* {!checkout.loading && checkout.timeLeft <= 0 && (
103
+ <TouchableOpacity>
104
+ <Text>Resend</Text>
105
+ </TouchableOpacity>
106
+ )} */}
99
107
 
100
108
  {/* Footer */}
101
109
  <View style={styles.footer}>
@@ -1,7 +1,6 @@
1
1
  import { Ionicons } from "@expo/vector-icons";
2
2
  import { ActivityIndicator, ScrollView, StyleSheet, Text, TouchableOpacity, View, } from "react-native";
3
3
  export default function USSDPayment({ selectedBank, setSelectedBank, showBankDropdown, ussString, setShowBankDropdown, ussdBanks, loading, copied, handleCopy, }) {
4
- // console.log("USSSSSS", ussdBanks);
5
4
  return (<View>
6
5
  <View style={styles.inputGroup}>
7
6
  <Text style={styles.inputLabel}>Select Your Bank</Text>
@@ -12,6 +11,18 @@ export default function USSDPayment({ selectedBank, setSelectedBank, showBankDro
12
11
  <Ionicons name="chevron-down" size={20} color="#9CA3AF"/>
13
12
  </TouchableOpacity>
14
13
 
14
+ {!showBankDropdown && !selectedBank && (<View style={styles.instructionContainer}>
15
+ <Text style={styles.instructionTitle}>How to pay with USSD</Text>
16
+
17
+ <Text style={styles.instructionText}>
18
+ 1. Select your bank{"\n"}
19
+ 2. Dial the generated USSD code{"\n"}
20
+ 3. Follow the prompts on your phone{"\n"}
21
+ 4. Authorize payment with your PIN{"\n"}
22
+ 5. Click the "Confirm Payment" button.
23
+ </Text>
24
+ </View>)}
25
+
15
26
  {showBankDropdown && (<BankDropdown ussdBanks={ussdBanks} loading={loading} onSelectBank={(bank) => {
16
27
  setSelectedBank(bank);
17
28
  setShowBankDropdown(false);
@@ -51,12 +62,32 @@ function USSDInstructions({ ussdCode, copied, handleCopy, loading, }) {
51
62
  <Text style={styles.ussdStepsText}>
52
63
  1. Dial the USSD code on your phone{"\n"}
53
64
  2. Follow the prompts on your screen{"\n"}
54
- 3. Authorize payment with your bank PIN
65
+ 3. Authorize payment with your bank PIN{"\n"}
66
+ 4. Click the "Confirm Payment" button.
55
67
  </Text>
56
68
  </View>
57
69
  </View>);
58
70
  }
59
71
  const styles = StyleSheet.create({
72
+ instructionContainer: {
73
+ marginTop: 12,
74
+ padding: 16,
75
+ backgroundColor: "#F9FAFB",
76
+ borderRadius: 12,
77
+ borderWidth: 1,
78
+ borderColor: "#E5E7EB",
79
+ },
80
+ instructionTitle: {
81
+ fontSize: 14,
82
+ fontWeight: "600",
83
+ color: "#111827",
84
+ marginBottom: 8,
85
+ },
86
+ instructionText: {
87
+ fontSize: 13,
88
+ lineHeight: 22,
89
+ color: "#6B7280",
90
+ },
60
91
  overlay: {
61
92
  flex: 1,
62
93
  backgroundColor: "rgba(0,0,0,0.5)",
@@ -250,8 +281,9 @@ const styles = StyleSheet.create({
250
281
  },
251
282
  ussdCodeContainer: {
252
283
  backgroundColor: "white", // bg-white
253
- borderRadius: 12, // rounded-xl
254
- padding: 12, // p-4
284
+ borderRadius: 8, // rounded-xl
285
+ paddingHorizontal: 12, // p-4
286
+ paddingTop: 12,
255
287
  marginBottom: 12, // mb-3
256
288
  },
257
289
  ussdCodeRow: {
@@ -277,6 +309,7 @@ const styles = StyleSheet.create({
277
309
  },
278
310
  ussdStepsText: {
279
311
  fontSize: 14, // text-sm
312
+ padding: 4, // px-2
280
313
  color: "#1E40AF", // text-indigo-800
281
314
  },
282
315
  payButton: {
@@ -1,4 +1,4 @@
1
- export declare function usePaymentCheckout(amount: number, requestId: string, customerEmail: string, customerName: string, customerPhone: string, onSuccess?: (reference: string) => void): {
1
+ export declare function usePaymentCheckout(amount: number, requestId: string, customerEmail: string, customerName: string, customerPhone: string, onSuccess?: (reference: string) => void, onPending?: (result: any) => void, onError?: (error: any) => void): {
2
2
  selectedMethod: string;
3
3
  cardNumber: string;
4
4
  expiryDate: string;
@@ -3,7 +3,7 @@ import * as Clipboard from "expo-clipboard";
3
3
  import { useEffect, useState } from "react";
4
4
  import { Dimensions, Platform } from "react-native";
5
5
  const { width, height } = Dimensions.get("window");
6
- export function usePaymentCheckout(amount, requestId, customerEmail, customerName, customerPhone, onSuccess) {
6
+ export function usePaymentCheckout(amount, requestId, customerEmail, customerName, customerPhone, onSuccess, onPending, onError) {
7
7
  const [selectedMethod, setSelectedMethod] = useState("card");
8
8
  const [cardNumber, setCardNumber] = useState("");
9
9
  const [expiryDate, setExpiryDate] = useState("");
@@ -67,7 +67,7 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
67
67
  }
68
68
  }, [selectedMethod]);
69
69
  const fetchTransferDetails = async () => {
70
- var _a, _b;
70
+ var _a;
71
71
  setLoading(true);
72
72
  try {
73
73
  const payload = {
@@ -84,8 +84,7 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
84
84
  "User-Agent": "PostmanRuntime/7.51.0",
85
85
  },
86
86
  });
87
- console.log("RESPONSE", (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data);
88
- setTransferDetail((_b = res === null || res === void 0 ? void 0 : res.data) === null || _b === void 0 ? void 0 : _b.data);
87
+ setTransferDetail((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data);
89
88
  }
90
89
  catch (error) {
91
90
  console.log("FETCH ERROR:", error);
@@ -111,6 +110,7 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
111
110
  "User-Agent": "PostmanRuntime/7.51.0",
112
111
  },
113
112
  });
113
+ console.log("USSD GENERATION RES", JSON.stringify(res.data.data, null, 2));
114
114
  setUssdBankResponse((_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data);
115
115
  }
116
116
  catch (error) {
@@ -121,13 +121,14 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
121
121
  }
122
122
  };
123
123
  const verifyUssd = async () => {
124
+ var _a, _b, _c, _d;
124
125
  try {
125
126
  setLoading(true);
126
127
  const payload = {
127
128
  codeReference: ussdBankResponse === null || ussdBankResponse === void 0 ? void 0 : ussdBankResponse.codeRef,
128
129
  amount: ussdBankResponse === null || ussdBankResponse === void 0 ? void 0 : ussdBankResponse.amount,
129
130
  };
130
- const res = await axios.post("https://api.fairsurepayment.com.ng/api/pub/ussd-status", payload, {
131
+ const res = await axios.post("https://api.fairsurepay.com/api/pub/ussd-status", payload, {
131
132
  headers: {
132
133
  Accept: "application/json",
133
134
  "Content-Type": "application/json",
@@ -135,16 +136,54 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
135
136
  "User-Agent": "PostmanRuntime/7.51.0",
136
137
  },
137
138
  });
138
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(cardDetails.transactionRef);
139
- setLoading(false);
139
+ const result = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data;
140
+ const status = (_c = (_b = result === null || result === void 0 ? void 0 : result.message) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : "";
141
+ if (status.includes("pending")) {
142
+ onPending === null || onPending === void 0 ? void 0 : onPending(result);
143
+ }
144
+ else if (status.includes("success") && (result === null || result === void 0 ? void 0 : result.paid)) {
145
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(result.transactionRef);
146
+ }
147
+ else {
148
+ onError === null || onError === void 0 ? void 0 : onError((_d = result === null || result === void 0 ? void 0 : result.message) !== null && _d !== void 0 ? _d : "Payment could not be verified");
149
+ }
140
150
  }
141
151
  catch (error) {
142
152
  console.log("FETCH ERROR:", error);
153
+ onError === null || onError === void 0 ? void 0 : onError(error);
143
154
  }
144
155
  finally {
145
156
  setLoading(false);
146
157
  }
147
158
  };
159
+ // const verifyUssd = async () => {
160
+ // try {
161
+ // setLoading(true);
162
+ // const payload = {
163
+ // codeReference: ussdBankResponse?.codeRef,
164
+ // amount: ussdBankResponse?.amount,
165
+ // };
166
+ // const res = await axios.post(
167
+ // "https://api.fairsurepay.com/api/pub/ussd-status",
168
+ // payload,
169
+ // {
170
+ // headers: {
171
+ // Accept: "application/json",
172
+ // "Content-Type": "application/json",
173
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
174
+ // "User-Agent": "PostmanRuntime/7.51.0",
175
+ // },
176
+ // },
177
+ // );
178
+ // console.log("USSD PAYMENT RESPONSE", res);
179
+ // onSuccess?.(cardDetails.transactionRef);
180
+ // setLoading(false);
181
+ // } catch (error) {
182
+ // console.log("FETCH ERROR:", error);
183
+ // } finally {
184
+ // setLoading(false);
185
+ // }
186
+ // };
148
187
  useEffect(() => {
149
188
  if (selectedBank) {
150
189
  generateUssdCode();
@@ -302,12 +341,12 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
302
341
  }
303
342
  };
304
343
  const verifyCardPayment = async () => {
344
+ var _a, _b, _c, _d;
305
345
  setLoading(true);
306
346
  try {
307
347
  const payload = {
308
348
  transactionId: cardDetails === null || cardDetails === void 0 ? void 0 : cardDetails.transactionRef,
309
349
  paymentId: cardDetails === null || cardDetails === void 0 ? void 0 : cardDetails.paymentId,
310
- // eciFlag: "07",
311
350
  otp: otp,
312
351
  customerName,
313
352
  customerPhone,
@@ -321,17 +360,85 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
321
360
  "User-Agent": "PostmanRuntime/7.36.0",
322
361
  },
323
362
  });
324
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(transferDetail.transactionReference);
325
- setLoading(false);
363
+ const result = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data;
364
+ const status = (_c = (_b = result === null || result === void 0 ? void 0 : result.message) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : "";
365
+ if (status.includes("pending")) {
366
+ onPending === null || onPending === void 0 ? void 0 : onPending(result);
367
+ }
368
+ else if (status.includes("success") || (result === null || result === void 0 ? void 0 : result.paid)) {
369
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(cardDetails.transactionRef);
370
+ }
371
+ else {
372
+ onError === null || onError === void 0 ? void 0 : onError((_d = result === null || result === void 0 ? void 0 : result.message) !== null && _d !== void 0 ? _d : "Card payment could not be verified");
373
+ }
326
374
  return res === null || res === void 0 ? void 0 : res.data;
327
375
  }
328
376
  catch (error) {
329
- setLoading(false);
330
377
  console.log("ERROR", error);
378
+ onError === null || onError === void 0 ? void 0 : onError(error);
379
+ }
380
+ finally {
381
+ setLoading(false);
331
382
  }
332
383
  };
384
+ // const verifyCardPayment = async () => {
385
+ // setLoading(true);
386
+ // try {
387
+ // const payload = {
388
+ // transactionId: cardDetails?.transactionRef,
389
+ // paymentId: cardDetails?.paymentId,
390
+ // // eciFlag: "07",
391
+ // otp: otp,
392
+ // customerName,
393
+ // customerPhone,
394
+ // customerEmail,
395
+ // };
396
+ // const res = await axios.post(
397
+ // "https://api.fairsurepay.com/api/pub/submit-otp",
398
+ // payload,
399
+ // {
400
+ // headers: {
401
+ // Accept: "application/json",
402
+ // "Content-Type": "application/json",
403
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
404
+ // "User-Agent": "PostmanRuntime/7.36.0",
405
+ // },
406
+ // },
407
+ // );
408
+ // onSuccess?.(transferDetail.transactionReference);
409
+ // setLoading(false);
410
+ // return res?.data;
411
+ // } catch (error) {
412
+ // setLoading(false);
413
+ // console.log("ERROR", error);
414
+ // }
415
+ // };
416
+ // const verifyTransfer = async () => {
417
+ // setLoading(true);
418
+ // try {
419
+ // const res = await axios.get(
420
+ // `https://api.fairsurepay.com/api/pub/transfer-status?transactionReference=${transferDetail?.transactionReference}`,
421
+ // {
422
+ // timeout: 15000,
423
+ // headers: {
424
+ // Accept: "application/json",
425
+ // "Content-Type": "application/json",
426
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
427
+ // "User-Agent": "PostmanRuntime/7.36.0",
428
+ // },
429
+ // },
430
+ // );
431
+ // console.log("RESPONSE", res);
432
+ // onSuccess?.(transferDetail.transactionReference);
433
+ // return res?.data;
434
+ // } catch (error: any) {
435
+ // console.log("Failed to Verify transfer", error.response?.data);
436
+ // } finally {
437
+ // setLoading(false);
438
+ // }
439
+ // };
333
440
  const verifyTransfer = async () => {
334
- var _a;
441
+ var _a, _b, _c, _d, _e;
335
442
  setLoading(true);
336
443
  try {
337
444
  const res = await axios.get(`https://api.fairsurepay.com/api/pub/transfer-status?transactionReference=${transferDetail === null || transferDetail === void 0 ? void 0 : transferDetail.transactionReference}`, {
@@ -343,11 +450,22 @@ export function usePaymentCheckout(amount, requestId, customerEmail, customerNam
343
450
  "User-Agent": "PostmanRuntime/7.36.0",
344
451
  },
345
452
  });
346
- onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(transferDetail.transactionReference);
453
+ const result = (_a = res === null || res === void 0 ? void 0 : res.data) === null || _a === void 0 ? void 0 : _a.data;
454
+ const status = (_c = (_b = result === null || result === void 0 ? void 0 : result.message) === null || _b === void 0 ? void 0 : _b.toLowerCase()) !== null && _c !== void 0 ? _c : "";
455
+ if (status.includes("pending")) {
456
+ onPending === null || onPending === void 0 ? void 0 : onPending(result);
457
+ }
458
+ else if (status.includes("success") || (result === null || result === void 0 ? void 0 : result.paid)) {
459
+ onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(transferDetail.transactionReference);
460
+ }
461
+ else {
462
+ onError === null || onError === void 0 ? void 0 : onError((_d = result === null || result === void 0 ? void 0 : result.message) !== null && _d !== void 0 ? _d : "Transfer could not be verified");
463
+ }
347
464
  return res === null || res === void 0 ? void 0 : res.data;
348
465
  }
349
466
  catch (error) {
350
- console.log("Failed to Verify transfer", (_a = error.response) === null || _a === void 0 ? void 0 : _a.data);
467
+ console.log("Failed to Verify transfer", (_e = error.response) === null || _e === void 0 ? void 0 : _e.data);
468
+ onError === null || onError === void 0 ? void 0 : onError(error);
351
469
  }
352
470
  finally {
353
471
  setLoading(false);
@@ -10,7 +10,7 @@ export function CheckoutProvider({ children }) {
10
10
  return (<CheckoutContext.Provider value={{ openCheckout }}>
11
11
  {children}
12
12
 
13
- {config && (<Checkout amount={config.amount} merchantName={config.merchantName} onSuccess={config.onSuccess} onClose={closeCheckout} requestId={config.requestId} customerEmail={config.customerEmail} customerName={config.customerName} customerPhone={config.customerPhone}/>)}
13
+ {config && (<Checkout amount={config.amount} merchantName={config.merchantName} onSuccess={config.onSuccess} onPending={config.onPending} onError={config.onError} onClose={closeCheckout} requestId={config.requestId} customerEmail={config.customerEmail} customerName={config.customerName} customerPhone={config.customerPhone}/>)}
14
14
  </CheckoutContext.Provider>);
15
15
  }
16
16
  export const useCheckoutContext = () => useContext(CheckoutContext);
package/dist/types.d.ts CHANGED
@@ -2,6 +2,8 @@ export interface CheckoutConfig {
2
2
  amount: number;
3
3
  merchantName?: string;
4
4
  onSuccess?: (reference: string) => void;
5
+ onPending?: (result: any) => void;
6
+ onError?: (error: any) => void;
5
7
  requestId: string;
6
8
  customerEmail: string;
7
9
  customerName: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fairsure-checkout-sdk",
3
- "version": "1.0.8",
3
+ "version": "1.0.10",
4
4
  "main": "dist/index.js",
5
5
  "types": "dist/index.d.ts",
6
6
  "files": [
@@ -24,6 +24,8 @@ type CheckoutProps = {
24
24
  merchantName?: string;
25
25
  onClose: () => void;
26
26
  onSuccess?: (reference: string) => void;
27
+ onPending?: (result: any) => void;
28
+ onError?: (error: any) => void;
27
29
  };
28
30
 
29
31
  const paymentMethods = [
@@ -41,6 +43,8 @@ export default function Checkout({
41
43
  merchantName = "Merchant",
42
44
  onClose,
43
45
  onSuccess,
46
+ onPending,
47
+ onError,
44
48
  }: CheckoutProps) {
45
49
  const checkout = usePaymentCheckout(
46
50
  amount,
@@ -52,6 +56,14 @@ export default function Checkout({
52
56
  onSuccess?.(reference);
53
57
  handleClose();
54
58
  },
59
+ (result) => {
60
+ onPending?.(result);
61
+ handleClose();
62
+ },
63
+ (error) => {
64
+ onError?.(error);
65
+ handleClose();
66
+ },
55
67
  );
56
68
 
57
69
  const handleClose = () => {
@@ -194,11 +206,11 @@ export default function Checkout({
194
206
  <ActivityIndicator size="small" color="white" />
195
207
  )}
196
208
  </TouchableOpacity>
197
- {!checkout.loading && checkout.timeLeft <= 0 && (
209
+ {/* {!checkout.loading && checkout.timeLeft <= 0 && (
198
210
  <TouchableOpacity>
199
211
  <Text>Resend</Text>
200
212
  </TouchableOpacity>
201
- )}
213
+ )} */}
202
214
 
203
215
  {/* Footer */}
204
216
  <View style={styles.footer}>
@@ -36,8 +36,6 @@ export default function USSDPayment({
36
36
  copied,
37
37
  handleCopy,
38
38
  }: USSDPaymentProps) {
39
- // console.log("USSSSSS", ussdBanks);
40
-
41
39
  return (
42
40
  <View>
43
41
  <View style={styles.inputGroup}>
@@ -56,6 +54,20 @@ export default function USSDPayment({
56
54
  <Ionicons name="chevron-down" size={20} color="#9CA3AF" />
57
55
  </TouchableOpacity>
58
56
 
57
+ {!showBankDropdown && !selectedBank && (
58
+ <View style={styles.instructionContainer}>
59
+ <Text style={styles.instructionTitle}>How to pay with USSD</Text>
60
+
61
+ <Text style={styles.instructionText}>
62
+ 1. Select your bank{"\n"}
63
+ 2. Dial the generated USSD code{"\n"}
64
+ 3. Follow the prompts on your phone{"\n"}
65
+ 4. Authorize payment with your PIN{"\n"}
66
+ 5. Click the "Confirm Payment" button.
67
+ </Text>
68
+ </View>
69
+ )}
70
+
59
71
  {showBankDropdown && (
60
72
  <BankDropdown
61
73
  ussdBanks={ussdBanks}
@@ -153,13 +165,35 @@ function USSDInstructions({
153
165
  <Text style={styles.ussdStepsText}>
154
166
  1. Dial the USSD code on your phone{"\n"}
155
167
  2. Follow the prompts on your screen{"\n"}
156
- 3. Authorize payment with your bank PIN
168
+ 3. Authorize payment with your bank PIN{"\n"}
169
+ 4. Click the "Confirm Payment" button.
157
170
  </Text>
158
171
  </View>
159
172
  </View>
160
173
  );
161
174
  }
162
175
  const styles = StyleSheet.create({
176
+ instructionContainer: {
177
+ marginTop: 12,
178
+ padding: 16,
179
+ backgroundColor: "#F9FAFB",
180
+ borderRadius: 12,
181
+ borderWidth: 1,
182
+ borderColor: "#E5E7EB",
183
+ },
184
+
185
+ instructionTitle: {
186
+ fontSize: 14,
187
+ fontWeight: "600",
188
+ color: "#111827",
189
+ marginBottom: 8,
190
+ },
191
+
192
+ instructionText: {
193
+ fontSize: 13,
194
+ lineHeight: 22,
195
+ color: "#6B7280",
196
+ },
163
197
  overlay: {
164
198
  flex: 1,
165
199
  backgroundColor: "rgba(0,0,0,0.5)",
@@ -356,8 +390,9 @@ const styles = StyleSheet.create({
356
390
  },
357
391
  ussdCodeContainer: {
358
392
  backgroundColor: "white", // bg-white
359
- borderRadius: 12, // rounded-xl
360
- padding: 12, // p-4
393
+ borderRadius: 8, // rounded-xl
394
+ paddingHorizontal: 12, // p-4
395
+ paddingTop: 12,
361
396
  marginBottom: 12, // mb-3
362
397
  },
363
398
  ussdCodeRow: {
@@ -383,6 +418,7 @@ const styles = StyleSheet.create({
383
418
  },
384
419
  ussdStepsText: {
385
420
  fontSize: 14, // text-sm
421
+ padding: 4, // px-2
386
422
  color: "#1E40AF", // text-indigo-800
387
423
  },
388
424
  payButton: {
@@ -12,6 +12,8 @@ export function usePaymentCheckout(
12
12
  customerName: string,
13
13
  customerPhone: string,
14
14
  onSuccess?: (reference: string) => void,
15
+ onPending?: (result: any) => void,
16
+ onError?: (error: any) => void,
15
17
  ) {
16
18
  const [selectedMethod, setSelectedMethod] = useState("card");
17
19
  const [cardNumber, setCardNumber] = useState("");
@@ -104,8 +106,6 @@ export function usePaymentCheckout(
104
106
  },
105
107
  },
106
108
  );
107
- console.log("RESPONSE", res?.data?.data);
108
-
109
109
  setTransferDetail(res?.data?.data);
110
110
  } catch (error) {
111
111
  console.log("FETCH ERROR:", error);
@@ -135,6 +135,11 @@ export function usePaymentCheckout(
135
135
  },
136
136
  },
137
137
  );
138
+ console.log(
139
+ "USSD GENERATION RES",
140
+ JSON.stringify(res.data.data, null, 2),
141
+ );
142
+
138
143
  setUssdBankResponse(res?.data?.data);
139
144
  } catch (error) {
140
145
  console.log("FETCH ERROR:", error);
@@ -151,7 +156,7 @@ export function usePaymentCheckout(
151
156
  amount: ussdBankResponse?.amount,
152
157
  };
153
158
  const res = await axios.post(
154
- "https://api.fairsurepayment.com.ng/api/pub/ussd-status",
159
+ "https://api.fairsurepay.com/api/pub/ussd-status",
155
160
  payload,
156
161
  {
157
162
  headers: {
@@ -162,15 +167,54 @@ export function usePaymentCheckout(
162
167
  },
163
168
  },
164
169
  );
165
- onSuccess?.(cardDetails.transactionRef);
166
- setLoading(false);
170
+
171
+ const result = res?.data?.data;
172
+ const status = result?.message?.toLowerCase() ?? "";
173
+ if (status.includes("pending")) {
174
+ onPending?.(result);
175
+ } else if (status.includes("success") && result?.paid) {
176
+ onSuccess?.(result.transactionRef);
177
+ } else {
178
+ onError?.(result?.message ?? "Payment could not be verified");
179
+ }
167
180
  } catch (error) {
168
181
  console.log("FETCH ERROR:", error);
182
+ onError?.(error);
169
183
  } finally {
170
184
  setLoading(false);
171
185
  }
172
186
  };
173
187
 
188
+ // const verifyUssd = async () => {
189
+ // try {
190
+ // setLoading(true);
191
+ // const payload = {
192
+ // codeReference: ussdBankResponse?.codeRef,
193
+ // amount: ussdBankResponse?.amount,
194
+ // };
195
+ // const res = await axios.post(
196
+ // "https://api.fairsurepay.com/api/pub/ussd-status",
197
+ // payload,
198
+ // {
199
+ // headers: {
200
+ // Accept: "application/json",
201
+ // "Content-Type": "application/json",
202
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
203
+ // "User-Agent": "PostmanRuntime/7.51.0",
204
+ // },
205
+ // },
206
+ // );
207
+ // console.log("USSD PAYMENT RESPONSE", res);
208
+
209
+ // onSuccess?.(cardDetails.transactionRef);
210
+ // setLoading(false);
211
+ // } catch (error) {
212
+ // console.log("FETCH ERROR:", error);
213
+ // } finally {
214
+ // setLoading(false);
215
+ // }
216
+ // };
217
+
174
218
  useEffect(() => {
175
219
  if (selectedBank) {
176
220
  generateUssdCode();
@@ -342,13 +386,13 @@ export function usePaymentCheckout(
342
386
  setLoading(false);
343
387
  }
344
388
  };
389
+
345
390
  const verifyCardPayment = async () => {
346
391
  setLoading(true);
347
392
  try {
348
393
  const payload = {
349
394
  transactionId: cardDetails?.transactionRef,
350
395
  paymentId: cardDetails?.paymentId,
351
- // eciFlag: "07",
352
396
  otp: otp,
353
397
  customerName,
354
398
  customerPhone,
@@ -366,14 +410,83 @@ export function usePaymentCheckout(
366
410
  },
367
411
  },
368
412
  );
369
- onSuccess?.(transferDetail.transactionReference);
370
- setLoading(false);
413
+
414
+ const result = res?.data?.data;
415
+ const status = result?.message?.toLowerCase() ?? "";
416
+
417
+ if (status.includes("pending")) {
418
+ onPending?.(result);
419
+ } else if (status.includes("success") || result?.paid) {
420
+ onSuccess?.(cardDetails.transactionRef);
421
+ } else {
422
+ onError?.(result?.message ?? "Card payment could not be verified");
423
+ }
371
424
  return res?.data;
372
425
  } catch (error) {
373
- setLoading(false);
374
426
  console.log("ERROR", error);
427
+ onError?.(error);
428
+ } finally {
429
+ setLoading(false);
375
430
  }
376
431
  };
432
+ // const verifyCardPayment = async () => {
433
+ // setLoading(true);
434
+ // try {
435
+ // const payload = {
436
+ // transactionId: cardDetails?.transactionRef,
437
+ // paymentId: cardDetails?.paymentId,
438
+ // // eciFlag: "07",
439
+ // otp: otp,
440
+ // customerName,
441
+ // customerPhone,
442
+ // customerEmail,
443
+ // };
444
+ // const res = await axios.post(
445
+ // "https://api.fairsurepay.com/api/pub/submit-otp",
446
+ // payload,
447
+ // {
448
+ // headers: {
449
+ // Accept: "application/json",
450
+ // "Content-Type": "application/json",
451
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
452
+ // "User-Agent": "PostmanRuntime/7.36.0",
453
+ // },
454
+ // },
455
+ // );
456
+ // onSuccess?.(transferDetail.transactionReference);
457
+ // setLoading(false);
458
+ // return res?.data;
459
+ // } catch (error) {
460
+ // setLoading(false);
461
+ // console.log("ERROR", error);
462
+ // }
463
+ // };
464
+ // const verifyTransfer = async () => {
465
+ // setLoading(true);
466
+ // try {
467
+ // const res = await axios.get(
468
+ // `https://api.fairsurepay.com/api/pub/transfer-status?transactionReference=${transferDetail?.transactionReference}`,
469
+ // {
470
+ // timeout: 15000,
471
+ // headers: {
472
+ // Accept: "application/json",
473
+ // "Content-Type": "application/json",
474
+ // publickey: "LIVE_7AXSCCY8R3HABAN14QP7",
475
+ // "User-Agent": "PostmanRuntime/7.36.0",
476
+ // },
477
+ // },
478
+ // );
479
+ // console.log("RESPONSE", res);
480
+
481
+ // onSuccess?.(transferDetail.transactionReference);
482
+ // return res?.data;
483
+ // } catch (error: any) {
484
+ // console.log("Failed to Verify transfer", error.response?.data);
485
+ // } finally {
486
+ // setLoading(false);
487
+ // }
488
+ // };
489
+
377
490
  const verifyTransfer = async () => {
378
491
  setLoading(true);
379
492
  try {
@@ -389,15 +502,25 @@ export function usePaymentCheckout(
389
502
  },
390
503
  },
391
504
  );
392
- onSuccess?.(transferDetail.transactionReference);
505
+
506
+ const result = res?.data?.data;
507
+ const status = result?.message?.toLowerCase() ?? "";
508
+
509
+ if (status.includes("pending")) {
510
+ onPending?.(result);
511
+ } else if (status.includes("success") || result?.paid) {
512
+ onSuccess?.(transferDetail.transactionReference);
513
+ } else {
514
+ onError?.(result?.message ?? "Transfer could not be verified");
515
+ }
393
516
  return res?.data;
394
517
  } catch (error: any) {
395
518
  console.log("Failed to Verify transfer", error.response?.data);
519
+ onError?.(error);
396
520
  } finally {
397
521
  setLoading(false);
398
522
  }
399
523
  };
400
-
401
524
  const resetForm = () => {
402
525
  setCardNumber("");
403
526
  setExpiryDate("");
@@ -23,6 +23,8 @@ export function CheckoutProvider({ children }: { children: React.ReactNode }) {
23
23
  amount={config.amount}
24
24
  merchantName={config.merchantName}
25
25
  onSuccess={config.onSuccess}
26
+ onPending={config.onPending}
27
+ onError={config.onError}
26
28
  onClose={closeCheckout}
27
29
  requestId={config.requestId}
28
30
  customerEmail={config.customerEmail}
package/src/types.ts CHANGED
@@ -2,6 +2,8 @@ export interface CheckoutConfig {
2
2
  amount: number;
3
3
  merchantName?: string;
4
4
  onSuccess?: (reference: string) => void;
5
+ onPending?: (result: any) => void;
6
+ onError?: (error: any) => void;
5
7
  requestId: string;
6
8
  customerEmail: string;
7
9
  customerName: string;