ordering-ui-react-native 0.18.50 → 0.18.52

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ordering-ui-react-native",
3
- "version": "0.18.50",
3
+ "version": "0.18.52",
4
4
  "description": "Reusable components made in react native",
5
5
  "main": "src/index.tsx",
6
6
  "author": "ordering.inc",
@@ -1,10 +1,8 @@
1
- import React, { useState, useEffect } from 'react'
1
+ import React, { useEffect } from 'react'
2
2
  import { useLanguage, useConfig } from 'ordering-components/native'
3
- import { useGooglePay, ApplePayButton, useApplePay } from '@stripe/stripe-react-native'
4
- import { OButton, OText } from '../shared';
5
- import { Platform, View } from 'react-native';
3
+ import { useGooglePay, useApplePay } from '@stripe/stripe-react-native'
4
+ import { Platform } from 'react-native';
6
5
  import { StripeMethodFormParams } from '../../types';
7
- import Spinner from 'react-native-loading-spinner-overlay';
8
6
  import { android_app_id } from '../../config.json'
9
7
 
10
8
  export const StripeMethodForm = (props: StripeMethodFormParams) => {
@@ -14,23 +12,35 @@ export const StripeMethodForm = (props: StripeMethodFormParams) => {
14
12
  onCancel,
15
13
  setErrors,
16
14
  paymethod,
17
- devMode
15
+ devMode,
16
+ setMethodPaySupported,
17
+ placeByMethodPay,
18
+ methodPaySupported,
19
+ setPlaceByMethodPay,
20
+ cartTotal
18
21
  } = props
19
22
  const { initGooglePay, createGooglePayPaymentMethod, loading } = useGooglePay();
20
23
  const { presentApplePay, isApplePaySupported } = useApplePay();
21
- const [initialized, setInitialized] = useState(false);
22
- const [loadingGooglePayment, setLoadingGooglePayment] = useState(false)
23
24
  const [, t] = useLanguage()
24
- const [{configs}] = useConfig()
25
-
25
+ const [{ configs }] = useConfig()
26
+ const applePay = ['global_apple_pay', 'apple_pay']
27
+ const googlePay = ['global_google_pay', 'google_pay']
26
28
  useEffect(() => {
27
- if (paymethod !== 'google_pay' || !initGooglePay) return
28
29
  if (Platform.OS === 'ios') {
29
30
  setErrors(t('GOOGLE_PAY_NOT_SUPPORTED', 'Google pay not supported'))
31
+ setMethodPaySupported({
32
+ enabled: false,
33
+ loading: false
34
+ })
35
+ setPlaceByMethodPay(false)
30
36
  return
31
37
  }
32
38
  const initialize = async () => {
33
39
  try {
40
+ setMethodPaySupported({
41
+ ...methodPaySupported,
42
+ loading: true
43
+ })
34
44
  const { error } = await initGooglePay({
35
45
  testEnv: devMode,
36
46
  merchantName: android_app_id,
@@ -46,36 +56,68 @@ export const StripeMethodForm = (props: StripeMethodFormParams) => {
46
56
 
47
57
  if (error) {
48
58
  setErrors(error.code + ' - ' + error.message);
59
+ setMethodPaySupported({
60
+ enabled: false,
61
+ loading: false
62
+ })
63
+ setPlaceByMethodPay(false)
49
64
  return;
50
65
  }
51
- setInitialized(true);
66
+ setMethodPaySupported({
67
+ enabled: true,
68
+ loading: false
69
+ })
70
+ setPlaceByMethodPay(false)
71
+ setErrors('')
52
72
  } catch (err: any) {
53
73
  setErrors('Catch ' + err?.message)
74
+ setMethodPaySupported({
75
+ enabled: false,
76
+ loading: false
77
+ })
78
+ setPlaceByMethodPay(false)
54
79
  }
55
80
  }
56
- initialize();
57
- }, [initGooglePay]);
81
+ if (googlePay.includes(paymethod)) {
82
+ initialize();
83
+ }
84
+ }, [initGooglePay, paymethod]);
58
85
 
59
86
  useEffect(() => {
60
- if (paymethod !== 'apple_pay') return
87
+ if (applePay.includes(paymethod) && !paymethod) return
61
88
  if (Platform.OS === 'android') {
89
+ setPlaceByMethodPay(false)
62
90
  setErrors(t('APPLE_PAY_NOT_SUPPORTED', 'Apple pay not supported'))
91
+ setMethodPaySupported({
92
+ enabled: false,
93
+ loading: false
94
+ })
63
95
  return
64
96
  }
65
- }, [])
97
+ }, [paymethod])
66
98
 
67
99
  const createPaymentMethod = async () => {
68
- setLoadingGooglePayment(true)
100
+ setMethodPaySupported({
101
+ ...methodPaySupported,
102
+ loading: true
103
+ })
69
104
  const { error, paymentMethod } = await createGooglePayPaymentMethod({
70
- amount: cart?.balance ?? cart?.total,
105
+ amount: cartTotal ?? cart?.balance ?? cart?.total,
71
106
  currencyCode: configs?.stripe_currency?.value ?? 'USD',
72
107
  });
73
108
  if (error) {
74
109
  setErrors(error.code + ' - ' + error.message);
75
- setLoadingGooglePayment(false)
110
+ setMethodPaySupported({
111
+ enabled: true,
112
+ loading: false
113
+ })
76
114
  return;
77
115
  } else if (paymentMethod) {
78
- handleSource({
116
+ setMethodPaySupported({
117
+ enabled: true,
118
+ loading: false
119
+ })
120
+ const source = {
79
121
  ...paymentMethod?.Card,
80
122
  id: paymentMethod.id,
81
123
  type: paymentMethod.type,
@@ -84,30 +126,48 @@ export const StripeMethodForm = (props: StripeMethodFormParams) => {
84
126
  brand: paymentMethod.Card.brand,
85
127
  last4: paymentMethod.Card.last4
86
128
  }
87
- })
129
+ }
130
+ handleSource(cartTotal ? JSON.stringify(source) : source)
88
131
  onCancel()
89
- setLoadingGooglePayment(false)
90
132
  }
133
+ setPlaceByMethodPay(false)
91
134
  };
