@eventlook/sdk 1.7.3 → 1.7.4
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/dist/cjs/index-EJYDEfV5.js +41925 -0
- package/dist/cjs/index-EJYDEfV5.js.map +1 -0
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.umd-CfKeY_Zj.js +13397 -0
- package/dist/cjs/index.umd-CfKeY_Zj.js.map +1 -0
- package/dist/esm/index-CAjHrQdF.js +41904 -0
- package/dist/esm/index-CAjHrQdF.js.map +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/index.umd-DjIEPZqJ.js +13395 -0
- package/dist/esm/index.umd-DjIEPZqJ.js.map +1 -0
- package/dist/types/form/Payment.d.ts +1 -0
- package/dist/types/form/payment/StripeCheckoutProvider.d.ts +36 -0
- package/dist/types/hooks/data/useStripeConfig.d.ts +3 -0
- package/dist/types/locales/cs.d.ts +3 -0
- package/dist/types/locales/en.d.ts +3 -0
- package/dist/types/locales/es.d.ts +3 -0
- package/dist/types/locales/pl.d.ts +3 -0
- package/dist/types/locales/sk.d.ts +3 -0
- package/dist/types/locales/uk.d.ts +3 -0
- package/dist/types/modules/order.d.ts +3 -0
- package/dist/types/utils/types/order.type.d.ts +2 -0
- package/dist/types/utils/types/payment-method.type.d.ts +1 -0
- package/package.json +3 -1
- package/src/form/Payment.tsx +42 -3
- package/src/form/PaymentOverviewBox.tsx +28 -9
- package/src/form/TicketForm.tsx +262 -167
- package/src/form/payment/StripeCheckoutProvider.tsx +154 -0
- package/src/form/tickets/TicketSelectionMobile.tsx +1 -1
- package/src/hooks/data/useStripeConfig.ts +14 -0
- package/src/locales/cs.tsx +3 -0
- package/src/locales/en.tsx +3 -0
- package/src/locales/es.tsx +3 -0
- package/src/locales/pl.tsx +3 -0
- package/src/locales/sk.tsx +3 -0
- package/src/locales/uk.tsx +3 -0
- package/src/modules/order.ts +3 -0
- package/src/utils/types/order.type.ts +5 -0
- package/src/utils/types/payment-method.type.ts +1 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { MutableRefObject } from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Imperative handle the order form uses to drive the inline Stripe payment from
|
|
4
|
+
* its own submit handler (which lives outside the <Elements> tree).
|
|
5
|
+
*/
|
|
6
|
+
export interface StripeCheckoutApi {
|
|
7
|
+
ready: boolean;
|
|
8
|
+
/** Validate + collect the card fields. Returns an error message, or null. */
|
|
9
|
+
submit: () => Promise<string | null>;
|
|
10
|
+
/** Confirm the server-created PaymentIntent. */
|
|
11
|
+
confirm: (clientSecret: string, returnUrl: string) => Promise<{
|
|
12
|
+
ok: boolean;
|
|
13
|
+
error?: string;
|
|
14
|
+
}>;
|
|
15
|
+
}
|
|
16
|
+
interface Props {
|
|
17
|
+
/** Mount Elements only when a Stripe method is offered and the key is loaded. */
|
|
18
|
+
active: boolean;
|
|
19
|
+
publishableKey: string | null;
|
|
20
|
+
/** 'payment' for paid orders, 'setup' for free (0-amount) card verification. */
|
|
21
|
+
mode: 'payment' | 'setup';
|
|
22
|
+
/** Charge amount in minor units (used by Elements; the server intent is authoritative). */
|
|
23
|
+
amount: number;
|
|
24
|
+
currency: string;
|
|
25
|
+
locale: string;
|
|
26
|
+
apiRef: MutableRefObject<StripeCheckoutApi | null>;
|
|
27
|
+
children: React.ReactNode;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Wraps the order form in a deferred-mode <Elements> provider so the Payment
|
|
31
|
+
* Element can be shown inline (expanded under the selected method) before the
|
|
32
|
+
* order — and its PaymentIntent — exists. When no Stripe method is on offer it
|
|
33
|
+
* renders children untouched and loads nothing.
|
|
34
|
+
*/
|
|
35
|
+
declare const StripeCheckoutProvider: React.FC<Props>;
|
|
36
|
+
export default StripeCheckoutProvider;
|
|
@@ -44,6 +44,9 @@ declare const cs: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -44,6 +44,9 @@ declare const en: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -44,6 +44,9 @@ declare const es: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -44,6 +44,9 @@ declare const pl: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -44,6 +44,9 @@ declare const sk: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -44,6 +44,9 @@ declare const uk: {
|
|
|
44
44
|
total: string;
|
|
45
45
|
with_fee: string;
|
|
46
46
|
service_fee: string;
|
|
47
|
+
payment_processing_fee: string;
|
|
48
|
+
card_payment_title: string;
|
|
49
|
+
card_payment_error: string;
|
|
47
50
|
shipping_fee: string;
|
|
48
51
|
ticket_insurance: string;
|
|
49
52
|
price_including_service_fee: string;
|
|
@@ -5,3 +5,6 @@ import { Currencies } from '@utils/data/currency';
|
|
|
5
5
|
export declare const postOrder: (data: ITicketBody) => Promise<IResponse<IOrderCreate>>;
|
|
6
6
|
export declare const getAllowedPaymentMethods: (currency: Currencies, eventId?: number) => Promise<any>;
|
|
7
7
|
export declare const postOrderPaid: (data: IOrderPaidData) => Promise<IResponse<IOrderPaid>>;
|
|
8
|
+
export declare const getStripeConfig: () => Promise<{
|
|
9
|
+
publishableKey: string | null;
|
|
10
|
+
}>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@eventlook/sdk",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.4",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/esm/index.js",
|
|
6
6
|
"types": "dist/types/index.d.ts",
|
|
@@ -56,6 +56,8 @@
|
|
|
56
56
|
"@rollup/plugin-replace": "^6.0.3",
|
|
57
57
|
"@rollup/plugin-typescript": "^12.3.0",
|
|
58
58
|
"@seat-picker/seat-picker-sdk": "^1.2.0",
|
|
59
|
+
"@stripe/react-stripe-js": "^6.6.0",
|
|
60
|
+
"@stripe/stripe-js": "^9.7.0",
|
|
59
61
|
"@types/js-cookie": "^3.0.6",
|
|
60
62
|
"@types/lodash": "^4.17.24",
|
|
61
63
|
"@types/numeral": "^2.0.5",
|
package/src/form/Payment.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import React, { KeyboardEvent, useEffect, useMemo, useState } from 'react';
|
|
|
2
2
|
import {
|
|
3
3
|
Box,
|
|
4
4
|
Button,
|
|
5
|
+
CircularProgress,
|
|
5
6
|
Divider,
|
|
6
7
|
FormControl,
|
|
7
8
|
FormControlLabel,
|
|
@@ -19,6 +20,7 @@ import { PaymentItem, PaymentWrapper, PaymentSwiftWrapper } from '@form/style';
|
|
|
19
20
|
import Image from '@components/Image';
|
|
20
21
|
import Label from '@components/Label';
|
|
21
22
|
import PaymentSkeleton from '@form/payment/PaymentSkeleton';
|
|
23
|
+
import { PaymentElement } from '@stripe/react-stripe-js';
|
|
22
24
|
import { RHFRadioGroup } from '@components/hook-form';
|
|
23
25
|
import { postPromoCodeApply } from '@modules/promo-code';
|
|
24
26
|
import { IEvent } from '@utils/types/event.type';
|
|
@@ -32,9 +34,12 @@ import { IEventProductForm } from '@utils/types/product.type';
|
|
|
32
34
|
|
|
33
35
|
interface Props {
|
|
34
36
|
event: IEvent;
|
|
37
|
+
// True once the Stripe Elements provider is mounted (key loaded), so the
|
|
38
|
+
// inline Payment Element can render under the selected Stripe method.
|
|
39
|
+
stripeReady?: boolean;
|
|
35
40
|
}
|
|
36
41
|
|
|
37
|
-
const Payment: React.FC<Props> = ({ event }) => {
|
|
42
|
+
const Payment: React.FC<Props> = ({ event, stripeReady }) => {
|
|
38
43
|
const { t, lang } = useGlobal();
|
|
39
44
|
const { showSnackbar } = useGlobal();
|
|
40
45
|
const { data, isLoading } = useAllowedPaymentMethods(event.currency, event.id);
|
|
@@ -174,8 +179,12 @@ const Payment: React.FC<Props> = ({ event }) => {
|
|
|
174
179
|
|
|
175
180
|
if (total === 0 && (hasTickets || hasProducts)) {
|
|
176
181
|
setValue('isPaymentVerify', true);
|
|
177
|
-
|
|
178
|
-
|
|
182
|
+
// Free orders only offer card-verification methods (incl. Stripe, which
|
|
183
|
+
// verifies via a SetupIntent) — bot protection without a charge.
|
|
184
|
+
return data.filter(
|
|
185
|
+
(payment) =>
|
|
186
|
+
['PAYMENT_CARD', 'APPLE_PAY', 'GPAY', 'CLICK_TO_PAY'].includes(payment.type) ||
|
|
187
|
+
payment.provider === 'STRIPE'
|
|
179
188
|
);
|
|
180
189
|
} else {
|
|
181
190
|
setValue('isPaymentVerify', false);
|
|
@@ -334,6 +343,36 @@ const Payment: React.FC<Props> = ({ event }) => {
|
|
|
334
343
|
/>
|
|
335
344
|
</PaymentSwiftWrapper>
|
|
336
345
|
)}
|
|
346
|
+
{payment.provider === 'STRIPE' &&
|
|
347
|
+
!!paymentMethodId &&
|
|
348
|
+
Number(paymentMethodId) === payment.id && (
|
|
349
|
+
<PaymentSwiftWrapper sx={{ pb: 3 }}>
|
|
350
|
+
<Divider sx={{ mb: 2 }} />
|
|
351
|
+
{stripeReady ? (
|
|
352
|
+
<PaymentElement options={{ layout: 'tabs' }} />
|
|
353
|
+
) : Number(total) > 0 ? (
|
|
354
|
+
<Stack alignItems="center" sx={{ py: 3 }}>
|
|
355
|
+
<CircularProgress size={26} />
|
|
356
|
+
</Stack>
|
|
357
|
+
) : (
|
|
358
|
+
<Stack
|
|
359
|
+
alignItems="center"
|
|
360
|
+
spacing={1}
|
|
361
|
+
sx={{ py: 3, px: 2, textAlign: 'center' }}
|
|
362
|
+
>
|
|
363
|
+
<Iconify
|
|
364
|
+
icon="carbon:shopping-cart"
|
|
365
|
+
width={28}
|
|
366
|
+
height={28}
|
|
367
|
+
sx={{ color: 'text.disabled' }}
|
|
368
|
+
/>
|
|
369
|
+
<Typography variant="body2" sx={{ color: 'text.secondary' }}>
|
|
370
|
+
{t('form.validation.count_tickets_or_products')}
|
|
371
|
+
</Typography>
|
|
372
|
+
</Stack>
|
|
373
|
+
)}
|
|
374
|
+
</PaymentSwiftWrapper>
|
|
375
|
+
)}
|
|
337
376
|
</PaymentItem>
|
|
338
377
|
))}
|
|
339
378
|
</RadioGroup>
|
|
@@ -42,6 +42,7 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
42
42
|
const insuranceAvailable = isInsuranceAvailable(event.currency);
|
|
43
43
|
const { data: eventProducts } = useActiveEventProducts(event.id, true);
|
|
44
44
|
const [shippingFee, setShippingFee] = useState(0);
|
|
45
|
+
const [paymentMethodFee, setPaymentMethodFee] = useState(0);
|
|
45
46
|
const { setValue, watch } = useFormContext<ITicketForm>();
|
|
46
47
|
const values = watch();
|
|
47
48
|
const {
|
|
@@ -135,6 +136,10 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
135
136
|
}, [event, flatProducts]);
|
|
136
137
|
|
|
137
138
|
const getFee = useMemo(() => fCurrency(totalFee ?? 0, lang, event.currency), [totalFee]);
|
|
139
|
+
const getPaymentMethodFee = useMemo(
|
|
140
|
+
() => fCurrency(paymentMethodFee ?? 0, lang, event.currency),
|
|
141
|
+
[paymentMethodFee]
|
|
142
|
+
);
|
|
138
143
|
|
|
139
144
|
const shoppingCartBody = useMemo<ICalculateShoppingCartDto>(
|
|
140
145
|
() => ({
|
|
@@ -253,8 +258,10 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
253
258
|
setValue('originalPrice', data.originalPrice);
|
|
254
259
|
setValue('total', data.totalPrice || 0);
|
|
255
260
|
|
|
256
|
-
|
|
257
|
-
|
|
261
|
+
// The Stripe processing surcharge is shown as its own line, so keep the
|
|
262
|
+
// service fee and the payment-method fee separate.
|
|
263
|
+
setValue('totalFee', data.serviceFee ?? 0);
|
|
264
|
+
setPaymentMethodFee(data.paymentMethodFee ?? 0);
|
|
258
265
|
|
|
259
266
|
setShippingFee(data.shippingFee);
|
|
260
267
|
setValue('ticketInsurance', data.ticketInsurance.enabled);
|
|
@@ -480,15 +487,21 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
480
487
|
)}
|
|
481
488
|
<Stack
|
|
482
489
|
className="overview-card__order-info"
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
490
|
+
// Keep horizontal padding on mobile even when `withoutPadding` — that
|
|
491
|
+
// flag is only meant to drop the vertical gap under the header, not let
|
|
492
|
+
// the rows run into the card edge.
|
|
493
|
+
sx={{
|
|
494
|
+
px: 2,
|
|
495
|
+
pt: { xs: 1.5, sm: 2 },
|
|
496
|
+
pb: { xs: withoutPadding ? 0 : 2, md: 2 },
|
|
497
|
+
}}
|
|
498
|
+
spacing={1.25}
|
|
486
499
|
useFlexGap
|
|
487
500
|
>
|
|
488
|
-
{!!selectedTickets.length && !isMobile && <Divider sx={{ borderStyle: 'dashed' }} />}
|
|
501
|
+
{!!selectedTickets.length && !isMobile && <Divider sx={{ borderStyle: 'dashed', my: 1 }} />}
|
|
489
502
|
|
|
490
503
|
{!!selectedTickets.length && (
|
|
491
|
-
<Stack spacing={
|
|
504
|
+
<Stack spacing={1}>
|
|
492
505
|
{insuranceAvailable && (
|
|
493
506
|
<PaymentOverviewCheckbox
|
|
494
507
|
checkboxName="ticketInsurance"
|
|
@@ -515,7 +528,7 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
515
528
|
</>
|
|
516
529
|
}
|
|
517
530
|
/>
|
|
518
|
-
<Divider sx={{ borderStyle: 'dashed' }} />
|
|
531
|
+
<Divider sx={{ borderStyle: 'dashed', mt: 0.5 }} />
|
|
519
532
|
</Stack>
|
|
520
533
|
)}
|
|
521
534
|
{selectedTickets.map((ticket, index) => (
|
|
@@ -600,8 +613,14 @@ const PaymentOverviewBox: React.FC<Props> = ({ event, withoutPadding, hideBuyBut
|
|
|
600
613
|
<Typography variant="body2">{getFee}</Typography>
|
|
601
614
|
</Stack>
|
|
602
615
|
)}
|
|
616
|
+
{!!total && !!paymentMethodFee && (
|
|
617
|
+
<Stack direction="row" justifyContent="space-between" alignItems="center" spacing={2}>
|
|
618
|
+
<Typography variant="body2">{t('form.labels.payment_processing_fee')}</Typography>
|
|
619
|
+
<Typography variant="body2">{getPaymentMethodFee}</Typography>
|
|
620
|
+
</Stack>
|
|
621
|
+
)}
|
|
603
622
|
{((!!selectedTickets.length && isMobile) || !isMobile) && (
|
|
604
|
-
<Divider sx={{ borderStyle: 'dashed' }} />
|
|
623
|
+
<Divider sx={{ borderStyle: 'dashed', my: 1 }} />
|
|
605
624
|
)}
|
|
606
625
|
{!hideBuyButton && (
|
|
607
626
|
<>
|