boxpay-checkout-reactnative-sdk 1.0.11-beta → 1.0.11-beta3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/module/components/checkboxContainer.js +1 -1
- package/lib/module/components/header.js +1 -1
- package/lib/module/components/header.js.map +1 -1
- package/lib/module/components/paymentSelector.js +1 -1
- package/lib/module/components/paymentSelector.js.map +1 -1
- package/lib/module/components/paymentSuccess.js +2 -7
- package/lib/module/components/paymentSuccess.js.map +1 -1
- package/lib/module/components/savedCardComponent.js +1 -1
- package/lib/module/components/savedCardComponent.js.map +1 -1
- package/lib/module/components/subscriptionRow.js +33 -0
- package/lib/module/components/subscriptionRow.js.map +1 -0
- package/lib/module/interface.js +1 -0
- package/lib/module/interface.js.map +1 -1
- package/lib/module/screens/addressScreen.js +11 -60
- package/lib/module/screens/addressScreen.js.map +1 -1
- package/lib/module/screens/cardScreen.js +488 -447
- package/lib/module/screens/cardScreen.js.map +1 -1
- package/lib/module/screens/emiScreen.js +2 -6
- package/lib/module/screens/emiScreen.js.map +1 -1
- package/lib/module/screens/instantOfferList.js +2 -6
- package/lib/module/screens/instantOfferList.js.map +1 -1
- package/lib/module/screens/mainScreen.js +50 -2
- package/lib/module/screens/mainScreen.js.map +1 -1
- package/lib/module/screens/netBankingScreen.js +2 -6
- package/lib/module/screens/netBankingScreen.js.map +1 -1
- package/lib/module/screens/upiScreen.js +2 -6
- package/lib/module/screens/upiScreen.js.map +1 -1
- package/lib/module/screens/walletScreen.js +2 -6
- package/lib/module/screens/walletScreen.js.map +1 -1
- package/lib/module/sdk-version.json +1 -1
- package/lib/module/sharedContext/checkoutDetailsHandler.js +8 -2
- package/lib/module/sharedContext/checkoutDetailsHandler.js.map +1 -1
- package/lib/module/sharedContext/getTextInputTheme.js +15 -0
- package/lib/module/sharedContext/getTextInputTheme.js.map +1 -0
- package/lib/module/styles/indexStyles.js +1 -1
- package/lib/module/styles/indexStyles.js.map +1 -1
- package/lib/module/styles/screens/bnplScreenStyles.js +2 -3
- package/lib/module/styles/screens/bnplScreenStyles.js.map +1 -1
- package/lib/module/styles/screens/cardScreenStyles.js +9 -4
- package/lib/module/styles/screens/cardScreenStyles.js.map +1 -1
- package/lib/module/styles/screens/netBankingScreenStyles.js +2 -3
- package/lib/module/styles/screens/netBankingScreenStyles.js.map +1 -1
- package/lib/module/styles/screens/walletScreenStyles.js +2 -3
- package/lib/module/styles/screens/walletScreenStyles.js.map +1 -1
- package/lib/module/utility.js +16 -0
- package/lib/module/utility.js.map +1 -1
- package/lib/typescript/src/components/subscriptionRow.d.ts +9 -0
- package/lib/typescript/src/components/subscriptionRow.d.ts.map +1 -0
- package/lib/typescript/src/interface.d.ts +26 -2
- package/lib/typescript/src/interface.d.ts.map +1 -1
- package/lib/typescript/src/screens/addressScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/cardScreen.d.ts +1 -1
- package/lib/typescript/src/screens/cardScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/emiScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/instantOfferList.d.ts.map +1 -1
- package/lib/typescript/src/screens/mainScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/netBankingScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/upiScreen.d.ts.map +1 -1
- package/lib/typescript/src/screens/walletScreen.d.ts.map +1 -1
- package/lib/typescript/src/sharedContext/checkoutDetailsHandler.d.ts.map +1 -1
- package/lib/typescript/src/sharedContext/getTextInputTheme.d.ts +7 -0
- package/lib/typescript/src/sharedContext/getTextInputTheme.d.ts.map +1 -0
- package/lib/typescript/src/styles/indexStyles.d.ts +1 -1
- package/lib/typescript/src/styles/screens/bnplScreenStyles.d.ts +1 -2
- package/lib/typescript/src/styles/screens/bnplScreenStyles.d.ts.map +1 -1
- package/lib/typescript/src/styles/screens/cardScreenStyles.d.ts +8 -3
- package/lib/typescript/src/styles/screens/cardScreenStyles.d.ts.map +1 -1
- package/lib/typescript/src/styles/screens/netBankingScreenStyles.d.ts +1 -2
- package/lib/typescript/src/styles/screens/netBankingScreenStyles.d.ts.map +1 -1
- package/lib/typescript/src/styles/screens/walletScreenStyles.d.ts +1 -2
- package/lib/typescript/src/styles/screens/walletScreenStyles.d.ts.map +1 -1
- package/lib/typescript/src/utility.d.ts +2 -0
- package/lib/typescript/src/utility.d.ts.map +1 -1
- package/package.json +2 -2
- package/src/components/checkboxContainer.tsx +1 -1
- package/src/components/header.tsx +1 -1
- package/src/components/paymentSelector.tsx +1 -1
- package/src/components/paymentSuccess.tsx +3 -5
- package/src/components/savedCardComponent.tsx +1 -1
- package/src/components/subscriptionRow.tsx +19 -0
- package/src/interface.ts +24 -2
- package/src/screens/addressScreen.tsx +11 -60
- package/src/screens/cardScreen.tsx +188 -124
- package/src/screens/emiScreen.tsx +2 -6
- package/src/screens/instantOfferList.tsx +2 -6
- package/src/screens/mainScreen.tsx +54 -3
- package/src/screens/netBankingScreen.tsx +2 -6
- package/src/screens/upiScreen.tsx +2 -6
- package/src/screens/walletScreen.tsx +2 -6
- package/src/sdk-version.json +1 -1
- package/src/sharedContext/checkoutDetailsHandler.ts +8 -2
- package/src/sharedContext/getTextInputTheme.ts +12 -0
- package/src/styles/indexStyles.ts +1 -1
- package/src/styles/screens/bnplScreenStyles.ts +2 -3
- package/src/styles/screens/cardScreenStyles.ts +3 -4
- package/src/styles/screens/netBankingScreenStyles.ts +2 -3
- package/src/styles/screens/walletScreenStyles.ts +2 -3
- package/src/utility.ts +24 -1
|
@@ -1,38 +1,43 @@
|
|
|
1
|
+
import type { NavigationProp, RouteProp } from '@react-navigation/native';
|
|
2
|
+
import LottieView from 'lottie-react-native';
|
|
3
|
+
import { useEffect, useRef, useState } from 'react';
|
|
1
4
|
import {
|
|
2
|
-
View,
|
|
3
|
-
Text,
|
|
4
|
-
Image,
|
|
5
5
|
BackHandler,
|
|
6
|
+
Image,
|
|
7
|
+
InputAccessoryView,
|
|
8
|
+
Keyboard,
|
|
9
|
+
Platform,
|
|
6
10
|
Pressable,
|
|
11
|
+
ScrollView,
|
|
12
|
+
Text,
|
|
7
13
|
TouchableOpacity,
|
|
8
|
-
|
|
14
|
+
View
|
|
9
15
|
} from 'react-native';
|
|
10
|
-
import { useEffect, useRef, useState } from 'react';
|
|
11
|
-
import Header from '../components/header';
|
|
12
|
-
import type { RouteProp, NavigationProp } from '@react-navigation/native';
|
|
13
16
|
import { TextInput } from 'react-native-paper';
|
|
14
|
-
import
|
|
15
|
-
import
|
|
16
|
-
import
|
|
17
|
-
import
|
|
17
|
+
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
|
|
18
|
+
import { SvgUri } from 'react-native-svg';
|
|
19
|
+
import Toast from 'react-native-toast-message';
|
|
20
|
+
import CheckBoxContainer from '../components/checkboxContainer';
|
|
21
|
+
import CvvInfoBottomSheet from '../components/cvvInfoBottomSheet';
|
|
22
|
+
import Header from '../components/header';
|
|
23
|
+
import KnowMoreBottomSheet from '../components/knowMoreBottomSheet';
|
|
18
24
|
import PaymentFailed from '../components/paymentFailed';
|
|
19
25
|
import PaymentSuccess from '../components/paymentSuccess';
|
|
20
26
|
import SessionExpire from '../components/sessionExpire';
|
|
21
|
-
import { APIStatus, type
|
|
22
|
-
import {
|
|
23
|
-
import
|
|
24
|
-
import WebViewScreen from './webViewScreen';
|
|
25
|
-
import fetchStatus from '../postRequest/fetchStatus';
|
|
26
|
-
import { SvgUri } from 'react-native-svg';
|
|
27
|
-
import ShimmerPlaceHolder from 'react-native-shimmer-placeholder';
|
|
27
|
+
import { APIStatus, type CardScreenParams, type PaymentResultObject } from '../interface';
|
|
28
|
+
import type { CheckoutStackParamList } from '../navigation';
|
|
29
|
+
import cardPostRequest from '../postRequest/cardPostRequest';
|
|
28
30
|
import emiPostRequest from '../postRequest/emiPostRequest';
|
|
29
|
-
import
|
|
30
|
-
import
|
|
31
|
-
import
|
|
31
|
+
import fetchCardDetails from '../postRequest/fetchCardDetails';
|
|
32
|
+
import fetchStatus from '../postRequest/fetchStatus';
|
|
33
|
+
import { checkoutDetailsHandler, setCheckOutDetailsHandlerToDefault } from '../sharedContext/checkoutDetailsHandler';
|
|
32
34
|
import { handleFetchStatusResponseHandler, handlePaymentResponse } from '../sharedContext/handlePaymentResponseHandler';
|
|
33
|
-
import
|
|
35
|
+
import { paymentHandler } from '../sharedContext/paymentStatusHandler';
|
|
34
36
|
import { setUserDataHandlerToDefault } from '../sharedContext/userdataHandler';
|
|
35
|
-
import
|
|
37
|
+
import styles from '../styles/screens/cardScreenStyles';
|
|
38
|
+
import WebViewScreen from './webViewScreen';
|
|
39
|
+
import SubscriptionRow from '../components/subscriptionRow';
|
|
40
|
+
import { getTextInputTheme } from '../sharedContext/getTextInputTheme';
|
|
36
41
|
|
|
37
42
|
type CardScreenRouteProp = RouteProp<CheckoutStackParamList, 'CardScreen'>;
|
|
38
43
|
|
|
@@ -75,7 +80,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
75
80
|
const [cardNickNameText, setCardNickNameText] = useState<string | null>(null);
|
|
76
81
|
|
|
77
82
|
const [cardSelectedIcon, setCardSelectedIcon] = useState(
|
|
78
|
-
require('../../assets/images/
|
|
83
|
+
require('../../assets/images/ic_card.png')
|
|
79
84
|
);
|
|
80
85
|
const [maxCvvLength, setMaxCvvLength] = useState(4);
|
|
81
86
|
const [maxCardNumberLength, setMaxCardNumberLength] = useState(19);
|
|
@@ -137,6 +142,12 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
137
142
|
const [emiIssuer, setEmiIssuer] = useState('');
|
|
138
143
|
const [shopperToken, setShopperToken] = useState<string | null>(null);
|
|
139
144
|
|
|
145
|
+
const cardNumberAccessoryID = "cardNumberAccessoryID";
|
|
146
|
+
const cardExpiryAccessoryID = "cardExpiryAccessoryID";
|
|
147
|
+
const cardCvvAccessoryID = "cardCvvAccessoryID";
|
|
148
|
+
const cardHolderNameAccessoryID = "cardHolderNameAccessoryID";
|
|
149
|
+
const cardNickNameAccessoryID = "cardNickNameAccessoryID";
|
|
150
|
+
|
|
140
151
|
const handleCardNumberTextChange = async (text: string) => {
|
|
141
152
|
if (text == '') {
|
|
142
153
|
setCardNumberText(text);
|
|
@@ -191,7 +202,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
191
202
|
setMaxCardNumberLength(19);
|
|
192
203
|
} else {
|
|
193
204
|
setCardSelectedIcon(
|
|
194
|
-
require('../../assets/images/
|
|
205
|
+
require('../../assets/images/ic_card.png')
|
|
195
206
|
);
|
|
196
207
|
setMaxCvvLength(3);
|
|
197
208
|
setMaxCardNumberLength(19);
|
|
@@ -214,13 +225,17 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
214
225
|
});
|
|
215
226
|
}
|
|
216
227
|
} else {
|
|
217
|
-
setCardSelectedIcon(require('../../assets/images/
|
|
228
|
+
setCardSelectedIcon(require('../../assets/images/ic_card.png'));
|
|
218
229
|
setMaxCvvLength(3);
|
|
219
230
|
setMaxCardNumberLength(19);
|
|
220
231
|
}
|
|
221
232
|
}
|
|
222
233
|
};
|
|
223
234
|
|
|
235
|
+
const isSubscriptionDetailsVisible =
|
|
236
|
+
checkoutDetails.isSubscriptionCheckout &&
|
|
237
|
+
(isSICheckBoxClicked || !checkoutDetails.isSICheckboxVisible);
|
|
238
|
+
|
|
224
239
|
const isValidCardNumberByLuhn = (stringInputCardNumber: string): boolean => {
|
|
225
240
|
const minCardLength = 13;
|
|
226
241
|
|
|
@@ -254,7 +269,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
254
269
|
const cleanedLength = maxCardNumberLength == 19 ? 16 : 15;
|
|
255
270
|
setCardNumberErrorText(
|
|
256
271
|
cleaned.length < 1
|
|
257
|
-
? '
|
|
272
|
+
? 'Card Number is required'
|
|
258
273
|
: checkoutDetails.env === 'test'
|
|
259
274
|
? ''
|
|
260
275
|
: cleaned.length < cleanedLength
|
|
@@ -377,7 +392,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
377
392
|
const cleaned = cardExpiryText?.replace(/ /g, '') || '';
|
|
378
393
|
setCardExpiryErrorText(
|
|
379
394
|
cleaned.length < 1
|
|
380
|
-
? '
|
|
395
|
+
? 'Expiry is required'
|
|
381
396
|
: cleaned.length < 5 || !cardExpiryValid
|
|
382
397
|
? 'Expiry is invalid'
|
|
383
398
|
: ''
|
|
@@ -390,7 +405,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
390
405
|
const cleaned = cardCvvText?.replace(/ /g, '') || '';
|
|
391
406
|
setCardCvvErrorText(
|
|
392
407
|
cleaned.length < 1
|
|
393
|
-
? '
|
|
408
|
+
? 'CVV is required'
|
|
394
409
|
: cleaned.length < maxCvvLength
|
|
395
410
|
? 'CVV is invalid'
|
|
396
411
|
: ''
|
|
@@ -401,7 +416,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
401
416
|
|
|
402
417
|
const handleCardHolderNameBlur = () => {
|
|
403
418
|
const cleaned = cardHolderNameText?.replace(/ /g, '') || '';
|
|
404
|
-
setCardHolderNameErrorText(cleaned.length < 1 ? '
|
|
419
|
+
setCardHolderNameErrorText(cleaned.length < 1 ? 'Name is required' : '');
|
|
405
420
|
setCardHolderNameFocused(false);
|
|
406
421
|
setCardHolderNameError(cleaned.length < 1);
|
|
407
422
|
};
|
|
@@ -409,7 +424,7 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
409
424
|
const handleCardCvvTextChange = (text: string) => {
|
|
410
425
|
setCardCvvText(text);
|
|
411
426
|
if (text == '') {
|
|
412
|
-
setCardCvvErrorText('
|
|
427
|
+
setCardCvvErrorText('CVV is required');
|
|
413
428
|
setCardCvvError(true);
|
|
414
429
|
} else {
|
|
415
430
|
setCardCvvError(false);
|
|
@@ -582,7 +597,8 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
582
597
|
}, [paymentHtml]);
|
|
583
598
|
|
|
584
599
|
return (
|
|
585
|
-
|
|
600
|
+
<>
|
|
601
|
+
<View style={styles.screenView}>
|
|
586
602
|
{loading ? (
|
|
587
603
|
<View
|
|
588
604
|
style={styles.loadingContainer}
|
|
@@ -685,21 +701,18 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
685
701
|
fontFamily: checkoutDetails.fontFamily.regular,
|
|
686
702
|
}]}
|
|
687
703
|
>
|
|
688
|
-
Card Number
|
|
704
|
+
Card Number*
|
|
689
705
|
</Text>
|
|
690
706
|
}
|
|
691
707
|
value={cardNumberText || ''}
|
|
692
708
|
onChangeText={(it) => {
|
|
693
709
|
handleCardNumberTextChange(it);
|
|
694
710
|
}}
|
|
695
|
-
theme={
|
|
696
|
-
|
|
697
|
-
primary: '#2D2B32',
|
|
698
|
-
outline: '#E6E6E6',
|
|
699
|
-
},
|
|
700
|
-
}}
|
|
711
|
+
theme={getTextInputTheme()}
|
|
712
|
+
inputAccessoryViewID={Platform.OS === 'ios' ? cardNumberAccessoryID : undefined}
|
|
701
713
|
style={[styles.textInput, { marginTop: 28, marginHorizontal: 16, fontFamily: checkoutDetails.fontFamily.regular, }]}
|
|
702
714
|
error={cardNumberError}
|
|
715
|
+
returnKeyType="done"
|
|
703
716
|
right={
|
|
704
717
|
cardNumberError ? (
|
|
705
718
|
<TextInput.Icon
|
|
@@ -715,7 +728,10 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
715
728
|
icon={() => (
|
|
716
729
|
<Image
|
|
717
730
|
source={cardSelectedIcon}
|
|
718
|
-
style={{ width:
|
|
731
|
+
style={{ width: 32, height: 20,tintColor:
|
|
732
|
+
cardSelectedIcon === require('../../assets/images/ic_card.png')
|
|
733
|
+
? '#6B7280' // Cool Grey 500
|
|
734
|
+
: undefined, }}
|
|
719
735
|
/>
|
|
720
736
|
)}
|
|
721
737
|
/>
|
|
@@ -735,11 +751,65 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
735
751
|
/>
|
|
736
752
|
{cardNumberError && (
|
|
737
753
|
<Text
|
|
738
|
-
style={[styles.errorText, { fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
754
|
+
style={[styles.errorText, { fontFamily: checkoutDetails.fontFamily.regular,marginHorizontal : 16}]}
|
|
739
755
|
>
|
|
740
756
|
{cardNumberErrorText}
|
|
741
757
|
</Text>
|
|
742
758
|
)}
|
|
759
|
+
<TextInput
|
|
760
|
+
mode="outlined"
|
|
761
|
+
label={
|
|
762
|
+
<Text
|
|
763
|
+
style={[styles.textFieldLabel,{
|
|
764
|
+
color: cardHolderNameFocused
|
|
765
|
+
? '#2D2B32'
|
|
766
|
+
: cardHolderNameText != '' && cardHolderNameText != null
|
|
767
|
+
? '#2D2B32'
|
|
768
|
+
: '#ADACB0',
|
|
769
|
+
fontFamily: checkoutDetails.fontFamily.regular,
|
|
770
|
+
}]}
|
|
771
|
+
>
|
|
772
|
+
Cardholder Name*
|
|
773
|
+
</Text>
|
|
774
|
+
}
|
|
775
|
+
value={cardHolderNameText || ''}
|
|
776
|
+
onChangeText={(it) => {
|
|
777
|
+
handleCardHolderNameTextChange(it);
|
|
778
|
+
}}
|
|
779
|
+
theme={getTextInputTheme()}
|
|
780
|
+
style={[styles.textInput, { marginHorizontal: 16, marginTop: 16, fontFamily: checkoutDetails.fontFamily.regular, }]}
|
|
781
|
+
error={cardHolderNameError}
|
|
782
|
+
inputAccessoryViewID={Platform.OS === 'ios' ? cardHolderNameAccessoryID : undefined}
|
|
783
|
+
returnKeyType="done"
|
|
784
|
+
right={
|
|
785
|
+
cardHolderNameError ? (
|
|
786
|
+
<TextInput.Icon
|
|
787
|
+
icon={() => (
|
|
788
|
+
<Image
|
|
789
|
+
source={require('../../assets/images/ic_upi_error.png')}
|
|
790
|
+
style={{ width: 24, height: 24 }}
|
|
791
|
+
/>
|
|
792
|
+
)}
|
|
793
|
+
/>
|
|
794
|
+
) : null
|
|
795
|
+
}
|
|
796
|
+
outlineStyle={{
|
|
797
|
+
borderRadius: 8, // Add this
|
|
798
|
+
borderWidth: 1.5,
|
|
799
|
+
}}
|
|
800
|
+
onBlur={handleCardHolderNameBlur}
|
|
801
|
+
onFocus={() => {
|
|
802
|
+
setCardHolderNameFocused(true);
|
|
803
|
+
setCardHolderNameError(false);
|
|
804
|
+
}}
|
|
805
|
+
/>
|
|
806
|
+
{cardHolderNameError && (
|
|
807
|
+
<Text
|
|
808
|
+
style={[styles.errorText, { fontFamily: checkoutDetails.fontFamily.regular,marginHorizontal : 16}]}
|
|
809
|
+
>
|
|
810
|
+
{cardHolderNameErrorText}
|
|
811
|
+
</Text>
|
|
812
|
+
)}
|
|
743
813
|
<View
|
|
744
814
|
style={styles.expiryCvvContainer}
|
|
745
815
|
>
|
|
@@ -757,21 +827,18 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
757
827
|
fontFamily: checkoutDetails.fontFamily.regular,
|
|
758
828
|
}]}
|
|
759
829
|
>
|
|
760
|
-
Expiry (MM/YY)
|
|
830
|
+
Expiry (MM/YY)*
|
|
761
831
|
</Text>
|
|
762
832
|
}
|
|
763
833
|
value={cardExpiryText || ''}
|
|
764
834
|
onChangeText={(it) => {
|
|
765
835
|
handleCardExpiryTextChange(it);
|
|
766
836
|
}}
|
|
767
|
-
theme={
|
|
768
|
-
|
|
769
|
-
primary: '#2D2B32',
|
|
770
|
-
outline: '#E6E6E6',
|
|
771
|
-
},
|
|
772
|
-
}}
|
|
837
|
+
theme={getTextInputTheme()}
|
|
838
|
+
inputAccessoryViewID={Platform.OS === 'ios' ? cardExpiryAccessoryID : undefined}
|
|
773
839
|
style={[styles.textInput, {fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
774
840
|
error={cardExpiryError}
|
|
841
|
+
returnKeyType="done"
|
|
775
842
|
right={
|
|
776
843
|
cardExpiryError ? (
|
|
777
844
|
<TextInput.Icon
|
|
@@ -818,21 +885,18 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
818
885
|
fontFamily: checkoutDetails.fontFamily.regular,
|
|
819
886
|
}]}
|
|
820
887
|
>
|
|
821
|
-
CVV
|
|
888
|
+
CVV*
|
|
822
889
|
</Text>
|
|
823
890
|
}
|
|
824
891
|
value={cardCvvText || ''}
|
|
825
892
|
onChangeText={(it) => {
|
|
826
893
|
handleCardCvvTextChange(it);
|
|
827
894
|
}}
|
|
828
|
-
theme={
|
|
829
|
-
|
|
830
|
-
primary: '#2D2B32',
|
|
831
|
-
outline: '#E6E6E6',
|
|
832
|
-
},
|
|
833
|
-
}}
|
|
895
|
+
theme={getTextInputTheme()}
|
|
896
|
+
inputAccessoryViewID={Platform.OS === 'ios' ? cardCvvAccessoryID : undefined}
|
|
834
897
|
style={[styles.textInput, {fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
835
898
|
error={cardCvvError}
|
|
899
|
+
returnKeyType="done"
|
|
836
900
|
right={
|
|
837
901
|
cardCvvError ? (
|
|
838
902
|
<TextInput.Icon
|
|
@@ -847,8 +911,8 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
847
911
|
<TextInput.Icon
|
|
848
912
|
icon={() => (
|
|
849
913
|
<Image
|
|
850
|
-
source={require('../../assets/images/
|
|
851
|
-
style={{ width: 24, height: 24 }}
|
|
914
|
+
source={require('../../assets/images/ic_info.png')}
|
|
915
|
+
style={{ width: 24, height: 24, tintColor : checkoutDetails.buttonColor }}
|
|
852
916
|
/>
|
|
853
917
|
)}
|
|
854
918
|
onPress={() => {
|
|
@@ -879,63 +943,6 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
879
943
|
)}
|
|
880
944
|
</View>
|
|
881
945
|
</View>
|
|
882
|
-
<TextInput
|
|
883
|
-
mode="outlined"
|
|
884
|
-
label={
|
|
885
|
-
<Text
|
|
886
|
-
style={[styles.textFieldLabel,{
|
|
887
|
-
color: cardHolderNameFocused
|
|
888
|
-
? '#2D2B32'
|
|
889
|
-
: cardHolderNameText != '' && cardHolderNameText != null
|
|
890
|
-
? '#2D2B32'
|
|
891
|
-
: '#ADACB0',
|
|
892
|
-
fontFamily: checkoutDetails.fontFamily.regular,
|
|
893
|
-
}]}
|
|
894
|
-
>
|
|
895
|
-
Name on the Card
|
|
896
|
-
</Text>
|
|
897
|
-
}
|
|
898
|
-
value={cardHolderNameText || ''}
|
|
899
|
-
onChangeText={(it) => {
|
|
900
|
-
handleCardHolderNameTextChange(it);
|
|
901
|
-
}}
|
|
902
|
-
theme={{
|
|
903
|
-
colors: {
|
|
904
|
-
primary: '#2D2B32',
|
|
905
|
-
outline: '#E6E6E6',
|
|
906
|
-
},
|
|
907
|
-
}}
|
|
908
|
-
style={[styles.textInput, { marginHorizontal: 16, marginTop: 16, fontFamily: checkoutDetails.fontFamily.regular, }]}
|
|
909
|
-
error={cardHolderNameError}
|
|
910
|
-
right={
|
|
911
|
-
cardHolderNameError ? (
|
|
912
|
-
<TextInput.Icon
|
|
913
|
-
icon={() => (
|
|
914
|
-
<Image
|
|
915
|
-
source={require('../../assets/images/ic_upi_error.png')}
|
|
916
|
-
style={{ width: 24, height: 24 }}
|
|
917
|
-
/>
|
|
918
|
-
)}
|
|
919
|
-
/>
|
|
920
|
-
) : null
|
|
921
|
-
}
|
|
922
|
-
outlineStyle={{
|
|
923
|
-
borderRadius: 8, // Add this
|
|
924
|
-
borderWidth: 1.5,
|
|
925
|
-
}}
|
|
926
|
-
onBlur={handleCardHolderNameBlur}
|
|
927
|
-
onFocus={() => {
|
|
928
|
-
setCardHolderNameFocused(true);
|
|
929
|
-
setCardHolderNameError(false);
|
|
930
|
-
}}
|
|
931
|
-
/>
|
|
932
|
-
{cardHolderNameError && (
|
|
933
|
-
<Text
|
|
934
|
-
style={[styles.errorText, { fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
935
|
-
>
|
|
936
|
-
{cardHolderNameErrorText}
|
|
937
|
-
</Text>
|
|
938
|
-
)}
|
|
939
946
|
{shopperToken != null && shopperToken != '' && (
|
|
940
947
|
<>
|
|
941
948
|
<TextInput
|
|
@@ -958,16 +965,13 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
958
965
|
onChangeText={(it) => {
|
|
959
966
|
setCardNickNameText(it);
|
|
960
967
|
}}
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
primary: '#2D2B32',
|
|
964
|
-
outline: '#E6E6E6',
|
|
965
|
-
},
|
|
966
|
-
}}
|
|
968
|
+
inputAccessoryViewID={Platform.OS === 'ios' ? cardNickNameAccessoryID : undefined}
|
|
969
|
+
theme={getTextInputTheme()}
|
|
967
970
|
style={[
|
|
968
971
|
styles.textInput,
|
|
969
972
|
{ marginHorizontal: 16, marginTop: 16 , fontFamily: checkoutDetails.fontFamily.regular,},
|
|
970
973
|
]}
|
|
974
|
+
returnKeyType="done"
|
|
971
975
|
outlineStyle={{
|
|
972
976
|
borderRadius: 8, // Add this
|
|
973
977
|
borderWidth: 1.5,
|
|
@@ -1042,6 +1046,20 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
1042
1046
|
}}
|
|
1043
1047
|
/>
|
|
1044
1048
|
)}
|
|
1049
|
+
|
|
1050
|
+
{isSubscriptionDetailsVisible && (
|
|
1051
|
+
<View style = {styles.subscriptionContainer}>
|
|
1052
|
+
{checkoutDetails.subscriptionDetails && checkoutDetails.subscriptionDetails.map((item) => item.value && (
|
|
1053
|
+
<SubscriptionRow
|
|
1054
|
+
key={item.label}
|
|
1055
|
+
checkoutDetails={checkoutDetails}
|
|
1056
|
+
heading={item.label}
|
|
1057
|
+
value={item.value}
|
|
1058
|
+
/>
|
|
1059
|
+
))}
|
|
1060
|
+
</View>
|
|
1061
|
+
)}
|
|
1062
|
+
|
|
1045
1063
|
</ScrollView>
|
|
1046
1064
|
<View>
|
|
1047
1065
|
{cardValid ? (
|
|
@@ -1054,14 +1072,38 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
1054
1072
|
onProceedForward();
|
|
1055
1073
|
}}
|
|
1056
1074
|
>
|
|
1057
|
-
|
|
1058
|
-
|
|
1075
|
+
<Text style={[styles.buttonText, {fontFamily: checkoutDetails.fontFamily.semiBold,}]}>
|
|
1076
|
+
Pay{' '}
|
|
1077
|
+
<Text
|
|
1078
|
+
style={{
|
|
1079
|
+
fontFamily: 'Inter-SemiBold',
|
|
1080
|
+
fontSize: 16,
|
|
1081
|
+
color: 'white',
|
|
1082
|
+
}}
|
|
1083
|
+
>
|
|
1084
|
+
{' '}
|
|
1085
|
+
{checkoutDetails.currencySymbol}
|
|
1086
|
+
</Text>
|
|
1087
|
+
{checkoutDetails.amount}
|
|
1088
|
+
</Text>
|
|
1089
|
+
</Pressable>
|
|
1059
1090
|
) : (
|
|
1060
1091
|
<Pressable
|
|
1061
1092
|
style={[styles.buttonContainer, { backgroundColor: '#E6E6E6' , borderRadius: checkoutDetails.ctaBorderRadius,}]}
|
|
1062
1093
|
>
|
|
1063
|
-
<Text style={[styles.buttonText, {
|
|
1064
|
-
|
|
1094
|
+
<Text style={[styles.buttonText, {fontFamily: checkoutDetails.fontFamily.semiBold,}]}>
|
|
1095
|
+
Pay{' '}
|
|
1096
|
+
<Text
|
|
1097
|
+
style={{
|
|
1098
|
+
fontFamily: 'Inter-SemiBold',
|
|
1099
|
+
fontSize: 16,
|
|
1100
|
+
color: 'white',
|
|
1101
|
+
}}
|
|
1102
|
+
>
|
|
1103
|
+
{' '}
|
|
1104
|
+
{checkoutDetails.currencySymbol}
|
|
1105
|
+
</Text>
|
|
1106
|
+
{checkoutDetails.amount}
|
|
1065
1107
|
</Text>
|
|
1066
1108
|
</Pressable>
|
|
1067
1109
|
)}
|
|
@@ -1118,6 +1160,28 @@ const CardScreen = ({ route, navigation }: Props) => {
|
|
|
1118
1160
|
</View>
|
|
1119
1161
|
)}
|
|
1120
1162
|
</View>
|
|
1163
|
+
{Platform.OS === 'ios' && (
|
|
1164
|
+
<>
|
|
1165
|
+
{[
|
|
1166
|
+
cardNumberAccessoryID,
|
|
1167
|
+
cardExpiryAccessoryID,
|
|
1168
|
+
cardCvvAccessoryID,
|
|
1169
|
+
cardHolderNameAccessoryID,
|
|
1170
|
+
cardNickNameAccessoryID,
|
|
1171
|
+
].map((id) => (
|
|
1172
|
+
<InputAccessoryView key={id} nativeID={id}>
|
|
1173
|
+
<View style={{ backgroundColor: '#f1f1f1', padding: 10, alignItems: 'flex-end' }}>
|
|
1174
|
+
<TouchableOpacity onPress={() => Keyboard.dismiss()}>
|
|
1175
|
+
<Text style={{ fontSize: 16, fontFamily: checkoutDetails.fontFamily.semiBold }}>
|
|
1176
|
+
Done
|
|
1177
|
+
</Text>
|
|
1178
|
+
</TouchableOpacity>
|
|
1179
|
+
</View>
|
|
1180
|
+
</InputAccessoryView>
|
|
1181
|
+
))}
|
|
1182
|
+
</>
|
|
1183
|
+
)}
|
|
1184
|
+
</>
|
|
1121
1185
|
);
|
|
1122
1186
|
};
|
|
1123
1187
|
|
|
@@ -38,6 +38,7 @@ import { handleFetchStatusResponseHandler, handlePaymentResponse } from '../shar
|
|
|
38
38
|
import type { CheckoutStackParamList } from '../navigation';
|
|
39
39
|
import type { NavigationProp, RouteProp } from '@react-navigation/native';
|
|
40
40
|
import { setUserDataHandlerToDefault } from '../sharedContext/userdataHandler';
|
|
41
|
+
import { getTextInputTheme } from '../sharedContext/getTextInputTheme';
|
|
41
42
|
|
|
42
43
|
type EmiScreenRouteProp = RouteProp<CheckoutStackParamList, 'EmiScreen'>;
|
|
43
44
|
|
|
@@ -633,12 +634,7 @@ const EmiScreen = ({ navigation, route }: Props) => {
|
|
|
633
634
|
onChangeText={(it) => {
|
|
634
635
|
setSearchText(it);
|
|
635
636
|
}}
|
|
636
|
-
theme={
|
|
637
|
-
colors: {
|
|
638
|
-
primary: '#2D2B32',
|
|
639
|
-
outline: '#E6E6E6',
|
|
640
|
-
},
|
|
641
|
-
}}
|
|
637
|
+
theme={getTextInputTheme()}
|
|
642
638
|
style={[styles.textInputStyle, {fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
643
639
|
left={
|
|
644
640
|
<TextInput.Icon
|
|
@@ -14,6 +14,7 @@ import type { RouteProp, NavigationProp } from '@react-navigation/native';
|
|
|
14
14
|
import Header from '../components/header';
|
|
15
15
|
import styles from '../styles/screens/instantOfferScreenStyles';
|
|
16
16
|
import { checkoutDetailsHandler } from '../sharedContext/checkoutDetailsHandler';
|
|
17
|
+
import { getTextInputTheme } from '../sharedContext/getTextInputTheme';
|
|
17
18
|
|
|
18
19
|
export interface InstantOfferProps {
|
|
19
20
|
couponList: GetInstantOffersResponse[];
|
|
@@ -98,12 +99,7 @@ const InstantOfferScreen = ({ route, navigation } : Props) => {
|
|
|
98
99
|
onChangeText={(it) => {
|
|
99
100
|
handleSearchTextChange(it);
|
|
100
101
|
}}
|
|
101
|
-
theme={
|
|
102
|
-
colors: {
|
|
103
|
-
primary: '#2D2B32',
|
|
104
|
-
outline: '#E6E6E6',
|
|
105
|
-
},
|
|
106
|
-
}}
|
|
102
|
+
theme={getTextInputTheme()}
|
|
107
103
|
style={[styles.searchTextInput, {fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
108
104
|
left={
|
|
109
105
|
<TextInput.Icon
|
|
@@ -15,7 +15,7 @@ import type { CheckoutStackParamList } from '../navigation';
|
|
|
15
15
|
import { paymentHandler, setPaymentHandler } from "../sharedContext/paymentStatusHandler";
|
|
16
16
|
import { loadBoxpayFonts } from '../components/fontFamily';
|
|
17
17
|
import { setUserDataHandler, setUserDataHandlerToDefault, userDataHandler } from '../sharedContext/userdataHandler';
|
|
18
|
-
import { type PaymentResultObject, type PaymentClass, type InstrumentDetails, type PaymentMethod, type OrderItem, APIStatus, AnalyticsEvents, type DeliveryAddress, type BoxpayCheckoutProps, type GetInstantOffersResponse, UIConfigurationOptions, TransactionStatus } from '../interface';
|
|
18
|
+
import { type PaymentResultObject, type PaymentClass, type InstrumentDetails, type PaymentMethod, type OrderItem, APIStatus, AnalyticsEvents, type DeliveryAddress, type BoxpayCheckoutProps, type GetInstantOffersResponse, UIConfigurationOptions, TransactionStatus, type SubscriptionDetails } from '../interface';
|
|
19
19
|
import { checkoutDetailsHandler, setCheckoutDetailsHandler, setCheckOutDetailsHandlerToDefault } from '../sharedContext/checkoutDetailsHandler';
|
|
20
20
|
import WebViewScreen from '../screens/webViewScreen';
|
|
21
21
|
import styles from '../styles/indexStyles';
|
|
@@ -30,7 +30,7 @@ import fetchSessionDetails from '../postRequest/fetchSessionDetails';
|
|
|
30
30
|
import MorePaymentMethods from '../components/morePaymentMethods';
|
|
31
31
|
import { fetchSavedInstrumentsHandler, handleFetchStatusResponseHandler, handlePaymentResponse } from '../sharedContext/handlePaymentResponseHandler';
|
|
32
32
|
import callUIAnalytics from '../postRequest/callUIAnalytics';
|
|
33
|
-
import { formatAddress, getPhoneNumberCodeAndCountryName, useCountdown } from '../utility';
|
|
33
|
+
import { formatAddress, formatDate, getPhoneNumberCodeAndCountryName, isEmpty, useCountdown } from '../utility';
|
|
34
34
|
import fetchSurCharge from '../postRequest/fetchSurcharge';
|
|
35
35
|
import fetchInstantOffer from '../postRequest/fetchInstantOffer';
|
|
36
36
|
import ApplyCouponCard from '../components/applyCouponCard';
|
|
@@ -552,6 +552,8 @@ const MainScreen = ({route, navigation} : MainScreenProps) => {
|
|
|
552
552
|
},
|
|
553
553
|
ctaBorderRadius : uiConfiguration?.[UIConfigurationOptions.CTABorderRadius] ? uiConfiguration[UIConfigurationOptions.CTABorderRadius] : 12,
|
|
554
554
|
buttonColor: response.data.merchantDetails.checkoutTheme.primaryButtonColor,
|
|
555
|
+
textInputFieldFocusedOutlineColor: uiConfiguration?.[UIConfigurationOptions.TextInputFields]?.focusedBorderColor ? uiConfiguration[UIConfigurationOptions.TextInputFields].focusedBorderColor : '#2D2B32',
|
|
556
|
+
textInputFieldUnFocusedOutlineColor : uiConfiguration?.[UIConfigurationOptions.TextInputFields]?.borderColor ? uiConfiguration[UIConfigurationOptions.TextInputFields].borderColor : '#E6E6E6',
|
|
555
557
|
buttonTextColor : response.data.merchantDetails.checkoutTheme.buttonTextColor,
|
|
556
558
|
headerColor : response.data.merchantDetails.checkoutTheme.headerColor,
|
|
557
559
|
headerTextColor : response.data.merchantDetails.checkoutTheme.headerTextColor,
|
|
@@ -586,7 +588,8 @@ const MainScreen = ({route, navigation} : MainScreenProps) => {
|
|
|
586
588
|
isUPIOtmQRMethodEnabled : methodFlags.isUPIOtmQRVisible,
|
|
587
589
|
isOrderItemDetailsVisible : isFieldEnabled('ORDER_ITEM_DETAILS'),
|
|
588
590
|
isSICheckboxVisible : configurationOptions?.SHOW_SI_CHECKBOX ? true : false,
|
|
589
|
-
isSubscriptionCheckout : paymentDetails.subscriptionDetails != null ? true : false
|
|
591
|
+
isSubscriptionCheckout : paymentDetails.subscriptionDetails != null ? true : false,
|
|
592
|
+
subscriptionDetails : getSubscriptionDetails(paymentDetails.subscriptionDetails, paymentDetails.money.amountLocaleFull, symbol)
|
|
590
593
|
},
|
|
591
594
|
});
|
|
592
595
|
setPaymentHandler({
|
|
@@ -614,6 +617,54 @@ const MainScreen = ({route, navigation} : MainScreenProps) => {
|
|
|
614
617
|
loadSession()
|
|
615
618
|
}, []);
|
|
616
619
|
|
|
620
|
+
const getSubscriptionDetails = (data: SubscriptionDetails | null, amount : string, currencySymbol : string) => {
|
|
621
|
+
if (isEmpty(data)) return null;
|
|
622
|
+
|
|
623
|
+
const { billingCycle } = data!;
|
|
624
|
+
|
|
625
|
+
// Frequency
|
|
626
|
+
let frequency: string | null = null;
|
|
627
|
+
if (!isEmpty(billingCycle)) {
|
|
628
|
+
const { billingCycleValue, count, billingTimeUnit } = billingCycle!;
|
|
629
|
+
|
|
630
|
+
if (count === 1) {
|
|
631
|
+
frequency = billingTimeUnit;
|
|
632
|
+
} else {
|
|
633
|
+
frequency = `Every ${count} ${billingCycleValue}`;
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
|
|
637
|
+
// Validity
|
|
638
|
+
let validity: string | null = null;
|
|
639
|
+
if (!isEmpty(data!.expiryDateLocale)) {
|
|
640
|
+
const date = formatDate(data!.expiryDateLocale!.split(' ')[0] ?? "");
|
|
641
|
+
validity = `Till ${date}`;
|
|
642
|
+
} else if (!isEmpty(data!.recurringExpiryDateLocale)) {
|
|
643
|
+
const date = formatDate(data!.recurringExpiryDateLocale!.split(' ')[0] ?? "");
|
|
644
|
+
validity = `${date}`;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
const rows = [
|
|
648
|
+
{
|
|
649
|
+
label: 'To be paid now',
|
|
650
|
+
value: !isEmpty(amount) ? `${currencySymbol}${amount}` : null,
|
|
651
|
+
},
|
|
652
|
+
{
|
|
653
|
+
label: 'Recurring Amount',
|
|
654
|
+
value: !isEmpty(data!.maxAmountLocaleFull) ? `Up to ${currencySymbol}${data!.maxAmountLocaleFull}` : null,
|
|
655
|
+
},
|
|
656
|
+
{
|
|
657
|
+
label: 'Frequency',
|
|
658
|
+
value: frequency,
|
|
659
|
+
},
|
|
660
|
+
{
|
|
661
|
+
label: 'Expiry Date',
|
|
662
|
+
value: validity,
|
|
663
|
+
},
|
|
664
|
+
];
|
|
665
|
+
return rows.filter(row => !isEmpty(row.value));
|
|
666
|
+
};
|
|
667
|
+
|
|
617
668
|
const handleSurchargeDetails = async() => {
|
|
618
669
|
const response = await fetchSurCharge()
|
|
619
670
|
switch (response.apiStatus) {
|
|
@@ -26,6 +26,7 @@ import styles from '../styles/screens/netBankingScreenStyles';
|
|
|
26
26
|
import type { CheckoutStackParamList } from '../navigation';
|
|
27
27
|
import type { NavigationProp, RouteProp } from '@react-navigation/native';
|
|
28
28
|
import { setUserDataHandlerToDefault } from '../sharedContext/userdataHandler';
|
|
29
|
+
import { getTextInputTheme } from '../sharedContext/getTextInputTheme';
|
|
29
30
|
|
|
30
31
|
type NetBankingScreenRouteProp = RouteProp<CheckoutStackParamList, 'NetBankingScreen'>;
|
|
31
32
|
|
|
@@ -314,12 +315,7 @@ const NetBankingScreen = ({ navigation, route }: Props) => {
|
|
|
314
315
|
onChangeText={(it) => {
|
|
315
316
|
handleSearchTextChange(it);
|
|
316
317
|
}}
|
|
317
|
-
theme={
|
|
318
|
-
colors: {
|
|
319
|
-
primary: '#2D2B32',
|
|
320
|
-
outline: '#E6E6E6',
|
|
321
|
-
},
|
|
322
|
-
}}
|
|
318
|
+
theme={getTextInputTheme()}
|
|
323
319
|
style={[styles.searchTextInput, {fontFamily: checkoutDetails.fontFamily.regular,}]}
|
|
324
320
|
left={
|
|
325
321
|
<TextInput.Icon
|