92
135
 
93
136
  const pay = async () => {
137
+ setMethodPaySupported({
138
+ ...methodPaySupported,
139
+ loading: true
140
+ })
94
141
  if (!isApplePaySupported) {
95
142
  setErrors(t('APPLE_PAY_NOT_SUPPORTED', 'Apple pay not supported'))
143
+ setMethodPaySupported({
144
+ enabled: false,
145
+ loading: false
146
+ })
147
+ setPlaceByMethodPay(false)
96
148
  return
97
149
  }
98
150
 
99
151
  const { error, paymentMethod } = await presentApplePay({
100
152
  cartItems: [{
101
153
  label: t('CART', 'Cart'),
102
- amount: cart?.balance?.toString() ?? cart?.total?.toString?.()
154
+ amount: cartTotal?.toString?.() ?? cart?.balance?.toString() ?? cart?.total?.toString?.()
103
155
  }],
104
156
  country: 'US',
105
157
  currency: configs?.stripe_currency?.value ?? 'USD',
106
158
  });
107
159
  if (error) {
108
160
  setErrors(error.code + ' - ' + error.message);
161
+ setMethodPaySupported({
162
+ enabled: true,
163
+ loading: false
164
+ })
109
165
  } else if (paymentMethod) {
110
- handleSource({
166
+ setMethodPaySupported({
167
+ enabled: true,
168
+ loading: false
169
+ })
170
+ const source = {
111
171
  ...paymentMethod?.Card,
112
172
  id: paymentMethod.id,
113
173
  type: paymentMethod.type,
@@ -116,50 +176,29 @@ export const StripeMethodForm = (props: StripeMethodFormParams) => {
116
176
  brand: paymentMethod.Card.brand,
117
177
  last4: paymentMethod.Card.last4
118
178
  }
119
- })
179
+ }
180
+ handleSource(cartTotal ? JSON.stringify(source) : source)
120
181
  }
182
+ setPlaceByMethodPay(false)
121
183
  }
122
184
 
185
+ useEffect(() => {
186
+ if (isApplePaySupported && applePay.includes(paymethod)) {
187
+ setMethodPaySupported({
188
+ enabled: true,
189
+ loading: false
190
+ })
191
+ setErrors('')
192
+ }
193
+ }, [isApplePaySupported, paymethod])
194
+
195
+ useEffect(() => {
196
+ if (placeByMethodPay) {
197
+ applePay.includes(paymethod) ? pay() : createPaymentMethod()
198
+ }
199
+ }, [placeByMethodPay])
200
+
123
201
  return (
124
- <>
125
- {paymethod === 'google_pay' ? (
126
- <View>
127
- <OButton
128
- textStyle={{
129
- color: '#fff'
130
- }}
131
- imgRightSrc={null}
132
- onClick={createPaymentMethod}
133
- isDisabled={loading || !initialized}
134
- text={t('PAY_WITH_GOOGLE_PAY', 'Pay with Google Pay')}
135
- isLoading={loading || !initialized}
136
- style={{ marginTop: 20 }}
137
- />
138
- </View>
139
- ) : (
140
- <View>
141
- {isApplePaySupported ? (
142
- <>
143
- <OText>{t('APPLE_PAY_PAYMENT', 'Apple pay payment')}</OText>
144
- <ApplePayButton
145
- onPress={pay}
146
- type="plain"
147
- buttonStyle="black"
148
- borderRadius={4}
149
- style={{
150
- width: '100%',
151
- height: 50,
152
- }}
153
- />
154
- </>
155
- ) : (
156
- <OText>{t('APPLE_PAY_NOT_SUPPORTED', 'Apple pay not supported')}</OText>
157
- )}
158
- </View>
159
- )}
160
- <Spinner
161
- visible={loadingGooglePayment}
162
- />
163
- </>
202
+ <></>
164
203
  )
165
204
  }
@@ -490,4 +490,9 @@ export interface StripeMethodFormParams {
490
490
  setErrors: (error: string) => void;
491
491
  paymethod: string;
492
492
  devMode?: boolean;
493
+ setMethodPaySupported?: any
494
+ placeByMethodPay?: any
495
+ methodPaySupported?: any,
496
+ setPlaceByMethodPay?: any,
497
+ cartTotal?: number
493
498
  }
@@ -618,7 +618,9 @@ export const OrderContentComponent = (props: OrderContent) => {
618
618
  )}
619
619
  </View>
620
620
  <OText>
621
- -{parsePrice(event.amount, { currency: order?.currency })}
621
+ {(event?.paymethod?.gateway === 'cash' && order?.cash)
622
+ ? parsePrice(order?.cash, { currency: order?.currency })
623
+ : `-${parsePrice(event?.amount, { currency: order?.currency })}`}
622
624
  </OText>
623
625
  </View>
624
626
  ))}
