ordering-ui-external 14.2.11 → 14.2.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (23) hide show
  1. package/_bundles/{0.ordering-ui.99491aeaa7bd0c4a178e.js → 0.ordering-ui.ab0542c9c03a55329be6.js} +1 -1
  2. package/_bundles/{4.ordering-ui.99491aeaa7bd0c4a178e.js → 4.ordering-ui.ab0542c9c03a55329be6.js} +1 -1
  3. package/_bundles/{7.ordering-ui.99491aeaa7bd0c4a178e.js → 7.ordering-ui.ab0542c9c03a55329be6.js} +1 -1
  4. package/_bundles/{ordering-ui.99491aeaa7bd0c4a178e.js → ordering-ui.ab0542c9c03a55329be6.js} +2 -2
  5. package/_modules/components/StripeElementsForm/index.js +37 -9
  6. package/_modules/components/StripePaymentElementForm/index.js +204 -0
  7. package/_modules/components/StripePaymentElementForm/styles.js +15 -0
  8. package/_modules/index.js +7 -0
  9. package/_modules/themes/five/src/components/StripeElementsForm/index.js +34 -8
  10. package/package.json +2 -2
  11. package/src/components/StripeElementsForm/index.js +60 -32
  12. package/src/components/StripePaymentElementForm/index.js +174 -0
  13. package/src/components/StripePaymentElementForm/styles.js +31 -0
  14. package/src/index.js +2 -0
  15. package/src/themes/five/src/components/StripeElementsForm/index.js +60 -34
  16. /package/_bundles/{1.ordering-ui.99491aeaa7bd0c4a178e.js → 1.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  17. /package/_bundles/{2.ordering-ui.99491aeaa7bd0c4a178e.js → 2.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  18. /package/_bundles/{5.ordering-ui.99491aeaa7bd0c4a178e.js → 5.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  19. /package/_bundles/{6.ordering-ui.99491aeaa7bd0c4a178e.js → 6.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  20. /package/_bundles/{7.ordering-ui.99491aeaa7bd0c4a178e.js.LICENSE.txt → 7.ordering-ui.ab0542c9c03a55329be6.js.LICENSE.txt} +0 -0
  21. /package/_bundles/{8.ordering-ui.99491aeaa7bd0c4a178e.js → 8.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  22. /package/_bundles/{9.ordering-ui.99491aeaa7bd0c4a178e.js → 9.ordering-ui.ab0542c9c03a55329be6.js} +0 -0
  23. /package/_bundles/{ordering-ui.99491aeaa7bd0c4a178e.js.LICENSE.txt → ordering-ui.ab0542c9c03a55329be6.js.LICENSE.txt} +0 -0
@@ -0,0 +1,174 @@
1
+ import React, { useEffect, useMemo, useState } from 'react'
2
+ import {
3
+ PaymentElement,
4
+ useElements,
5
+ useStripe
6
+ } from '@stripe/react-stripe-js'
7
+ import { CardForm as CardFormController, useConfig, useLanguage } from 'ordering-components-external'
8
+ import { Button } from '../../styles/Buttons'
9
+ import {
10
+ Container,
11
+ ErrorMessage,
12
+ FormActions,
13
+ InfoNote,
14
+ PaymentElementWrapper
15
+ } from './styles'
16
+
17
+ const googlePayMethods = ['google_pay', 'global_google_pay']
18
+ const applePayMethods = ['apple_pay', 'global_apple_pay']
19
+
20
+ const getPaymentAmount = (cart, cartGroup) => {
21
+ const total = cartGroup?.balance ?? cartGroup?.total ?? cart?.balance ?? cart?.total ?? 0
22
+ const amountInCents = Math.floor(Number(total) * 100)
23
+ return amountInCents > 0 ? amountInCents : 100
24
+ }
25
+
26
+ const buildPaymethodPayload = (paymentMethod) => {
27
+ const card = paymentMethod?.card
28
+ return {
29
+ ...(card || {}),
30
+ id: paymentMethod.id,
31
+ type: paymentMethod.type,
32
+ source_id: paymentMethod.id,
33
+ card: card
34
+ ? {
35
+ brand: card.brand,
36
+ last4: card.last4
37
+ }
38
+ : undefined
39
+ }
40
+ }
41
+
42
+ export const StripePaymentElementFormUI = (props) => {
43
+ const {
44
+ cart,
45
+ handleSource,
46
+ handleCancel,
47
+ paymethod,
48
+ cartGroup
49
+ } = props
50
+
51
+ const [, t] = useLanguage()
52
+ const [{ configs }] = useConfig()
53
+ const stripe = useStripe()
54
+ const elements = useElements()
55
+ const [error, setError] = useState(null)
56
+ const [loading, setLoading] = useState(false)
57
+ const [isReady, setIsReady] = useState(false)
58
+ const [isGooglePayUnavailable, setIsGooglePayUnavailable] = useState(false)
59
+
60
+ const isGooglePayMethod = googlePayMethods.includes(paymethod)
61
+
62
+ useEffect(() => {
63
+ if (!stripe || !isGooglePayMethod) {
64
+ setIsGooglePayUnavailable(false)
65
+ return
66
+ }
67
+
68
+ let cartNames = ''
69
+ if (cartGroup) {
70
+ cartGroup?.carts?.forEach((groupCart, i) => {
71
+ cartNames = `${groupCart?.business?.name}${i < cartGroup.carts.length - 1 ? ', ' : ''}`
72
+ })
73
+ }
74
+
75
+ const paymentRequest = stripe.paymentRequest({
76
+ country: 'US',
77
+ currency: configs?.stripe_currency?.value?.toLowerCase?.() || 'usd',
78
+ total: {
79
+ label: cartNames || cart?.business?.name || 'Total',
80
+ amount: getPaymentAmount(cart, cartGroup)
81
+ },
82
+ requestPayerName: true,
83
+ requestPayerEmail: true
84
+ })
85
+
86
+ paymentRequest.canMakePayment().then((result) => {
87
+ setIsGooglePayUnavailable(!result?.googlePay)
88
+ })
89
+ }, [stripe, isGooglePayMethod, cart, cartGroup, configs?.stripe_currency?.value])
90
+
91
+ const paymentElementOptions = useMemo(() => {
92
+ const isGooglePay = googlePayMethods.includes(paymethod)
93
+ const isApplePay = applePayMethods.includes(paymethod)
94
+
95
+ return {
96
+ layout: 'tabs',
97
+ wallets: {
98
+ googlePay: isGooglePay ? 'auto' : 'never',
99
+ applePay: isApplePay ? 'auto' : 'never'
100
+ }
101
+ }
102
+ }, [paymethod])
103
+
104
+ const handleSubmit = async (event) => {
105
+ event.preventDefault()
106
+ if (!stripe || !elements) {
107
+ setError(t('STRIPE_LOAD_ERROR', 'Failed to load Stripe properly'))
108
+ return
109
+ }
110
+
111
+ setLoading(true)
112
+ setError(null)
113
+
114
+ const { error: submitError } = await elements.submit()
115
+ if (submitError) {
116
+ setError(submitError.message)
117
+ setLoading(false)
118
+ return
119
+ }
120
+
121
+ const { error: createError, paymentMethod } = await stripe.createPaymentMethod({
122
+ elements
123
+ })
124
+
125
+ if (createError) {
126
+ setError(createError.message)
127
+ setLoading(false)
128
+ return
129
+ }
130
+
131
+ const data = buildPaymethodPayload(paymentMethod)
132
+ handleCancel?.()
133
+ handleSource(cartGroup ? JSON.stringify(data) : data)
134
+ setLoading(false)
135
+ }
136
+
137
+ return (
138
+ <Container onSubmit={handleSubmit}>
139
+ <PaymentElementWrapper>
140
+ <PaymentElement
141
+ options={paymentElementOptions}
142
+ onReady={() => setIsReady(true)}
143
+ onLoadError={(event) => setError(event?.error?.message)}
144
+ />
145
+ </PaymentElementWrapper>
146
+ {isGooglePayUnavailable && (
147
+ <InfoNote role='note'>
148
+ {t(
149
+ 'GOOGLE_PAY_NOT_CONFIGURED_NOTE',
150
+ 'Google Pay is not configured on this device. Add a card to complete your payment normally.'
151
+ )}
152
+ </InfoNote>
153
+ )}
154
+ {error && <ErrorMessage role='alert'>{error}</ErrorMessage>}
155
+ <FormActions>
156
+ <Button
157
+ color='primary'
158
+ type='submit'
159
+ disabled={loading || !isReady || !stripe || !elements}
160
+ >
161
+ {loading ? t('LOADING', 'Loading...') : t('PLACE_ORDER', 'Place order')}
162
+ </Button>
163
+ </FormActions>
164
+ </Container>
165
+ )
166
+ }
167
+
168
+ export const StripePaymentElementForm = (props) => {
169
+ const propsController = {
170
+ ...props,
171
+ UIComponent: StripePaymentElementFormUI
172
+ }
173
+ return <CardFormController {...propsController} />
174
+ }
@@ -0,0 +1,31 @@
1
+ import styled from 'styled-components'
2
+
3
+ export const Container = styled.form`
4
+ width: 100%;
5
+ display: flex;
6
+ flex-direction: column;
7
+ gap: 16px;
8
+ `
9
+
10
+ export const PaymentElementWrapper = styled.div`
11
+ width: 100%;
12
+ min-height: 44px;
13
+ `
14
+
15
+ export const ErrorMessage = styled.p`
16
+ color: #fa755a;
17
+ margin: 0;
18
+ font-size: 14px;
19
+ `
20
+
21
+ export const FormActions = styled.div`
22
+ display: flex;
23
+ justify-content: flex-end;
24
+ `
25
+
26
+ export const InfoNote = styled.p`
27
+ color: #6b7280;
28
+ margin: 0;
29
+ font-size: 13px;
30
+ line-height: 1.5;
31
+ `
package/src/index.js CHANGED
@@ -82,6 +82,7 @@ import { SingleProductCard } from './components/SingleProductCard'
82
82
  import { SmartAppBanner } from './components/SmartAppBanner'
83
83
  import { SpinnerLoader } from './components/SpinnerLoader'
84
84
  import { StripeElementsForm } from './components/StripeElementsForm'
85
+ import { StripePaymentElementForm } from './components/StripePaymentElementForm'
85
86
  import { StripeRedirectForm } from './components/StripeRedirectForm'
86
87
  import { TaxInformation } from './components/TaxInformation'
87
88
  import { UpsellingPage } from './components/UpsellingPage'
@@ -224,6 +225,7 @@ export {
224
225
  SmartAppBanner,
225
226
  SpinnerLoader,
226
227
  StripeElementsForm,
228
+ StripePaymentElementForm,
227
229
  StripeRedirectForm,
228
230
  SidebarMenu,
229
231
  TaxInformation,
@@ -1,14 +1,20 @@
1
- import React from 'react'
2
- import { StripeElementsForm as StripeElementsFormController, useLanguage } from 'ordering-components-external'
1
+ import React, { useMemo } from 'react'
2
+ import { StripeElementsForm as StripeElementsFormController, useConfig, useLanguage } from 'ordering-components-external'
3
3
  import { loadStripe } from '@stripe/stripe-js/pure'
4
4
  import { Elements } from '@stripe/react-stripe-js'
5
5
 
6
+ import { StripePaymentElementForm } from '../../../../../components/StripePaymentElementForm'
6
7
  import {
7
8
  ErrorMessage
8
9
  } from './styles'
9
10
 
10
11
  import { CardForm } from '../CardForm'
11
- import { StripeMethodForm } from '../../../../../components/StripeMethodForm'
12
+
13
+ const getPaymentAmount = (cart, cartGroup) => {
14
+ const total = cartGroup?.balance ?? cartGroup?.total ?? cart?.balance ?? cart?.total ?? 0
15
+ const amountInCents = Math.floor(Number(total) * 100)
16
+ return amountInCents > 0 ? amountInCents : 100
17
+ }
12
18
 
13
19
  const StripeElementsFormUI = (props) => {
14
20
  const {
@@ -26,6 +32,20 @@ const StripeElementsFormUI = (props) => {
26
32
  cartGroup
27
33
  } = props
28
34
  const [, t] = useLanguage()
35
+ const [{ configs }] = useConfig()
36
+ const isWalletPaymethod = methodsPay?.includes(paymethod)
37
+ const stripePromise = useMemo(() => (publicKey ? loadStripe(publicKey) : null), [publicKey])
38
+
39
+ const walletElementsOptions = useMemo(() => {
40
+ if (!isWalletPaymethod) return null
41
+ return {
42
+ mode: 'payment',
43
+ amount: getPaymentAmount(cart, cartGroup),
44
+ currency: configs?.stripe_currency?.value?.toLowerCase?.() || 'usd',
45
+ paymentMethodCreation: 'manual'
46
+ }
47
+ }, [isWalletPaymethod, cart, cartGroup, configs?.stripe_currency?.value])
48
+
29
49
  return (
30
50
  <>
31
51
  {props.beforeElements?.map((BeforeElement, i) => (
@@ -34,37 +54,43 @@ const StripeElementsFormUI = (props) => {
34
54
  </React.Fragment>))}
35
55
  {props.beforeComponents?.map((BeforeComponent, i) => (
36
56
  <BeforeComponent key={i} {...props} />))}
37
- {publicKey ? (
38
- <Elements stripe={loadStripe(publicKey)}>
39
- {methodsPay?.includes(paymethod) ? (
40
- <StripeMethodForm
41
- cart={cart}
42
- cartGroup={cartGroup}
43
- handleSource={handleSource}
44
- onNewCard={onNewCard}
45
- toSave={toSave}
46
- requirements={requirements}
47
- businessId={businessId}
48
- handleCancel={onCancel}
49
- paymethod={paymethod}
50
- handlePlaceOrder={handlePlaceOrder}
51
- />
52
- ) : (
53
- <CardForm
54
- handleSource={handleSource}
55
- onNewCard={onNewCard}
56
- toSave={toSave}
57
- isSplitForm
58
- requirements={requirements}
59
- businessId={businessId}
60
- handleCancel={onCancel}
61
- businessIds={props.businessIds}
62
- />
63
- )}
64
- </Elements>
65
- ) : (
66
- <ErrorMessage>{t('SOMETHING_WRONG', 'Something is wrong!')}</ErrorMessage>
67
- )}
57
+ {publicKey
58
+ ? (
59
+ isWalletPaymethod
60
+ ? (
61
+ <Elements stripe={stripePromise} options={walletElementsOptions}>
62
+ <StripePaymentElementForm
63
+ cart={cart}
64
+ cartGroup={cartGroup}
65
+ handleSource={handleSource}
66
+ onNewCard={onNewCard}
67
+ toSave={toSave}
68
+ requirements={requirements}
69
+ businessId={businessId}
70
+ handleCancel={onCancel}
71
+ paymethod={paymethod}
72
+ handlePlaceOrder={handlePlaceOrder}
73
+ />
74
+ </Elements>
75
+ )
76
+ : (
77
+ <Elements stripe={stripePromise}>
78
+ <CardForm
79
+ handleSource={handleSource}
80
+ onNewCard={onNewCard}
81
+ toSave={toSave}
82
+ isSplitForm
83
+ requirements={requirements}
84
+ businessId={businessId}
85
+ handleCancel={onCancel}
86
+ businessIds={props.businessIds}
87
+ />
88
+ </Elements>
89
+ )
90
+ )
91
+ : (
92
+ <ErrorMessage>{t('SOMETHING_WRONG', 'Something is wrong!')}</ErrorMessage>
93
+ )}
68
94
  {props.afterComponents?.map((AfterComponent, i) => (
69
95
  <AfterComponent key={i} {...props} />))}
70
96
  {props.afterElements?.map((AfterElement, i) => (