@eventlook/sdk 1.7.2 → 1.7.3-beta.0
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/.prettierignore +3 -0
- package/CLAUDE.md +33 -0
- package/dist/cjs/{index-D1KZ-2U1.js → index-CXsZ9BsP.js} +26476 -25947
- package/dist/cjs/index-CXsZ9BsP.js.map +1 -0
- package/dist/cjs/index-DgOx9uHQ.js +41917 -0
- package/dist/cjs/index-DgOx9uHQ.js.map +1 -0
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/{index.umd-C2KzR75H.js → index.umd-DR37hmpO.js} +2 -2
- package/dist/cjs/{index.umd-C2KzR75H.js.map → index.umd-DR37hmpO.js.map} +1 -1
- package/dist/cjs/index.umd-TbjzhsUx.js +13397 -0
- package/dist/cjs/index.umd-TbjzhsUx.js.map +1 -0
- package/dist/cjs/{mui-tel-input.es-Bjml407E.js → mui-tel-input.es-Dk9M_v4X.js} +6 -6
- package/dist/{esm/mui-tel-input.es-Bt2rE3An.js.map → cjs/mui-tel-input.es-Dk9M_v4X.js.map} +1 -1
- package/dist/esm/index-Ds-63DcA.js +41896 -0
- package/dist/esm/index-Ds-63DcA.js.map +1 -0
- package/dist/esm/{index-DRYwiFvp.js → index-z31XSEKz.js} +26751 -26240
- package/dist/esm/index-z31XSEKz.js.map +1 -0
- package/dist/esm/index.js +3 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/{index.umd-BXOC8cuK.js → index.umd-5znOX_Ww.js} +4 -4
- package/dist/esm/{index.umd-BXOC8cuK.js.map → index.umd-5znOX_Ww.js.map} +1 -1
- package/dist/esm/index.umd-ddggyAGa.js +13395 -0
- package/dist/esm/index.umd-ddggyAGa.js.map +1 -0
- package/dist/esm/{mui-tel-input.es-Bt2rE3An.js → mui-tel-input.es-Cb4Lpqx7.js} +21 -21
- package/dist/{cjs/mui-tel-input.es-Bjml407E.js.map → esm/mui-tel-input.es-Cb4Lpqx7.js.map} +1 -1
- package/dist/types/form/Payment.d.ts +1 -0
- package/dist/types/form/paydroid/PaydroidCashlessSection.d.ts +7 -0
- package/dist/types/form/paydroid/PaydroidError.d.ts +3 -0
- package/dist/types/form/paydroid/PaydroidErrorAccount.d.ts +3 -0
- package/dist/types/form/paydroid/PaydroidErrorTicket.d.ts +3 -0
- package/dist/types/form/paydroid/PaydroidPage.d.ts +6 -0
- package/dist/types/form/paydroid/PaydroidStatusCard.d.ts +10 -0
- package/dist/types/form/paydroid/PaydroidSuccess.d.ts +3 -0
- package/dist/types/form/paydroid/PaydroidSuccessTopup.d.ts +3 -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 +34 -0
- package/dist/types/locales/en.d.ts +34 -0
- package/dist/types/locales/es.d.ts +34 -0
- package/dist/types/locales/pl.d.ts +34 -0
- package/dist/types/locales/sk.d.ts +34 -0
- package/dist/types/locales/uk.d.ts +34 -0
- package/dist/types/modules/order.d.ts +3 -0
- package/dist/types/modules/paydroid.d.ts +4 -0
- package/dist/types/utils/data/page.d.ts +7 -0
- package/dist/types/utils/page.d.ts +1 -0
- package/dist/types/utils/paydroid.d.ts +6 -0
- package/dist/types/utils/types/global.type.d.ts +1 -0
- package/dist/types/utils/types/order.type.d.ts +4 -0
- package/dist/types/utils/types/paydroid.d.ts +23 -0
- package/dist/types/utils/types/payment-method.type.d.ts +1 -0
- package/package.json +6 -2
- package/src/form/Payment.tsx +42 -3
- package/src/form/PaymentOverviewBox.tsx +20 -7
- package/src/form/PaymentSuccess.tsx +6 -2
- package/src/form/TicketForm.tsx +269 -168
- package/src/form/paydroid/PaydroidCashlessSection.tsx +311 -0
- package/src/form/paydroid/PaydroidError.tsx +26 -0
- package/src/form/paydroid/PaydroidErrorAccount.tsx +26 -0
- package/src/form/paydroid/PaydroidErrorTicket.tsx +26 -0
- package/src/form/paydroid/PaydroidPage.tsx +22 -0
- package/src/form/paydroid/PaydroidStatusCard.tsx +91 -0
- package/src/form/paydroid/PaydroidSuccess.tsx +26 -0
- package/src/form/paydroid/PaydroidSuccessTopup.tsx +26 -0
- package/src/form/payment/StripeCheckoutProvider.tsx +154 -0
- package/src/hooks/data/useStripeConfig.ts +14 -0
- package/src/locales/cs.tsx +40 -0
- package/src/locales/en.tsx +38 -0
- package/src/locales/es.tsx +39 -0
- package/src/locales/pl.tsx +38 -0
- package/src/locales/sk.tsx +40 -0
- package/src/locales/uk.tsx +38 -0
- package/src/modules/order.ts +3 -0
- package/src/modules/paydroid.ts +33 -0
- package/src/utils/data/page.ts +7 -0
- package/src/utils/page.ts +4 -0
- package/src/utils/paydroid.ts +35 -0
- package/src/utils/types/global.type.ts +1 -0
- package/src/utils/types/order.type.ts +7 -0
- package/src/utils/types/paydroid.ts +26 -0
- package/src/utils/types/payment-method.type.ts +1 -0
- package/dist/cjs/index-D1KZ-2U1.js.map +0 -1
- package/dist/esm/index-DRYwiFvp.js.map +0 -1
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
3
|
+
import React, { MutableRefObject, useEffect, useMemo } from 'react';
|
|
4
|
+
import { useTheme } from '@mui/material';
|
|
5
|
+
import { loadStripe, Appearance } from '@stripe/stripe-js';
|
|
6
|
+
import { Elements, useElements, useStripe } from '@stripe/react-stripe-js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Imperative handle the order form uses to drive the inline Stripe payment from
|
|
10
|
+
* its own submit handler (which lives outside the <Elements> tree).
|
|
11
|
+
*/
|
|
12
|
+
export interface StripeCheckoutApi {
|
|
13
|
+
ready: boolean;
|
|
14
|
+
/** Validate + collect the card fields. Returns an error message, or null. */
|
|
15
|
+
submit: () => Promise<string | null>;
|
|
16
|
+
/** Confirm the server-created PaymentIntent. */
|
|
17
|
+
confirm: (clientSecret: string, returnUrl: string) => Promise<{ ok: boolean; error?: string }>;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
// Locales the Stripe Elements UI supports; anything else falls back to auto.
|
|
21
|
+
const STRIPE_LOCALES = ['cs', 'de', 'en', 'es', 'fr', 'pl', 'sk', 'it'];
|
|
22
|
+
|
|
23
|
+
// Bridges the Stripe/Elements instances (only available inside <Elements>) up to
|
|
24
|
+
// a ref the form's submit handler can call.
|
|
25
|
+
const Bridge: React.FC<{ apiRef: MutableRefObject<StripeCheckoutApi | null> }> = ({ apiRef }) => {
|
|
26
|
+
const stripe = useStripe();
|
|
27
|
+
const elements = useElements();
|
|
28
|
+
|
|
29
|
+
useEffect(() => {
|
|
30
|
+
apiRef.current = {
|
|
31
|
+
ready: !!stripe && !!elements,
|
|
32
|
+
submit: async () => {
|
|
33
|
+
if (!elements) return 'Stripe not ready';
|
|
34
|
+
const { error } = await elements.submit();
|
|
35
|
+
return error?.message ?? null;
|
|
36
|
+
},
|
|
37
|
+
confirm: async (clientSecret, returnUrl) => {
|
|
38
|
+
if (!stripe || !elements) return { ok: false, error: 'Stripe not ready' };
|
|
39
|
+
// Resolve in-page when possible (incl. the 3-D Secure modal); Stripe
|
|
40
|
+
// only does a full redirect when the method strictly requires it.
|
|
41
|
+
const confirmParams = { return_url: returnUrl };
|
|
42
|
+
|
|
43
|
+
// Free (0-amount) orders confirm a SetupIntent (seti_…) — card
|
|
44
|
+
// verification for bot protection, no charge; paid orders confirm a
|
|
45
|
+
// PaymentIntent (pi_…).
|
|
46
|
+
if (clientSecret.startsWith('seti_')) {
|
|
47
|
+
const { error, setupIntent } = await stripe.confirmSetup({
|
|
48
|
+
elements,
|
|
49
|
+
clientSecret,
|
|
50
|
+
confirmParams,
|
|
51
|
+
redirect: 'if_required',
|
|
52
|
+
});
|
|
53
|
+
if (error) return { ok: false, error: error.message };
|
|
54
|
+
return { ok: setupIntent?.status === 'succeeded' };
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
const { error, paymentIntent } = await stripe.confirmPayment({
|
|
58
|
+
elements,
|
|
59
|
+
clientSecret,
|
|
60
|
+
confirmParams,
|
|
61
|
+
redirect: 'if_required',
|
|
62
|
+
});
|
|
63
|
+
if (error) return { ok: false, error: error.message };
|
|
64
|
+
const ok =
|
|
65
|
+
!!paymentIntent &&
|
|
66
|
+
(paymentIntent.status === 'succeeded' || paymentIntent.status === 'processing');
|
|
67
|
+
return { ok };
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
return () => {
|
|
71
|
+
apiRef.current = null;
|
|
72
|
+
};
|
|
73
|
+
}, [stripe, elements, apiRef]);
|
|
74
|
+
|
|
75
|
+
return null;
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
interface Props {
|
|
79
|
+
/** Mount Elements only when a Stripe method is offered and the key is loaded. */
|
|
80
|
+
active: boolean;
|
|
81
|
+
publishableKey: string | null;
|
|
82
|
+
/** 'payment' for paid orders, 'setup' for free (0-amount) card verification. */
|
|
83
|
+
mode: 'payment' | 'setup';
|
|
84
|
+
/** Charge amount in minor units (used by Elements; the server intent is authoritative). */
|
|
85
|
+
amount: number;
|
|
86
|
+
currency: string;
|
|
87
|
+
locale: string;
|
|
88
|
+
apiRef: MutableRefObject<StripeCheckoutApi | null>;
|
|
89
|
+
children: React.ReactNode;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wraps the order form in a deferred-mode <Elements> provider so the Payment
|
|
94
|
+
* Element can be shown inline (expanded under the selected method) before the
|
|
95
|
+
* order — and its PaymentIntent — exists. When no Stripe method is on offer it
|
|
96
|
+
* renders children untouched and loads nothing.
|
|
97
|
+
*/
|
|
98
|
+
const StripeCheckoutProvider: React.FC<Props> = ({
|
|
99
|
+
active,
|
|
100
|
+
publishableKey,
|
|
101
|
+
mode,
|
|
102
|
+
amount,
|
|
103
|
+
currency,
|
|
104
|
+
locale,
|
|
105
|
+
apiRef,
|
|
106
|
+
children,
|
|
107
|
+
}) => {
|
|
108
|
+
const theme = useTheme();
|
|
109
|
+
const stripePromise = useMemo(
|
|
110
|
+
() => (active && publishableKey ? loadStripe(publishableKey) : null),
|
|
111
|
+
[active, publishableKey]
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
if (!active || !stripePromise) return <>{children}</>;
|
|
115
|
+
|
|
116
|
+
const stripeLocale = STRIPE_LOCALES.includes(locale) ? locale : 'auto';
|
|
117
|
+
|
|
118
|
+
// Drive the Stripe Element off the host MUI theme so it matches light/dark and
|
|
119
|
+
// the brand colors instead of Stripe's default white card.
|
|
120
|
+
const appearance: Appearance = {
|
|
121
|
+
theme: theme.palette.mode === 'dark' ? 'night' : 'stripe',
|
|
122
|
+
variables: {
|
|
123
|
+
colorPrimary: theme.palette.primary.main,
|
|
124
|
+
colorBackground: theme.palette.background.paper,
|
|
125
|
+
colorText: theme.palette.text.primary,
|
|
126
|
+
colorTextSecondary: theme.palette.text.secondary,
|
|
127
|
+
colorDanger: theme.palette.error.main,
|
|
128
|
+
fontFamily: String(theme.typography.fontFamily ?? 'inherit'),
|
|
129
|
+
borderRadius: `${Number(theme.shape.borderRadius) || 8}px`,
|
|
130
|
+
},
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
return (
|
|
134
|
+
<Elements
|
|
135
|
+
stripe={stripePromise}
|
|
136
|
+
options={{
|
|
137
|
+
// Free orders verify the card (SetupIntent, no charge); paid orders
|
|
138
|
+
// charge it (PaymentIntent, needs an amount).
|
|
139
|
+
...(mode === 'setup'
|
|
140
|
+
? { mode: 'setup' as const }
|
|
141
|
+
: { mode: 'payment' as const, amount: Math.max(1, Math.round(amount)) }),
|
|
142
|
+
currency: currency.toLowerCase(),
|
|
143
|
+
paymentMethodTypes: ['card'],
|
|
144
|
+
locale: stripeLocale as 'auto',
|
|
145
|
+
appearance,
|
|
146
|
+
}}
|
|
147
|
+
>
|
|
148
|
+
<Bridge apiRef={apiRef} />
|
|
149
|
+
{children}
|
|
150
|
+
</Elements>
|
|
151
|
+
);
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
export default StripeCheckoutProvider;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import useSWR from 'swr';
|
|
2
|
+
import { getStripeConfig } from '@modules/order';
|
|
3
|
+
|
|
4
|
+
// Fetches the public Stripe publishable key, only when a Stripe method is on
|
|
5
|
+
// offer (pass enabled=false to skip the request entirely). Cached for the
|
|
6
|
+
// session — the key never changes.
|
|
7
|
+
export default function useStripeConfig(enabled: boolean) {
|
|
8
|
+
const { data } = useSWR(enabled ? ['stripe-config'] : null, () => getStripeConfig(), {
|
|
9
|
+
revalidateOnFocus: false,
|
|
10
|
+
revalidateIfStale: false,
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
return { publishableKey: data?.publishableKey ?? null };
|
|
14
|
+
}
|
package/src/locales/cs.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const cs = {
|
|
|
44
44
|
total: 'Celkem',
|
|
45
45
|
with_fee: 'vč. servisního poplatku',
|
|
46
46
|
service_fee: 'Servisní poplatek',
|
|
47
|
+
payment_processing_fee: 'Poplatek za platbu kartou',
|
|
48
|
+
card_payment_title: 'Platba kartou',
|
|
49
|
+
card_payment_error: 'Platbu se nepodařilo dokončit. Zkuste to prosím znovu.',
|
|
47
50
|
shipping_fee: 'Doprava',
|
|
48
51
|
ticket_insurance: 'Pojištění vstupenek',
|
|
49
52
|
price_including_service_fee: 'Cena zahrnuje servisní poplatek v hodnotě {{fee}}.',
|
|
@@ -64,6 +67,7 @@ const cs = {
|
|
|
64
67
|
'Tato kategorie je doplňková — zadejte číslo již zakoupené vstupenky.',
|
|
65
68
|
primary_ticket_dialog_title: 'Zadejte číslo primární vstupenky',
|
|
66
69
|
primary_ticket_dialog_input_label: 'Číslo primární vstupenky',
|
|
70
|
+
amount: 'Částka',
|
|
67
71
|
},
|
|
68
72
|
validation: {
|
|
69
73
|
required: 'Toto pole je povinné.',
|
|
@@ -185,6 +189,42 @@ const cs = {
|
|
|
185
189
|
button: 'Stáhnout vstupenku',
|
|
186
190
|
products: 'Vaše produkty',
|
|
187
191
|
},
|
|
192
|
+
paydroid: {
|
|
193
|
+
label: 'Paydroid Cashless',
|
|
194
|
+
heading: 'Vyhněte se frontám!',
|
|
195
|
+
heading_cta: 'Přednabijte si',
|
|
196
|
+
subtitle:
|
|
197
|
+
'Na akci lze platit pouze bezhotovostně pomocí systému Paydroid Cashless. Přednabijte si částku teď a vyhněte se frontám!',
|
|
198
|
+
amount_label: 'Jakou částku chcete přednabít?',
|
|
199
|
+
amount_placeholder: 'Zadejte částku',
|
|
200
|
+
promo: 'Přednabijte si na akci částku vyšší než 1000 Kč a získejte pivo zdarma!',
|
|
201
|
+
terms_prefix: 'Souhlasím s',
|
|
202
|
+
terms_conditions: 'Obchodními podmínkami',
|
|
203
|
+
terms_middle: 'Paydroid Cashless a se',
|
|
204
|
+
terms_privacy: 'Zásadami zpracování osobních údajů',
|
|
205
|
+
terms: 'Souhlas VOP a GDPR Paydroid Cashless',
|
|
206
|
+
skip: 'chci pouze vstupenku v aplikaci',
|
|
207
|
+
submit: 'přednabít',
|
|
208
|
+
success_title: 'Vstupenku jsme přidali k vašemu účtu',
|
|
209
|
+
success_subtitle:
|
|
210
|
+
'Teď už se stačí jen přihlásit do aplikace Paydroid Cashless. A pokud se budete chtít vyhnout frontám, přednabijte si v aplikaci!',
|
|
211
|
+
topup_success_title: 'Děkujeme za přednabitî!',
|
|
212
|
+
topup_success_subtitle:
|
|
213
|
+
'Právě jsme připsali kredit na Váš účet Paydroid Cashless, nyní už se stačí pouze přihlásit v aplikaci.',
|
|
214
|
+
error_title: 'Přednabití se nezdařilo',
|
|
215
|
+
error_subtitle:
|
|
216
|
+
'Nebyli jste nijak zpoplatněni, v případě jakýchkoliv problémů nás prosím kontaktujte.',
|
|
217
|
+
error_account_title: 'Nepodařilo se vytvořit účet',
|
|
218
|
+
error_account_subtitle:
|
|
219
|
+
'Pravděpodobně jste zadali údaje, které se liší se záznamem v naší databázi.',
|
|
220
|
+
error_account_button: 'přihlásit se do aplikace',
|
|
221
|
+
error_ticket_title: 'Přidání vstupenky se nezdařilo',
|
|
222
|
+
error_ticket_subtitle:
|
|
223
|
+
'Omlouváme se, vyzkoušejte to prosím později. V případě jakýchkoliv problémů nás prosím kontaktujte.',
|
|
224
|
+
faq_button: 'nejčastější dotazy',
|
|
225
|
+
retry_button: 'vyzkoušet znovu',
|
|
226
|
+
missing_api_key: 'Paydroid API klíč chybí',
|
|
227
|
+
},
|
|
188
228
|
unpaid: 'Platba neproběhla',
|
|
189
229
|
unpaid_description: 'Zkuste to prosím znovu kliknutím na tlačítko Zaplatit.',
|
|
190
230
|
},
|
package/src/locales/en.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const en = {
|
|
|
44
44
|
total: 'Total',
|
|
45
45
|
with_fee: 'incl. service fee',
|
|
46
46
|
service_fee: 'Service fee',
|
|
47
|
+
payment_processing_fee: 'Card processing fee',
|
|
48
|
+
card_payment_title: 'Card payment',
|
|
49
|
+
card_payment_error: 'The payment could not be completed. Please try again.',
|
|
47
50
|
shipping_fee: 'Shipping',
|
|
48
51
|
ticket_insurance: 'Ticket insurance',
|
|
49
52
|
price_including_service_fee: 'The price includes a service fee of {{fee}}.',
|
|
@@ -64,6 +67,7 @@ const en = {
|
|
|
64
67
|
'This is an addon category — enter the number of an already-purchased ticket.',
|
|
65
68
|
primary_ticket_dialog_title: 'Enter primary ticket number',
|
|
66
69
|
primary_ticket_dialog_input_label: 'Primary ticket number',
|
|
70
|
+
amount: 'Amount',
|
|
67
71
|
},
|
|
68
72
|
validation: {
|
|
69
73
|
required: 'This field is required.',
|
|
@@ -185,6 +189,40 @@ const en = {
|
|
|
185
189
|
button: 'Download ticket',
|
|
186
190
|
products: 'Your products',
|
|
187
191
|
},
|
|
192
|
+
paydroid: {
|
|
193
|
+
label: 'Paydroid Cashless',
|
|
194
|
+
heading: 'Skip the queues!',
|
|
195
|
+
heading_cta: 'Top up now',
|
|
196
|
+
subtitle:
|
|
197
|
+
'The event accepts only cashless payments via Paydroid Cashless. Top up your balance now and skip the queues!',
|
|
198
|
+
amount_label: 'How much would you like to top up?',
|
|
199
|
+
amount_placeholder: 'Enter amount',
|
|
200
|
+
promo: 'Top up more than 1000 CZK and get a free beer!',
|
|
201
|
+
terms_prefix: 'I agree to the',
|
|
202
|
+
terms_conditions: 'Terms and Conditions',
|
|
203
|
+
terms_middle: 'of Paydroid Cashless and the',
|
|
204
|
+
terms_privacy: 'Privacy Policy',
|
|
205
|
+
terms: 'I agree to the T&C and GDPR of Paydroid Cashless',
|
|
206
|
+
skip: 'I just want the ticket in the app',
|
|
207
|
+
submit: 'top up',
|
|
208
|
+
success_title: 'We added the ticket to your account',
|
|
209
|
+
success_subtitle:
|
|
210
|
+
'Just log in to the Paydroid Cashless app. And if you want to skip the queues, top up in the app!',
|
|
211
|
+
topup_success_title: 'Thank you for topping up!',
|
|
212
|
+
topup_success_subtitle:
|
|
213
|
+
'We have credited your Paydroid Cashless account. Just log in to the app.',
|
|
214
|
+
error_title: 'Top-up failed',
|
|
215
|
+
error_subtitle: 'You have not been charged. Please contact us if you have any issues.',
|
|
216
|
+
error_account_title: 'Failed to create account',
|
|
217
|
+
error_account_subtitle: 'You may have entered details that differ from our records.',
|
|
218
|
+
error_account_button: 'log in to the app',
|
|
219
|
+
error_ticket_title: 'Failed to add ticket',
|
|
220
|
+
error_ticket_subtitle:
|
|
221
|
+
'We are sorry, please try again later. Contact us if the issue persists.',
|
|
222
|
+
faq_button: 'frequently asked questions',
|
|
223
|
+
retry_button: 'try again',
|
|
224
|
+
missing_api_key: 'Paydroid API key is missing',
|
|
225
|
+
},
|
|
188
226
|
unpaid: 'The payment was not successful.',
|
|
189
227
|
unpaid_description: 'Please try again by clicking the Pay button.',
|
|
190
228
|
},
|
package/src/locales/es.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const es = {
|
|
|
44
44
|
total: 'Total',
|
|
45
45
|
with_fee: 'incl. tarifa de servicio',
|
|
46
46
|
service_fee: 'Tarifa de servicio',
|
|
47
|
+
payment_processing_fee: 'Comisión por pago con tarjeta',
|
|
48
|
+
card_payment_title: 'Pago con tarjeta',
|
|
49
|
+
card_payment_error: 'No se pudo completar el pago. Inténtalo de nuevo.',
|
|
47
50
|
shipping_fee: 'Envío',
|
|
48
51
|
ticket_insurance: 'Seguro de entrada',
|
|
49
52
|
price_including_service_fee: 'El precio incluye una tarifa de servicio de {{fee}}.',
|
|
@@ -64,6 +67,7 @@ const es = {
|
|
|
64
67
|
'Esta es una categoría complementaria — introduzca el número de una entrada ya comprada.',
|
|
65
68
|
primary_ticket_dialog_title: 'Introduzca el número de la entrada principal',
|
|
66
69
|
primary_ticket_dialog_input_label: 'Número de la entrada principal',
|
|
70
|
+
amount: 'Cantidad',
|
|
67
71
|
},
|
|
68
72
|
validation: {
|
|
69
73
|
required: 'Este campo es obligatorio.',
|
|
@@ -185,6 +189,41 @@ const es = {
|
|
|
185
189
|
button: 'Descargar entrada',
|
|
186
190
|
products: 'Tus productos',
|
|
187
191
|
},
|
|
192
|
+
paydroid: {
|
|
193
|
+
label: 'Paydroid Cashless',
|
|
194
|
+
heading: '¡Evita las colas!',
|
|
195
|
+
heading_cta: 'Recarga ahora',
|
|
196
|
+
subtitle:
|
|
197
|
+
'El evento solo acepta pagos sin efectivo a través de Paydroid Cashless. ¡Recarga tu saldo ahora y evita las colas!',
|
|
198
|
+
amount_label: '¿Cuánto deseas recargar?',
|
|
199
|
+
amount_placeholder: 'Ingresa el monto',
|
|
200
|
+
promo: '¡Recarga más de 1000 CZK y obtén una cerveza gratis!',
|
|
201
|
+
terms_prefix: 'Acepto los',
|
|
202
|
+
terms_conditions: 'Términos y condiciones',
|
|
203
|
+
terms_middle: 'de Paydroid Cashless y la',
|
|
204
|
+
terms_privacy: 'Política de privacidad',
|
|
205
|
+
terms: 'Acepto los T&C y GDPR de Paydroid Cashless',
|
|
206
|
+
skip: 'solo quiero la entrada en la app',
|
|
207
|
+
submit: 'recargar',
|
|
208
|
+
success_title: 'Añadimos la entrada a tu cuenta',
|
|
209
|
+
success_subtitle:
|
|
210
|
+
'Solo inicia sesión en la app Paydroid Cashless. ¡Y si quieres saltarte las colas, recarga en la app!',
|
|
211
|
+
topup_success_title: '¡Gracias por recargar!',
|
|
212
|
+
topup_success_subtitle:
|
|
213
|
+
'Hemos acreditado tu cuenta Paydroid Cashless. Solo inicia sesión en la app.',
|
|
214
|
+
error_title: 'La recarga falló',
|
|
215
|
+
error_subtitle: 'No se te ha cobrado nada. Contáctanos si tienes algún problema.',
|
|
216
|
+
error_account_title: 'No se pudo crear la cuenta',
|
|
217
|
+
error_account_subtitle:
|
|
218
|
+
'Es posible que hayas introducido datos diferentes a los de nuestros registros.',
|
|
219
|
+
error_account_button: 'iniciar sesión en la app',
|
|
220
|
+
error_ticket_title: 'No se pudo añadir la entrada',
|
|
221
|
+
error_ticket_subtitle:
|
|
222
|
+
'Lo sentimos, inténtalo más tarde. Contáctanos si el problema persiste.',
|
|
223
|
+
faq_button: 'preguntas frecuentes',
|
|
224
|
+
retry_button: 'intentar de nuevo',
|
|
225
|
+
missing_api_key: 'Falta la clave API de Paydroid',
|
|
226
|
+
},
|
|
188
227
|
unpaid: 'El pago no se realizó.',
|
|
189
228
|
unpaid_description: 'Por favor, inténtelo de nuevo haciendo clic en el botón Pagar.',
|
|
190
229
|
},
|
package/src/locales/pl.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const pl = {
|
|
|
44
44
|
total: 'Razem',
|
|
45
45
|
with_fee: 'z opłatą serwisową',
|
|
46
46
|
service_fee: 'Opłata serwisowa',
|
|
47
|
+
payment_processing_fee: 'Opłata za obsługę karty',
|
|
48
|
+
card_payment_title: 'Płatność kartą',
|
|
49
|
+
card_payment_error: 'Nie udało się zrealizować płatności. Spróbuj ponownie.',
|
|
47
50
|
shipping_fee: 'Wysyłka',
|
|
48
51
|
ticket_insurance: 'Ubezpieczenie biletu',
|
|
49
52
|
price_including_service_fee: 'Cena zawiera opłatę serwisową {{fee}}.',
|
|
@@ -64,6 +67,7 @@ const pl = {
|
|
|
64
67
|
'To jest kategoria dodatkowa — wprowadź numer już zakupionego biletu.',
|
|
65
68
|
primary_ticket_dialog_title: 'Wprowadź numer biletu głównego',
|
|
66
69
|
primary_ticket_dialog_input_label: 'Numer biletu głównego',
|
|
70
|
+
amount: 'Kwota',
|
|
67
71
|
},
|
|
68
72
|
validation: {
|
|
69
73
|
required: 'To pole jest wymagane.',
|
|
@@ -184,6 +188,40 @@ const pl = {
|
|
|
184
188
|
button: 'Pobierz bilet',
|
|
185
189
|
products: 'Twoje produkty',
|
|
186
190
|
},
|
|
191
|
+
paydroid: {
|
|
192
|
+
label: 'Paydroid Cashless',
|
|
193
|
+
heading: 'Unikaj kolejek!',
|
|
194
|
+
heading_cta: 'Doładuj teraz',
|
|
195
|
+
subtitle:
|
|
196
|
+
'Na imprezie płatności są wyłącznie bezgotówkowe za pomocą systemu Paydroid Cashless. Doładuj konto teraz i unikaj kolejek!',
|
|
197
|
+
amount_label: 'Jaką kwotę chcesz doładować?',
|
|
198
|
+
amount_placeholder: 'Wpisz kwotę',
|
|
199
|
+
promo: 'Doładuj kwotę wyższą niż 1000 CZK i otrzymaj piwo gratis!',
|
|
200
|
+
terms_prefix: 'Zgadzam się z',
|
|
201
|
+
terms_conditions: 'Regulaminem',
|
|
202
|
+
terms_middle: 'Paydroid Cashless oraz z',
|
|
203
|
+
terms_privacy: 'Zasadami przetwarzania danych osobowych',
|
|
204
|
+
terms: 'Zgoda na regulamin i RODO Paydroid Cashless',
|
|
205
|
+
skip: 'chcę tylko bilet w aplikacji',
|
|
206
|
+
submit: 'doładuj',
|
|
207
|
+
success_title: 'Dodaliśmy bilet do Twojego konta',
|
|
208
|
+
success_subtitle:
|
|
209
|
+
'Zaloguj się do aplikacji Paydroid Cashless. Jeśli chcesz uniknąć kolejek, doładuj konto w aplikacji!',
|
|
210
|
+
topup_success_title: 'Dziękujemy za doładowanie!',
|
|
211
|
+
topup_success_subtitle:
|
|
212
|
+
'Właśnie dodaliśmy środki na Twoje konto Paydroid Cashless. Zaloguj się do aplikacji.',
|
|
213
|
+
error_title: 'Doładowanie nie powiodło się',
|
|
214
|
+
error_subtitle: 'Nie zostałeś obciążony. Skontaktuj się z nami w razie problemów.',
|
|
215
|
+
error_account_title: 'Nie udało się utworzyć konta',
|
|
216
|
+
error_account_subtitle: 'Prawdopodobnie podałeś dane różniące się od naszych zapisów.',
|
|
217
|
+
error_account_button: 'zaloguj się do aplikacji',
|
|
218
|
+
error_ticket_title: 'Nie udało się dodać biletu',
|
|
219
|
+
error_ticket_subtitle:
|
|
220
|
+
'Przepraszamy, spróbuj ponownie później. Skontaktuj się z nami jeśli problem się powtórzy.',
|
|
221
|
+
faq_button: 'najczęstsze pytania',
|
|
222
|
+
retry_button: 'spróbuj ponownie',
|
|
223
|
+
missing_api_key: 'Brak klucza API Paydroid',
|
|
224
|
+
},
|
|
187
225
|
unpaid: 'Płatność nie powiodła się.',
|
|
188
226
|
unpaid_description: 'Spróbuj ponownie, klikając przycisk Zapłać.',
|
|
189
227
|
},
|
package/src/locales/sk.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const sk = {
|
|
|
44
44
|
total: 'Spolu',
|
|
45
45
|
with_fee: 'vrátane servisného poplatku',
|
|
46
46
|
service_fee: 'Servisný poplatok',
|
|
47
|
+
payment_processing_fee: 'Poplatok za platbu kartou',
|
|
48
|
+
card_payment_title: 'Platba kartou',
|
|
49
|
+
card_payment_error: 'Platbu sa nepodarilo dokončiť. Skúste to znova.',
|
|
47
50
|
shipping_fee: 'Doručenie',
|
|
48
51
|
ticket_insurance: 'Poistenie vstupenky',
|
|
49
52
|
price_including_service_fee: 'Cena zahŕňa servisný poplatok {{fee}}.',
|
|
@@ -64,6 +67,7 @@ const sk = {
|
|
|
64
67
|
'Táto kategória je doplnková — zadajte číslo už zakúpenej vstupenky.',
|
|
65
68
|
primary_ticket_dialog_title: 'Zadajte číslo primárnej vstupenky',
|
|
66
69
|
primary_ticket_dialog_input_label: 'Číslo primárnej vstupenky',
|
|
70
|
+
amount: 'Čiastka',
|
|
67
71
|
},
|
|
68
72
|
validation: {
|
|
69
73
|
required: 'Toto pole je povinné.',
|
|
@@ -185,6 +189,42 @@ const sk = {
|
|
|
185
189
|
button: 'Stiahnuť vstupenku',
|
|
186
190
|
products: 'Vaše produkty',
|
|
187
191
|
},
|
|
192
|
+
paydroid: {
|
|
193
|
+
label: 'Paydroid Cashless',
|
|
194
|
+
heading: 'Vyhnite sa radom!',
|
|
195
|
+
heading_cta: 'Prednabite si',
|
|
196
|
+
subtitle:
|
|
197
|
+
'Na akcii sa platí len bezhotovostne pomocou systému Paydroid Cashless. Prednabite si čiastku teraz a vyhnite sa radom!',
|
|
198
|
+
amount_label: 'Akú čiastku chcete prednabiť?',
|
|
199
|
+
amount_placeholder: 'Zadajte čiastku',
|
|
200
|
+
promo: 'Prednabite si na akciu čiastku vyššiu ako 1000 Kč a získajte pivo zadarmo!',
|
|
201
|
+
terms_prefix: 'Súhlasím s',
|
|
202
|
+
terms_conditions: 'Obchodnými podmienkami',
|
|
203
|
+
terms_middle: 'Paydroid Cashless a so',
|
|
204
|
+
terms_privacy: 'Zásadami spracovania osobných údajov',
|
|
205
|
+
terms: 'Súhlas VOP a GDPR Paydroid Cashless',
|
|
206
|
+
skip: 'chcem len vstupenku v aplikácii',
|
|
207
|
+
submit: 'prednabiť',
|
|
208
|
+
success_title: 'Vstupenku sme pridali k vášmu účtu',
|
|
209
|
+
success_subtitle:
|
|
210
|
+
'Stačí sa prihlásiť do aplikácie Paydroid Cashless. A ak sa chcete vyhnúť radom, prednabite si v aplikácii!',
|
|
211
|
+
topup_success_title: 'Ďakujeme za prednabitie!',
|
|
212
|
+
topup_success_subtitle:
|
|
213
|
+
'Práve sme pripísali kredit na Váš účet Paydroid Cashless, stačí sa prihlásiť v aplikácii.',
|
|
214
|
+
error_title: 'Prednabitie sa nepodarilo',
|
|
215
|
+
error_subtitle:
|
|
216
|
+
'Neboli ste nijako spoplatnení, v prípade akýchkoľvek problémov nás prosím kontaktujte.',
|
|
217
|
+
error_account_title: 'Nepodarilo sa vytvoriť účet',
|
|
218
|
+
error_account_subtitle:
|
|
219
|
+
'Pravdepodobne ste zadali údaje, ktoré sa líšia od záznamu v našej databáze.',
|
|
220
|
+
error_account_button: 'prihlásiť sa do aplikácie',
|
|
221
|
+
error_ticket_title: 'Pridanie vstupenky sa nepodarilo',
|
|
222
|
+
error_ticket_subtitle:
|
|
223
|
+
'Ospravedlňujeme sa, skúste to neskôr. V prípade problémov nás prosím kontaktujte.',
|
|
224
|
+
faq_button: 'najčastejšie otázky',
|
|
225
|
+
retry_button: 'skúsiť znova',
|
|
226
|
+
missing_api_key: 'Paydroid API kľúč chýba',
|
|
227
|
+
},
|
|
188
228
|
unpaid: 'Platba neprebehla.',
|
|
189
229
|
unpaid_description: 'Skúste to prosím znova kliknutím na tlačidlo Zaplatiť.',
|
|
190
230
|
},
|
package/src/locales/uk.tsx
CHANGED
|
@@ -44,6 +44,9 @@ const uk = {
|
|
|
44
44
|
total: 'Всього',
|
|
45
45
|
with_fee: 'вкл. сервісний збір',
|
|
46
46
|
service_fee: 'Сервісний збір',
|
|
47
|
+
payment_processing_fee: 'Комісія за оплату карткою',
|
|
48
|
+
card_payment_title: 'Оплата карткою',
|
|
49
|
+
card_payment_error: 'Не вдалося завершити оплату. Спробуйте ще раз.',
|
|
47
50
|
shipping_fee: 'Доставка',
|
|
48
51
|
ticket_insurance: 'Страхування квитка',
|
|
49
52
|
price_including_service_fee: 'Ціна включає сервісний збір {{fee}}.',
|
|
@@ -63,6 +66,7 @@ const uk = {
|
|
|
63
66
|
primary_ticket_number_hint: 'Це додаткова категорія — введіть номер уже придбаного квитка.',
|
|
64
67
|
primary_ticket_dialog_title: 'Введіть номер основного квитка',
|
|
65
68
|
primary_ticket_dialog_input_label: 'Номер основного квитка',
|
|
69
|
+
amount: 'Сума',
|
|
66
70
|
},
|
|
67
71
|
validation: {
|
|
68
72
|
required: "Це поле обов'язкове.",
|
|
@@ -184,6 +188,40 @@ const uk = {
|
|
|
184
188
|
button: 'Завантажити квиток',
|
|
185
189
|
products: 'Ваші продукти',
|
|
186
190
|
},
|
|
191
|
+
paydroid: {
|
|
192
|
+
label: 'Paydroid Cashless',
|
|
193
|
+
heading: 'Уникайте черг!',
|
|
194
|
+
heading_cta: 'Поповніть баланс',
|
|
195
|
+
subtitle:
|
|
196
|
+
'На заході оплата виключно безготівкова за допомогою системи Paydroid Cashless. Поповніть баланс зараз і уникайте черг!',
|
|
197
|
+
amount_label: 'Яку суму ви хочете поповнити?',
|
|
198
|
+
amount_placeholder: 'Введіть суму',
|
|
199
|
+
promo: 'Поповніть суму понад 1000 CZK та отримайте пиво безкоштовно!',
|
|
200
|
+
terms_prefix: 'Я погоджуюсь з',
|
|
201
|
+
terms_conditions: 'Умовами використання',
|
|
202
|
+
terms_middle: 'Paydroid Cashless та із',
|
|
203
|
+
terms_privacy: 'Правилами обробки персональних даних',
|
|
204
|
+
terms: 'Згода з умовами та GDPR Paydroid Cashless',
|
|
205
|
+
skip: 'лише квиток у додатку',
|
|
206
|
+
submit: 'поповнити',
|
|
207
|
+
success_title: 'Ми додали квиток до вашого облікового запису',
|
|
208
|
+
success_subtitle:
|
|
209
|
+
'Просто увійдіть у додаток Paydroid Cashless. Якщо хочете уникнути черг — поповніть баланс у додатку!',
|
|
210
|
+
topup_success_title: 'Дякуємо за поповнення!',
|
|
211
|
+
topup_success_subtitle:
|
|
212
|
+
'Ми щойно зарахували кошти на ваш рахунок Paydroid Cashless. Увійдіть у додаток.',
|
|
213
|
+
error_title: 'Поповнення не вдалося',
|
|
214
|
+
error_subtitle: 'З вас нічого не стягнуто. Зверніться до нас, якщо виникнуть проблеми.',
|
|
215
|
+
error_account_title: 'Не вдалося створити обліковий запис',
|
|
216
|
+
error_account_subtitle: 'Можливо, ви ввели дані, що відрізняються від наших записів.',
|
|
217
|
+
error_account_button: 'увійти в додаток',
|
|
218
|
+
error_ticket_title: 'Не вдалося додати квиток',
|
|
219
|
+
error_ticket_subtitle:
|
|
220
|
+
'Вибачте, спробуйте пізніше. Зверніться до нас, якщо проблема повториться.',
|
|
221
|
+
faq_button: 'часті запитання',
|
|
222
|
+
retry_button: 'спробувати знову',
|
|
223
|
+
missing_api_key: 'API ключ Paydroid відсутній',
|
|
224
|
+
},
|
|
187
225
|
unpaid: 'Платіж не здійснено.',
|
|
188
226
|
unpaid_description: 'Спробуйте ще раз, натиснувши кнопку Оплатити.',
|
|
189
227
|
},
|
package/src/modules/order.ts
CHANGED
|
@@ -18,3 +18,6 @@ export const getAllowedPaymentMethods = (currency: Currencies, eventId?: number)
|
|
|
18
18
|
|
|
19
19
|
export const postOrderPaid = (data: IOrderPaidData): Promise<IResponse<IOrderPaid>> =>
|
|
20
20
|
api.post('/v1/orders/paid', data).then((res) => res.data.data);
|
|
21
|
+
|
|
22
|
+
export const getStripeConfig = (): Promise<{ publishableKey: string | null }> =>
|
|
23
|
+
api.get('/v1/orders/stripe/config').then((res) => res.data.data.data);
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import api from '@utils/axios';
|
|
2
|
+
import { IResponse } from '@utils/types/global.type';
|
|
3
|
+
import {
|
|
4
|
+
IPaydroidCreateAccountData,
|
|
5
|
+
IPaydroidTopupAccountData,
|
|
6
|
+
IPaydroidTopupAccountResponse,
|
|
7
|
+
} from '@utils/types/paydroid';
|
|
8
|
+
|
|
9
|
+
const domain = 'https://api.paydroid.cz';
|
|
10
|
+
|
|
11
|
+
export const postPaydroidCreateAccount = (
|
|
12
|
+
apiKey: string,
|
|
13
|
+
data: IPaydroidCreateAccountData
|
|
14
|
+
): Promise<IResponse<null>> =>
|
|
15
|
+
api
|
|
16
|
+
.post(`${domain}/v1/requests/create-account`, data, {
|
|
17
|
+
headers: {
|
|
18
|
+
'X-Api-Key': apiKey,
|
|
19
|
+
},
|
|
20
|
+
})
|
|
21
|
+
.then((res) => res.data.data);
|
|
22
|
+
|
|
23
|
+
export const postPaydroidTopupAccount = (
|
|
24
|
+
apiKey: string,
|
|
25
|
+
data: IPaydroidTopupAccountData
|
|
26
|
+
): Promise<IResponse<IPaydroidTopupAccountResponse>> =>
|
|
27
|
+
api
|
|
28
|
+
.post(`${domain}/v1/requests/topup-account`, data, {
|
|
29
|
+
headers: {
|
|
30
|
+
'X-Api-Key': apiKey,
|
|
31
|
+
},
|
|
32
|
+
})
|
|
33
|
+
.then((res) => res.data);
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Page } from '@utils/data/page';
|
|
2
|
+
import { IOrderPaid } from '@utils/types/order.type';
|
|
3
|
+
import { IPaydroidCreateAccountData, IPaydroidTopupAccountData } from '@utils/types/paydroid';
|
|
4
|
+
import dayjs from 'dayjs';
|
|
5
|
+
|
|
6
|
+
export const getRedirectUrl = (page: Page): string => {
|
|
7
|
+
const base = window.location.origin + window.location.pathname;
|
|
8
|
+
return `${base}?page=${page}`;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const transformToCreateAccountData = (data: IOrderPaid): IPaydroidCreateAccountData => ({
|
|
12
|
+
first_name: data.customer.firstName,
|
|
13
|
+
last_name: data.customer.lastName,
|
|
14
|
+
email: data.customer.email,
|
|
15
|
+
phone_number: data.customer.phone,
|
|
16
|
+
event_id: data.paydroidEventId || '',
|
|
17
|
+
tickets: data.tickets.map((ticket) => ({
|
|
18
|
+
number: ticket.number.toString(),
|
|
19
|
+
category: ticket.releaseCategoryName,
|
|
20
|
+
})),
|
|
21
|
+
...(data.customer.birthdate
|
|
22
|
+
? { date_of_birth: dayjs(data.customer.birthdate).format('YYYY-MM-DD') }
|
|
23
|
+
: {}),
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
export const transformToTopupAccountData = (
|
|
27
|
+
amount: string,
|
|
28
|
+
data: IOrderPaid
|
|
29
|
+
): IPaydroidTopupAccountData => ({
|
|
30
|
+
email: data.customer.email,
|
|
31
|
+
event_id: data.paydroidEventId || '',
|
|
32
|
+
amount: Number(amount),
|
|
33
|
+
success_url: getRedirectUrl(Page.PAYDROID_TOPUP_SUCCESS),
|
|
34
|
+
failure_url: getRedirectUrl(Page.PAYDROID_ERROR),
|
|
35
|
+
});
|
|
@@ -23,6 +23,11 @@ export interface IOrder extends IBase {
|
|
|
23
23
|
|
|
24
24
|
export interface IOrderCreate {
|
|
25
25
|
gwUrl: string;
|
|
26
|
+
// Inline Stripe (Payment Element): set when the selected method confirms
|
|
27
|
+
// in-page instead of redirecting; the publishable key is returned alongside
|
|
28
|
+
// so the SDK can mount Elements without host-app configuration.
|
|
29
|
+
clientSecret: string | null;
|
|
30
|
+
publishableKey: string | null;
|
|
26
31
|
tickets: ICreateTicket[];
|
|
27
32
|
orderEntity: IOrder;
|
|
28
33
|
customer: ICustomer;
|
|
@@ -40,9 +45,11 @@ export interface IOrderPaid {
|
|
|
40
45
|
orderNumber: number;
|
|
41
46
|
tickets: IPaidTicket[];
|
|
42
47
|
products: IPaidProduct[];
|
|
48
|
+
customer: ICustomer;
|
|
43
49
|
extraFee: number;
|
|
44
50
|
currency: Currencies;
|
|
45
51
|
promoCodes: IPromoCode[] | null;
|
|
52
|
+
paydroidEventId: string | null;
|
|
46
53
|
}
|
|
47
54
|
|
|
48
55
|
export interface IAllowedPaymentMethod {
|