@@ -152,8 +152,9 @@ const CheckoutUI = (props: any) => {
152
152
  const [isOpen, setIsOpen] = useState(false)
153
153
  const [requiredFields, setRequiredFields] = useState<any>([])
154
154
  const [openModal, setOpenModal] = useState({ login: false, signup: false })
155
- const [allowedGuest, setAllowedGuest] = useState(false)
156
-
155
+ const [allowedGuest, setAllowedGuest] = useState(false)
156
+ const [placeByMethodPay, setPlaceByMethodPay] = useState(false)
157
+ const [methodPaySupported, setMethodPaySupported] = useState({ enabled: false, message: null, loading: true })
157
158
  const placeSpotTypes = [3, 4, 5]
158
159
  const placeSpotsEnabled = placeSpotTypes.includes(options?.type)
159
160
  const isGiftCardCart = !cart?.business_id
@@ -170,6 +171,7 @@ const CheckoutUI = (props: any) => {
170
171
 
171
172
  const creditPointPlan = loyaltyPlansState?.result?.find((loyal: any) => loyal.type === 'credit_point')
172
173
  const creditPointPlanOnBusiness = creditPointPlan?.businesses?.find((b: any) => b.business_id === cart?.business_id && b.accumulates)
174
+ const methodsPay = ['google_pay', 'apple_pay']
173
175
 
174
176
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
175
177
  const subtotalWithTaxes = cart?.taxes?.reduce((acc: any, item: any) => {
@@ -187,6 +189,7 @@ const CheckoutUI = (props: any) => {
187
189
  validationFields?.fields?.checkout?.driver_tip?.required &&
188
190
  (Number(cart?.driver_tip) <= 0)) ||
189
191
  (validateCommentsCartField)
192
+ || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading))
190
193
 
191
194
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
192
195
  ? JSON.parse(configs?.driver_tip_options?.value) || []
@@ -209,16 +212,16 @@ const CheckoutUI = (props: any) => {
209
212
  }
210
213
 
211
214
  const handleSuccessSignup = (user: any) => {
212
- login({
213
- user,
214
- token: user?.session?.access_token
215
- })
216
- setOpenModal({ ...openModal, signup: false })
217
- }
215
+ login({
216
+ user,
217
+ token: user?.session?.access_token
218
+ })
219
+ setOpenModal({ ...openModal, signup: false })
220
+ }
218
221
 
219
222
  const handleSuccessLogin = (user: any) => {
220
- if (user) setOpenModal({ ...openModal, login: false })
221
- }
223
+ if (user) setOpenModal({ ...openModal, login: false })
224
+ }
222
225
 
223
226
  const handlePlaceOrder = (confirmPayment: any, forcePlace: boolean = false) => {
224
227
  if (!userErrors.length && (!requiredFields?.length || allowedGuest) || forcePlace) {
@@ -239,9 +242,9 @@ const CheckoutUI = (props: any) => {
239
242
  }
240
243
 
241
244
  const handlePlaceOrderAsGuest = () => {
242
- setIsOpen(false)
243
- handlerClickPlaceOrder && handlerClickPlaceOrder()
244
- }
245
+ setIsOpen(false)
246
+ handlerClickPlaceOrder && handlerClickPlaceOrder()
247
+ }
245
248
 
246
249
  const handlePaymentMethodClick = (paymethod: any) => {
247
250
  setShowGateway({ closedByUser: false, open: true })
@@ -261,7 +264,7 @@ const CheckoutUI = (props: any) => {
261
264
  const checkValidationFields = () => {
262
265
  setUserErrors([])
263
266
  const errors = []
264
- const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes', 'comments']
267
+ const notFields = ['coupon', 'driver_tip', 'mobile_phone', 'address', 'zipcode', 'address_notes']
265
268
  const _requiredFields: any = []
266
269
 
267
270
  Object.values(validationFields?.fields?.checkout).map((field: any) => {
@@ -662,6 +665,10 @@ const CheckoutUI = (props: any) => {
662
665
  handlePaymentMethodClickCustom={handlePaymentMethodClick}
663
666
  handlePlaceOrder={handlePlaceOrder}
664
667
  merchantId={merchantId}
668
+ setMethodPaySupported={setMethodPaySupported}
669
+ methodPaySupported={methodPaySupported}
670
+ placeByMethodPay={placeByMethodPay}
671
+ setPlaceByMethodPay={setPlaceByMethodPay}
665
672
  />
666
673
  </ChPaymethods>
667
674
  </ChSection>
@@ -745,7 +752,7 @@ const CheckoutUI = (props: any) => {
745
752
  maxDate={maxDate}
746
753
  loyaltyRewardRate={
747
754
  creditPointPlanOnBusiness?.accumulation_rate ??
748
- (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
755
+ (!!creditPointPlanOnBusiness && creditPointPlan?.accumulation_rate) ?? 0
749
756
  }
750
757
  />
751
758
  </>
@@ -856,7 +863,7 @@ const CheckoutUI = (props: any) => {
856
863
  open={openModal.signup}
857
864
  onClose={() => setOpenModal({ ...openModal, signup: false })}
858
865
  >
859
- <ScrollView style={{ paddingHorizontal: 20, width: '100%'}}>
866
+ <ScrollView style={{ paddingHorizontal: 20, width: '100%' }}>
860
867
  <SignupForm
861
868
  handleSuccessSignup={handleSuccessSignup}
862
869
  isGuest
@@ -870,7 +877,7 @@ const CheckoutUI = (props: any) => {
870
877
  open={openModal.login}
871
878
  onClose={() => setOpenModal({ ...openModal, login: false })}
872
879
  >
873
- <ScrollView style={{ paddingHorizontal: 20, width: '100%'}}>
880
+ <ScrollView style={{ paddingHorizontal: 20, width: '100%' }}>
874
881
  <LoginForm
875
882
  handleSuccessLogin={handleSuccessLogin}
876
883
  isGuest
@@ -883,7 +890,12 @@ const CheckoutUI = (props: any) => {
883
890
  </Container>
884
891
  {!cartState.loading && cart && cart?.status !== 2 && (
885
892
  <FloatingButton
886
- handleClick={isDisabledButtonPlace ? () => vibrateApp() : () => handlePlaceOrder(null)}
893
+ handleClick={
894
+ isDisabledButtonPlace
895
+ ? () => vibrateApp()
896
+ : methodsPay.includes(paymethodSelected?.gateway)
897
+ ? () => setPlaceByMethodPay(true)
898
+ : () => handlePlaceOrder(null)}
887
899
  isSecondaryBtn={isDisabledButtonPlace}
888
900
  disabled={isDisabledButtonPlace}
889
901
  btnText={subtotalWithTaxes >= cart?.minimum
@@ -70,11 +70,17 @@ export const LottieAnimation = (props: Props) => {
70
70
  style={style}
71
71
  >
72
72
  {type === 'favorite' ? (
73
- <Lottie
74
- ref={favRef}
75
- progress={initialValue}
76
- style={{ width: 20, height: 20 }}
77
- source={animationGif}
73
+ // <Lottie
74
+ // ref={favRef}
75
+ // progress={initialValue}
76
+ // style={{ width: 20, height: 20 }}
77
+ // source={animationGif}
78
+ // />
79
+ <IconAntDesign
80
+ name={isActive ? icon[0] : icon[1]}
81
+ color={iconProps?.color || theme.colors.danger5}
82
+ size={iconProps?.size || 16}
83
+ style={iconProps?.style}
78
84
  />
79
85
  ) : (
80
86
  <>
@@ -1,4 +1,4 @@
1
- import React, { useState } from 'react'
1
+ import React, { useEffect, useState } from 'react'
2
2
  import {
3
3
  useLanguage,
4
4
  useConfig,
@@ -29,7 +29,15 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
29
29
  paymethodSelected,
30
30
  handleSelectPaymethod,
31
31
  handleSelectWallet,
32
- handlePaymethodDataChange
32
+ handlePaymethodDataChange,
33
+ setMethodPaySupported,
34
+ placeByMethodPay,
35
+ methodPaySupported,
36
+ setPlaceByMethodPay,
37
+ openCarts,
38
+ cartTotal,
39
+ handlePlaceOrder,
40
+ merchantId
33
41
  } = props
34
42
 
35
43
  const theme = useTheme()
@@ -54,6 +62,8 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
54
62
  }
55
63
 
56
64
  const creditBalance: any = (wallet: any) => ` = ${parsePrice(wallet.balance / wallet.redemption_rate, { isTruncable: true })}`
65
+ const filterMethodsPay = (gateway: string) => Platform.OS === 'ios' ? gateway !== 'global_google_pay' : gateway !== 'global_apple_pay'
66
+ const methodsPay = ['global_google_pay', 'global_apple_pay']
57
67
 
58
68
  const getPayIcon = (method: string) => {
59
69
  switch (method) {
@@ -71,35 +81,61 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
71
81
  return theme.images.general.stripes
72
82
  case 'stripe_redirect':
73
83
  return theme.images.general.stripesb
84
+ case 'global_apple_pay':
85
+ return theme.images.general.applePayMark
74
86
  default:
75
87
  return theme.images.general.creditCard
76
88
  }
77
89
  }
78
90
 
91
+ useEffect(() => {
92
+ if (methodsPay.includes(paymethodSelected?.gateway)) {
93
+ if (typeof paymethodSelected?.paymethod_data === 'string'){
94
+ const sourceId = JSON.parse(paymethodSelected?.paymethod_data)?.source_id
95
+ sourceId && handlePlaceOrder()
96
+ }
97
+ }
98
+ }, [JSON.stringify(paymethodSelected)])
99
+
79
100
  const renderPaymethods = ({ item }: any) => {
80
101
  return (
81
- <TouchableOpacity
82
- onPress={() => handleSelectPaymethod({ ...item, paymethod: { gateway: item.gateway }, paymethod_id: item?.id })}
83
- >
84
- <PMItem
85
- key={item.id}
86
- isActive={paymethodSelected?.id === item.id}
87
- >
88
- <OIcon
89
- src={getPayIcon(item?.gateway ?? item.paymethod?.gateway)}
90
- width={20}
91
- height={20}
92
- color={paymethodSelected?.id === item.id ? theme.colors.white : theme.colors.backgroundDark}
93
- />
94
- <OText
95
- size={10}
96
- style={{ margin: 0, marginTop: 4 }}
97
- color={paymethodSelected?.id === item.id ? theme.colors.white : '#000'}
102
+ <>
103
+ {item?.gateway === 'apple_pay' ? (
104
+ <TouchableOpacity
105
+ onPress={() => handleSelectPaymethod({ ...item, paymethod: { gateway: item.gateway }, paymethod_id: item?.id })}
98
106
  >
99
- {t(item?.gateway.toUpperCase(), item?.name)}
100
- </OText>
101
- </PMItem>
102
- </TouchableOpacity>
107
+ <OIcon
108
+ src={getPayIcon(item.gateway)}
109
+ width={70}
110
+ height={70}
111
+ style={{ marginRight: 10 }}
112
+ />
113
+ </TouchableOpacity>
114
+ ) : (
115
+ <TouchableOpacity
116
+ onPress={() => handleSelectPaymethod({ ...item, paymethod: { gateway: item.gateway }, paymethod_id: item?.id })}
117
+ >
118
+ <PMItem
119
+ key={item.id}
120
+ isActive={paymethodSelected?.id === item.id}
121
+ >
122
+ <OIcon
123
+ src={getPayIcon(item?.gateway ?? item.paymethod?.gateway)}
124
+ width={20}
125
+ height={20}
126
+ color={item?.gateway === 'apple_pay' ? '' : paymethodSelected?.id === item.id ? theme.colors.white : theme.colors.backgroundDark}
127
+ />
128
+ <OText
129
+ size={10}
130
+ style={{ margin: 0, marginTop: 4 }}
131
+ color={paymethodSelected?.id === item.id ? theme.colors.white : '#000'}
132
+ >
133
+ {t(item?.gateway.toUpperCase(), item?.name)}
134
+ </OText>
135
+ </PMItem>
136
+ </TouchableOpacity>
137
+ )}
138
+ </>
103
139
  )
104
140
  }
105
141
 
@@ -126,7 +162,7 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
126
162
  <FlatList
127
163
  horizontal
128
164
  showsHorizontalScrollIndicator={false}
129
- data={paymethodsAndWallets.paymethods}
165
+ data={paymethodsAndWallets.paymethods.filter((p: any) => filterMethodsPay(p.gateway))}
130
166
  renderItem={renderPaymethods}
131
167
  keyExtractor={(paymethod: any) => paymethod?.id?.toString?.()}
132
168
  />
@@ -159,6 +195,27 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
159
195
  </View>
160
196
  )}
161
197
 
198
+ {/* Google pay, Apple pay */}
199
+ {methodsPay.includes(paymethodSelected?.paymethod?.gateway) && (
200
+ <StripeElementsForm
201
+ toSave
202
+ businessId={businessIds[0]}
203
+ businessIds={businessIds}
204
+ publicKey={paymethodSelected?.data?.publishable}
205
+ requirements={props.clientSecret}
206
+ handleSource={handlePaymethodDataChange}
207
+ onCancel={() => setAddCardOpen({ ...addCardOpen, stripe: false })}
208
+ setMethodPaySupported={setMethodPaySupported}
209
+ methodPaySupported={methodPaySupported}
210
+ placeByMethodPay={placeByMethodPay}
211
+ setPlaceByMethodPay={setPlaceByMethodPay}
212
+ methodsPay={methodsPay}
213
+ paymethod={paymethodSelected?.paymethod?.gateway}
214
+ cartTotal={cartTotal}
215
+ merchantId={merchantId}
216
+ />
217
+ )}
218
+
162
219
  {(paymethodsAndWallets.loading || walletsState.loading) ? (
163
220
  <>
164
221
  {[...Array(2).keys()].map(i => (
@@ -174,46 +231,46 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
174
231
  <>
175
232
  {walletsState?.result?.filter((wallet: any) =>
176
233
  paymethodsAndWallets.wallets.find((item: any) => item.type === wallet.type))
177
- .map((wallet: any, idx: any) => walletName[wallet.type]?.isActive &&
178
- (
179
- <WalletItem
180
- key={wallet.type}
181
- isBottomBorder={idx === paymethodsAndWallets.wallets?.length - 1}
182
- onPress={() => handleSelectWallet(!!!walletsPaymethod?.find((walletPay: any) => walletPay.wallet_id === wallet.id)?.id, wallet)}
183
- >
184
- {!!walletsPaymethod?.find((walletPay: any) => walletPay.wallet_id === wallet.id)?.id ? (
185
- <MaterialCommunityIcons
186
- name="checkbox-marked"
187
- size={25}
188
- color={theme.colors.primary}
189
- />
190
- ) : (
191
- <MaterialCommunityIcons
192
- name="checkbox-blank-outline"
193
- size={25}
194
- color={theme.colors.disabled}
195
- />
196
- )}
197
- <OText size={12} style={{ flex: 1, marginLeft: 15 }}>{walletName[wallet.type]?.name}</OText>
198
- {wallet.type === 'cash' && (
199
- <OText>
200
- {parsePrice(wallet?.balance, { isTruncable: true })}
201
- </OText>
202
- )}
203
- {wallet.type === 'credit_point' && (
204
- <OText>
205
- <OText color={theme.colors.primary} weight='bold'>
206
- {`${wallet?.balance} ${t('POINTS', 'Points')}`}
207
- </OText>
208
- <OText>
209
- {wallet?.balance > 0
210
- ? creditBalance(wallet)
211
- : null}
212
- </OText>
213
- </OText>
214
- )}
215
- </WalletItem>
216
- ))}
234
+ .map((wallet: any, idx: any) => walletName[wallet.type]?.isActive &&
235
+ (
236
+ <WalletItem
237
+ key={wallet.type}
238
+ isBottomBorder={idx === paymethodsAndWallets.wallets?.length - 1}
239
+ onPress={() => handleSelectWallet(!!!walletsPaymethod?.find((walletPay: any) => walletPay.wallet_id === wallet.id)?.id, wallet)}
240
+ >
241
+ {!!walletsPaymethod?.find((walletPay: any) => walletPay.wallet_id === wallet.id)?.id ? (
242
+ <MaterialCommunityIcons
243
+ name="checkbox-marked"
244
+ size={25}
245
+ color={theme.colors.primary}
246
+ />
247
+ ) : (
248
+ <MaterialCommunityIcons
249
+ name="checkbox-blank-outline"
250
+ size={25}
251
+ color={theme.colors.disabled}
252
+ />
253
+ )}
254
+ <OText size={12} style={{ flex: 1, marginLeft: 15 }}>{walletName[wallet.type]?.name}</OText>
255
+ {wallet.type === 'cash' && (
256
+ <OText>
257
+ {parsePrice(wallet?.balance, { isTruncable: true })}
258
+ </OText>
259
+ )}
260
+ {wallet.type === 'credit_point' && (
261
+ <OText>
262
+ <OText color={theme.colors.primary} weight='bold'>
263
+ {`${wallet?.balance} ${t('POINTS', 'Points')}`}
264
+ </OText>
265
+ <OText>
266
+ {wallet?.balance > 0
267
+ ? creditBalance(wallet)
268
+ : null}
269
+ </OText>
270
+ </OText>
271
+ )}
272
+ </WalletItem>
273
+ ))}
217
274
  </>
218
275
  )}
219
276
 
@@ -230,6 +287,7 @@ const MultiCartsPaymethodsAndWalletsUI = (props: any) => {
230
287
  enabled={Platform.OS === 'ios' ? true : false}
231
288
  >
232
289
  <StripeElementsForm
290
+ openCarts={openCarts}
233
291
  toSave
234
292
  businessId={businessIds[0]}
235
293
  businessIds={businessIds}
@@ -64,7 +64,8 @@ const MultiCheckoutUI = (props: any) => {
64
64
  totalCartsFee,
65
65
  cartGroup,
66
66
  walletState,
67
- onNavigationRedirectReplace
67
+ onNavigationRedirectReplace,
68
+ merchantId
68
69
  } = props
69
70
 
70
71
  const theme = useTheme();
@@ -88,9 +89,6 @@ const MultiCheckoutUI = (props: any) => {
88
89
  const isPreOrder = configs?.preorder_status_enabled?.value === '1'
89
90
  const isMultiDriverTips = configs?.checkout_multi_business_enabled?.value === '1'
90
91
  const walletCarts = (Object.values(carts)?.filter((cart: any) => cart?.products && cart?.products?.length && cart?.status !== 2 && cart?.valid_schedule && cart?.valid_products && cart?.valid_address && cart?.valid_maximum && cart?.valid_minimum && cart?.wallets) || null) || []
91
- const isDisablePlaceOrderButton = cartGroup?.loading || (!(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) && cartGroup?.result?.balance > 0) ||
92
- (paymethodSelected?.paymethod?.gateway === 'stripe' && !paymethodSelected?.paymethod_data) ||
93
- walletCarts.length > 0
94
92
 
95
93
  const driverTipsOptions = typeof configs?.driver_tip_options?.value === 'string'
96
94
  ? JSON.parse(configs?.driver_tip_options?.value) || []
@@ -121,6 +119,13 @@ const MultiCheckoutUI = (props: any) => {
121
119
  const [isUserDetailsEdit, setIsUserDetailsEdit] = useState(false);
122
120
  const [phoneUpdate, setPhoneUpdate] = useState(false);
123
121
  const [userErrors, setUserErrors] = useState<any>([]);
122
+ const [placeByMethodPay, setPlaceByMethodPay] = useState(false)
123
+ const [methodPaySupported, setMethodPaySupported] = useState({ enabled: false, message: null, loading: true })
124
+ const methodsPay = ['global_google_pay', 'global_apple_pay']
125
+ const isDisablePlaceOrderButton = cartGroup?.loading || (!(paymethodSelected?.paymethod_id || paymethodSelected?.wallet_id) && cartGroup?.result?.balance > 0) ||
126
+ (paymethodSelected?.paymethod?.gateway === 'stripe' && !paymethodSelected?.paymethod_data) ||
127
+ walletCarts.length > 0
128
+ || (methodsPay.includes(paymethodSelected?.gateway) && (!methodPaySupported.enabled || methodPaySupported.loading))
124
129
 
125
130
  const handleMomentClick = () => {
126
131
  if (isPreOrder) {
@@ -284,6 +289,13 @@ const MultiCheckoutUI = (props: any) => {
284
289
  handleSelectWallet={handleSelectWallet}
285
290
  handlePaymethodDataChange={handlePaymethodDataChange}
286
291
  cartUuid={cartUuid}
292
+ merchantId={merchantId}
293
+ setMethodPaySupported={setMethodPaySupported}
294
+ methodPaySupported={methodPaySupported}
295
+ placeByMethodPay={placeByMethodPay}
296
+ setPlaceByMethodPay={setPlaceByMethodPay}
297
+ cartTotal={totalCartsPrice}
298
+ handlePlaceOrder={handlePlaceOrder}
287
299
  />
288
300
  <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
289
301
  </ChSection>
@@ -294,51 +306,51 @@ const MultiCheckoutUI = (props: any) => {
294
306
  validationFields?.fields?.checkout?.driver_tip?.enabled &&
295
307
  openCarts.every((cart: any) => cart.business_id && cart.status !== 2) &&
296
308
  driverTipsOptions && driverTipsOptions?.length > 0 &&
297
- (
298
- <ChSection>
299
- <DriverTipsContainer>
300
- <OText size={14} lineHeight={20} color={theme.colors.textNormal}>
301
- {t('DRIVER_TIPS', 'Driver Tips')}
302
- </OText>
303
- <DriverTips
304
- isMulti
305
- carts={openCarts}
306
- businessIds={openCarts.map((cart: any) => cart.business_id)}
307
- driverTipsOptions={driverTipsOptions}
308
- isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1}
309
- isDriverTipUseCustom={!!parseInt(configs?.driver_tip_use_custom?.value, 10)}
310
- driverTip={parseInt(configs?.driver_tip_type?.value, 10) === 1
311
- ? openCarts[0]?.driver_tip
312
- : openCarts[0]?.driver_tip_rate}
313
- useOrderContext
314
- />
315
- </DriverTipsContainer>
316
- <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
317
- </ChSection>
318
- )}
309
+ (
310
+ <ChSection>
311
+ <DriverTipsContainer>
312
+ <OText size={14} lineHeight={20} color={theme.colors.textNormal}>
313
+ {t('DRIVER_TIPS', 'Driver Tips')}
314
+ </OText>
315
+ <DriverTips
316
+ isMulti
317
+ carts={openCarts}
318
+ businessIds={openCarts.map((cart: any) => cart.business_id)}
319
+ driverTipsOptions={driverTipsOptions}
320
+ isFixedPrice={parseInt(configs?.driver_tip_type?.value, 10) === 1}
321
+ isDriverTipUseCustom={!!parseInt(configs?.driver_tip_use_custom?.value, 10)}
322
+ driverTip={parseInt(configs?.driver_tip_type?.value, 10) === 1
323
+ ? openCarts[0]?.driver_tip
324
+ : openCarts[0]?.driver_tip_rate}
325
+ useOrderContext
326
+ />
327
+ </DriverTipsContainer>
328
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
329
+ </ChSection>
330
+ )}
319
331
 
320
332
  {
321
333
  validationFields?.fields?.checkout?.coupon?.enabled &&
322
334
  openCarts.every((cart: any) => cart.business_id && cart.status !== 2) &&
323
335
  configs?.multi_business_checkout_coupon_input_style?.value === 'group' &&
324
- (
325
- <ChSection>
326
- <OText size={14} lineHeight={20} color={theme.colors.textNormal}>
327
- {t('DISCOUNT_COUPON', 'Discount coupon')}
328
- </OText>
329
- <OSTable>
330
- <OSCoupon>
331
- <CouponControl
332
- isMulti
333
- carts={openCarts}
334
- businessIds={openCarts.map((cart: any) => cart.business_id)}
335
- price={openCarts.reduce((total: any, cart: any) => total + cart.total, 0)}
336
- />
337
- </OSCoupon>
338
- </OSTable>
339
- <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
340
- </ChSection>
341
- )}
336
+ (
337
+ <ChSection>
338
+ <OText size={14} lineHeight={20} color={theme.colors.textNormal}>
339
+ {t('DISCOUNT_COUPON', 'Discount coupon')}
340
+ </OText>
341
+ <OSTable>
342
+ <OSCoupon>
343
+ <CouponControl
344
+ isMulti
345
+ carts={openCarts}
346
+ businessIds={openCarts.map((cart: any) => cart.business_id)}
347
+ price={openCarts.reduce((total: any, cart: any) => total + cart.total, 0)}
348
+ />
349
+ </OSCoupon>
350
+ </OSTable>
351
+ <View style={{ height: 8, backgroundColor: theme.colors.backgroundGray100, marginTop: 13, marginHorizontal: -40 }} />
352
+ </ChSection>
353
+ )}
342
354
 
343
355
  <ChSection>
344
356
  <ChCarts>
@@ -390,15 +402,15 @@ const MultiCheckoutUI = (props: any) => {
390
402
  )}
391
403
  {openCarts.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0) > 0 &&
392
404
  configs?.multi_business_checkout_show_combined_driver_tip?.value === '1' && (
393
- <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
394
- <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
395
- {t('DRIVER_TIP', 'Driver tip')}
396
- </OText>
397
- <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
398
- {parsePrice(openCarts.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0))}
399
- </OText>
400
- </View>
401
- )}
405
+ <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
406
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
407
+ {t('DRIVER_TIP', 'Driver tip')}
408
+ </OText>
409
+ <OText size={14} lineHeight={24} color={theme.colors.textNormal} weight={'400'}>
410
+ {parsePrice(openCarts.reduce((sum: any, cart: any) => sum + cart?.driver_tip, 0))}
411
+ </OText>
412
+ </View>
413
+ )}
402
414
  <View style={{ flexDirection: 'row', justifyContent: 'space-between' }}>
403
415
  <OText size={16} lineHeight={24} color={theme.colors.textNormal} weight={'500'}>
404
416
  {t('TOTAL_FOR_ALL_CARTS', 'Total for all Carts')}
@@ -423,7 +435,9 @@ const MultiCheckoutUI = (props: any) => {
423
435
  </Container>
424
436
 
425
437
  <FloatingButton
426
- handleClick={() => handlePlaceOrder()}
438
+ handleClick={methodsPay.includes(paymethodSelected?.gateway)
439
+ ? () => setPlaceByMethodPay(true)
440
+ : () => handlePlaceOrder()}
427
441
  isSecondaryBtn={isDisablePlaceOrderButton}
428
442
  disabled={isDisablePlaceOrderButton}
429
443
  btnText={placing ? t('PLACING', 'Placing') : t('PLACE_ORDER', 'Place Order')}
@@ -34,7 +34,7 @@ import { useApplePay } from '@stripe/stripe-react-native';
34
34
 
35
35
  const stripeOptions: any = ['stripe_direct', 'stripe', 'stripe_connect']
36
36
  const methodsPay = ['google_pay', 'apple_pay']
37
- const stripeDirectMethods = ['stripe_direct', ...methodsPay]
37
+ const stripeDirectMethods = ['stripe_direct']
38
38
  // const stripeRedirectOptions = [
39
39
  // { name: 'Bancontact', value: 'bancontact' },
40
40
  // { name: 'Alipay', value: 'alipay' },
@@ -43,6 +43,7 @@ const stripeDirectMethods = ['stripe_direct', ...methodsPay]
43
43
  // ]
44
44
 
45
45
  const webViewPaymentGateway: any = ['paypal', 'square']
46
+ const multiCheckoutMethods = ['global_google_pay', 'global_apple_pay']
46
47
 
47
48
  const PaymentOptionsUI = (props: any) => {
48
49
  const {
@@ -59,7 +60,11 @@ const PaymentOptionsUI = (props: any) => {
59
60
  isOpenMethod,
60
61
  handlePaymentMethodClickCustom,
61
62
  handlePlaceOrder,
62
- merchantId
63
+ merchantId,
64
+ setMethodPaySupported,
65
+ placeByMethodPay,
66
+ methodPaySupported,
67
+ setPlaceByMethodPay
63
68
  } = props
64
69
 
65
70
  const theme = useTheme();
@@ -187,6 +192,7 @@ const PaymentOptionsUI = (props: any) => {
187
192
  }
188
193
 
189
194
  const excludeIds: any = [32]; //exclude paypal & connect & redirect
195
+ const filterMethodsPay = (gateway : string) => Platform.OS === 'ios' ? gateway !== 'google_pay' : gateway !== 'apple_pay'
190
196
 
191
197
  return (
192
198
  <PMContainer>
@@ -195,7 +201,11 @@ const PaymentOptionsUI = (props: any) => {
195
201
  horizontal
196
202
  showsHorizontalScrollIndicator={false}
197
203
  // data={paymethodsList.paymethods.sort((a: any, b: any) => a.id - b.id)}
198
- data={paymethodsList.paymethods.sort((a: any, b: any) => a.id - b.id).filter((p: any) => !excludeIds.includes(p.id))}
204
+ data={paymethodsList.paymethods.sort((a: any, b: any) => a.id - b.id)
205
+ .filter((p: any) =>
206
+ !multiCheckoutMethods.includes(p.gateway) &&
207
+ filterMethodsPay(p.gateway) &&
208
+ !excludeIds.includes(p.id))}
199
209
  renderItem={renderPaymethods}
200
210
  keyExtractor={(paymethod: any) => paymethod?.id?.toString?.()}
201
211
  />
@@ -296,6 +306,23 @@ const PaymentOptionsUI = (props: any) => {
296
306
  />
297
307
  </View>
298
308
  )}
309
+ {/* Google pay, Apple pay */}
310
+ {methodsPay.includes(isOpenMethod?.paymethod?.gateway) && (
311
+ <StripeElementsForm
312
+ cart={cart}
313
+ paymethod={isOpenMethod?.paymethod?.gateway}
314
+ methodsPay={methodsPay}
315
+ businessId={props.businessId}
316
+ publicKey={isOpenMethod?.paymethod?.credentials?.publishable || isOpenMethod?.paymethod?.credentials?.publishable_key}
317
+ handleSource={handlePaymethodDataChange}
318
+ onCancel={() => handlePaymethodClick(null)}
319
+ merchantId={merchantId}
320
+ setMethodPaySupported={setMethodPaySupported}
321
+ methodPaySupported={methodPaySupported}
322
+ placeByMethodPay={placeByMethodPay}
323
+ setPlaceByMethodPay={setPlaceByMethodPay}
324
+ />
325
+ )}
299
326
 
300
327
  <OModal
301
328
  entireModal
@@ -320,7 +347,7 @@ const PaymentOptionsUI = (props: any) => {
320
347
  </KeyboardAvoidingView>
321
348
  </OModal>
322
349
 
323
- {/* Stripe direct, Google pay, Apple pay */}
350
+ {/* Stripe direct */}
324
351
  <OModal
325
352
  entireModal
326
353
  title={t('ADD_CREDIT_OR_DEBIT_CARD', 'Add credit or debit card')}
@@ -28,7 +28,12 @@ const StripeElementsFormUI = (props: any) => {
28
28
  onCancel,
29
29
  cart,
30
30
  merchantId,
31
- businessIds
31
+ businessIds,
32
+ setMethodPaySupported,
33
+ placeByMethodPay,
34
+ methodPaySupported,
35
+ setPlaceByMethodPay,
36
+ cartTotal
32
37
  } = props;
33
38
 
34
39
  const theme = useTheme();
@@ -78,24 +83,24 @@ const StripeElementsFormUI = (props: any) => {
78
83
 
79
84
  if (user?.address) {
80
85
  billingDetails.address = {
81
- line1: user?.address
82
- }
86
+ line1: user?.address
87
+ }
83
88
  }
84
89
 
85
90
  const createPayMethod = async () => {
86
91
  const params: any = { paymentMethodType: 'Card', paymentMethodData: {} }
87
92
  if (Object.keys(billingDetails).length > 0) {
88
- params.paymentMethodData.billingDetails = {...billingDetails, token: card?.last4}
93
+ params.paymentMethodData.billingDetails = { ...billingDetails, token: card?.last4 }
89
94
  }
90
95
  try {
91
96
  setCreatePmLoading(true)
92
97
  const { paymentMethod, error } = await createPaymentMethod(params);
93
98
 
94
- if (error) {
95
- setErrors(error?.message);
96
- setCreatePmLoading(false)
97
- return
98
- }
99
+ if (error) {
100
+ setErrors(error?.message);
101
+ setCreatePmLoading(false)
102
+ return
103
+ }
99
104
 
100
105
  setCreatePmLoading(false)
101
106
  handleSource && handleSource({
@@ -118,7 +123,7 @@ const StripeElementsFormUI = (props: any) => {
118
123
  setErrors(error?.message || error?.toString());
119
124
  }
120
125
  }
121
-
126
+
122
127
  const handleSaveCard = async () => {
123
128
  setErrors('');
124
129
  if (!requirements) {
@@ -127,7 +132,7 @@ const StripeElementsFormUI = (props: any) => {
127
132
  }
128
133
  const params: any = { paymentMethodType: 'Card', paymentMethodData: {} }
129
134
  if (Object.keys(billingDetails).length > 0) {
130
- params.paymentMethodData.billingDetails = {...billingDetails, token: card?.last4}
135
+ params.paymentMethodData.billingDetails = { ...billingDetails, token: card?.last4 }
131
136
  }
132
137
  try {
133
138
  const { setupIntent, error } = await confirmSetupIntent(requirements, params);
@@ -135,8 +140,8 @@ const StripeElementsFormUI = (props: any) => {
135
140
  if (setupIntent?.status === 'Succeeded') {
136
141
  if (businessIds) {
137
142
  businessIds.forEach((_businessId: any, index: any) => {
138
- const _isNewCard = index === 0
139
- stripeTokenHandler(setupIntent?.paymentMethodId, user, businessId, _isNewCard);
143
+ const _isNewCard = index === 0
144
+ stripeTokenHandler(setupIntent?.paymentMethodId, user, businessId, _isNewCard);
140
145
  })
141
146
  } else {
142
147
  stripeTokenHandler(setupIntent?.paymentMethodId, user, businessId);
@@ -188,7 +193,7 @@ const StripeElementsFormUI = (props: any) => {
188
193
  }, []);
189
194
 
190
195
  return (
191
- <View style={{ ...styles.container, height: height - top - bottom - 60 - (isKeyboardShow ? 250 : 0) }}>
196
+ <View style={{ ...styles.container, height: methodsPay?.includes(paymethod) ? 'auto' : height - top - bottom - 60 - (isKeyboardShow ? 250 : 0) }}>
192
197
  {publicKey ? (
193
198
  <View style={{ flex: 1 }}>
194
199
  <StripeProvider
@@ -201,9 +206,14 @@ const StripeElementsFormUI = (props: any) => {
201
206
  handleSource={handleSource}
202
207
  onCancel={onCancel}
203
208
  cart={cart}
209
+ cartTotal={cartTotal}
204
210
  setErrors={setErrors}
205
211
  paymethod={paymethod}
206
212
  devMode={publicKey?.includes('test')}
213
+ setMethodPaySupported={setMethodPaySupported}
214
+ placeByMethodPay={placeByMethodPay}
215
+ methodPaySupported={methodPaySupported}
216
+ setPlaceByMethodPay={setPlaceByMethodPay}
207
217
  />
208
218
  ) : (
209
219
  <CardField