@everymatrix/cashier-method-details 1.44.0 → 1.45.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (37) hide show
  1. package/components/CashierConfirmModal-B-t1-wAt.js +1063 -0
  2. package/components/CashierConfirmModal-O8Y6vOPF.cjs +4 -0
  3. package/components/CashierError-CnDiY61e.cjs +5 -0
  4. package/components/CashierError-DaumM6Zr.js +3758 -0
  5. package/components/CashierHeader-4ARwc1sM.cjs +1 -0
  6. package/components/CashierHeader-CYcLko5g.js +361 -0
  7. package/components/CashierIframeRedirect-BOPLcueW.cjs +1 -0
  8. package/components/CashierIframeRedirect-Bilctj-5.js +384 -0
  9. package/components/CashierMethodDetails-7O4DrJHq.cjs +18 -0
  10. package/components/CashierMethodDetails-CJU3RjOA.js +8096 -0
  11. package/components/CashierModal-CdNYc0Aj.js +220 -0
  12. package/components/CashierModal-DjXj2L6b.cjs +1 -0
  13. package/components/CashierNotifications-BVX2JvTh.cjs +1 -0
  14. package/components/CashierNotifications-DOgyzpyH.js +136 -0
  15. package/components/CashierReceiptPage-D9_BjYHP.cjs +1 -0
  16. package/components/CashierReceiptPage-DT7FhfRz.js +1093 -0
  17. package/components/CashierSpinner-BUe-mWNE.js +71 -0
  18. package/components/CashierSpinner-C7awkOxo.cjs +1 -0
  19. package/es2015/cashier-method-details.cjs +1 -0
  20. package/es2015/cashier-method-details.js +16 -0
  21. package/package.json +22 -32
  22. package/CHANGELOG.md +0 -36
  23. package/README.md +0 -30
  24. package/dist/cashier-method-details.js +0 -875
  25. package/dist/cashier-method-details.js.map +0 -1
  26. package/index.html +0 -36
  27. package/index.js +0 -1
  28. package/public/favicon.png +0 -0
  29. package/public/reset.css +0 -48
  30. package/rollup.config.js +0 -65
  31. package/src/CashierMethodDetails.svelte +0 -1539
  32. package/src/CashierMethodDetails.types.ts +0 -68
  33. package/src/i18n.js +0 -32
  34. package/src/index.ts +0 -4
  35. package/src/translations.js +0 -46
  36. package/stories/CashierMethodDetails.stories.js +0 -13
  37. package/tsconfig.json +0 -6
@@ -1,1539 +0,0 @@
1
- <svelte:options tag={null} />
2
-
3
- <script lang="ts">
4
- import { onMount } from "svelte";
5
- import { isMobile } from 'rvhelper';
6
- import { _, addNewMessages, setupI18n, setLocale } from './i18n';
7
- import { TRANSLATIONS } from './translations';
8
-
9
- import '@everymatrix/cashier-iframe-redirect';
10
- import '@everymatrix/cashier-receipt-page';
11
- import '@everymatrix/cashier-confirm-modal';
12
- import '@everymatrix/cashier-notifications';
13
- import '@everymatrix/cashier-error';
14
- import '@everymatrix/cashier-modal';
15
- import flatpickr from "flatpickr";
16
- import "flatpickr/dist/flatpickr.min.css";
17
- import FlatpickrLanguages from "flatpickr/dist/l10n";
18
- import dayjs from 'dayjs';
19
- import utc from 'dayjs/plugin/utc';
20
- dayjs.extend(utc);
21
- import customParseFormat from 'dayjs/plugin/customParseFormat';
22
- import type {DateTimeFormat, PaymentMethod} from "./CashierMethodDetails.types";
23
- export class PaymentMethodDetails {
24
- name: string;
25
- label: string;
26
- description: string;
27
- type: FieldTypes;
28
- defaultValue: any;
29
- format: string;
30
- placeholder: string;
31
- displayPlaceholder?: string;
32
- isReadonly: boolean;
33
- isRequired: boolean;
34
- isPrimaryField: boolean;
35
- demandUserInput: boolean;
36
- autoTrim: boolean;
37
- maxValue: string;
38
- minValue: string;
39
- autoUppercase: boolean;
40
- correlationFieldName: string;
41
- correlationFieldValue: string[];
42
- notEqualToFieldName: string;
43
- values: any[];
44
- selected: Object;
45
- useCopyButton: boolean;
46
- inputMask: string[];
47
- tags: string;
48
- constructor(element: any) {
49
- this.correlationFieldName = element.CorrelationFieldName || null;
50
- this.correlationFieldValue = element.CorrelationFieldValue && element.CorrelationFieldValue.length > 0 ?
51
- element.CorrelationFieldValue.split(',') : [];
52
- this.name = element.Name || null;
53
- this.label = element.Label || null;
54
- this.description = element.Description || null;
55
- this.type = fieldTypeMap.get(element.Type) || null;
56
- this.defaultValue = this.calcDefaultValue(element);
57
- this.format = this.setPlaceholderOrFormat(element, FieldParams.Format);
58
- this.placeholder = this.setPlaceholderOrFormat(element, FieldParams.Placeholder);
59
- this.isReadonly = element.IsReadonly || false;
60
- this.isRequired = element.IsRequired || false;
61
- this.maxValue = this.setValue(element, FieldParams.MaxValue);
62
- this.minValue = this.setValue(element, FieldParams.MinValue);
63
- this.isPrimaryField = element.IsPrimaryField || false;
64
- this.demandUserInput = element.DemandUserInput || false;
65
- this.autoTrim = element.AutoTrim || false;
66
- this.autoUppercase = element.AutoUppercase || false;
67
- this.notEqualToFieldName = element.NotEqualToFieldName || null;
68
- this.values = element.Values;
69
- this.useCopyButton = element.UseCopyButton || false;
70
- this.inputMask = element.InputMask;
71
- this.tags = element.Tags || null;
72
- }
73
-
74
- calcDefaultValue(element) {
75
- if (this.type === FieldTypes.Boolean) {
76
- return element.DefaultValue === 'True';
77
- } else if (defaultDateTimeFormatMap.has(element.Type)){
78
- return this.setValue(element, FieldParams.DefaultValue)
79
- } else {
80
- return element.DefaultValue || null;
81
- }
82
- }
83
- setPlaceholderOrFormat(element, paramsType) {
84
- if (defaultDateTimeFormatMap.has(element.Type) && !dateTimeFormatsMap.get(element.Placeholder)) {
85
- return defaultDateTimeFormatMap.get(element.Type)[paramsType];
86
- } else {
87
- return element[paramsType] || null;
88
- }
89
- }
90
- setValue(element, paramsType: string): string | null {
91
- if (defaultDateTimeFormatMap.has(element.Type) && !dateTimeFormatsMap.get(element.Placeholder)) {
92
- return dayjs(element[paramsType], element.Placeholder).format(defaultDateTimeFormatMap.get(element.Type).Placeholder)
93
- } else {
94
- return element[paramsType] || null;
95
- }
96
- }
97
- get descriptionWithLink(): string {
98
- if ((FieldTypes[this.type] === 'Boolean' && this.placeholder) || (FieldTypes[this.type] === 'Link')) {
99
- const regex = /{link}/i;
100
- const link = this.placeholder || this.defaultValue;
101
- const html = `<a href="${link}" target="_blank" rel="noopener noreferrer">${this.label}</a>`;
102
- if (this.description.match(regex)) {
103
- return this.description.replace(regex, html);
104
- }
105
- return `${this.description} ${html}`;
106
- }
107
- return this.description
108
- }
109
- }
110
- const mapReducer = (arr, [keys, val]) => [
111
- ...arr,
112
- ...(Array.isArray(keys) ? [...keys.map(key => [key, val])] : [[keys, val]]
113
- )
114
- ];
115
- enum TxnType {
116
- Deposit='Deposit',
117
- Withdraw='Withdraw'
118
- }
119
-
120
- enum ResponseCode {
121
- PlayerSessionIsNotValid = 'PlayerSessionIsNotValid',
122
- Success = 'Success',
123
- JwtTokenError = 'JwtTokenError',
124
- Maintenance = 'Maintenance'
125
- }
126
-
127
- const VISIBLE_FIELD_TYPES: string[] = 'Text,Number,Money,Boolean,Lookup,Date,Time,DateTime,Password,Label,Link,QRCode'.split(',');
128
-
129
- enum RedirectionModeStringEnum {
130
- Default = 'Default',
131
- RedirectWithRetry = 'Redirect'
132
- }
133
-
134
- const redirectModeMap = new Map([
135
- [['Default', 0], RedirectionModeStringEnum.Default],
136
- [['Redirect', 1], RedirectionModeStringEnum.RedirectWithRetry]
137
- ].reduce(mapReducer, []));
138
-
139
- enum FieldTypes {
140
- Unknown ='Unknown',
141
- Text ='Text',
142
- Boolean ='Boolean',
143
- Number ='Number',
144
- Money ='Money',
145
- DateTime ='DateTime',
146
- Lookup ='Lookup',
147
- IpAddress ='IpAddress',
148
- Date ='Date',
149
- Time ='Time',
150
- LookupCollection = 'LookupCollection',
151
- Hidden = 'Hidden',
152
- Label = 'Label',
153
- Password = 'Password',
154
- Link = 'Link',
155
- Image = 'Image',
156
- Html = 'Html',
157
- QRCode = 'QR'
158
- }
159
-
160
- enum FieldParams {
161
- MaxValue = 'MaxValue',
162
- MinValue = 'MinValue',
163
- DefaultValue = 'DefaultValue',
164
- Placeholder = 'Placeholder',
165
- Format = 'Format'
166
- }
167
-
168
- const defaultDateTimeFormatMap = new Map<FieldTypes, DateTimeFormat>([
169
- [FieldTypes.Date, {Placeholder: 'MM/DD/YYYY', Format: '^\\d{2}\/\\d{2}\/\\d{4}$' }],
170
- [FieldTypes.Time, { Placeholder: 'HH:mm', Format: '^\\d{2}:\\d{2}$' }],
171
- [FieldTypes.DateTime, {Placeholder: 'MM/DD/YYYY HH:mm', Format: '^\\d{2}\/\\d{2}\/\\d{4} \\d{2}:\\d{2}$'}]
172
- ]);
173
- const dateTimeFormatsMap = new Map<string, string>([
174
- ['MM/DD/YYYY HH:mm', 'm/d/Y H:i'],
175
- ['DD.MM.YYYY HH:mm', 'd.m.Y H:i'],
176
- ['YYYY-MM-DD', 'Y-m-d'],
177
- ['MM/DD/YYYY', 'm/d/Y'],
178
- ['DD/MM/YYYY', 'd/m/Y'],
179
- ['YYYY.MM.DD', 'Y.m.d'],
180
- ['HH:mm', 'H:i']
181
- ]);
182
- const fieldTypeMap = new Map([
183
- [['Unknown', 0], FieldTypes.Unknown],
184
- [['Text', 1], FieldTypes.Text],
185
- [['Boolean', 2], FieldTypes.Boolean],
186
- [['Number', 3], FieldTypes.Number],
187
- [['Money', 4], FieldTypes.Money],
188
- [['DateTime', 5], FieldTypes.DateTime],
189
- [['Lookup', 6], FieldTypes.Lookup],
190
- [['IpAddress', 7], FieldTypes.IpAddress],
191
- [['Date', 8], FieldTypes.Date],
192
- [['Time', 9], FieldTypes.Time],
193
- [['LookupCollection', 10], FieldTypes.LookupCollection],
194
- [['Hidden', 11], FieldTypes.Hidden],
195
- [['Label', 12], FieldTypes.Label],
196
- [['Password', 13], FieldTypes.Password],
197
- [['Link', 14], FieldTypes.Link],
198
- [['Image', 15], FieldTypes.Image],
199
- [['Html', 19], FieldTypes.Html],
200
- [['QR', 20], FieldTypes.QRCode]
201
- ].reduce(mapReducer, []))
202
- export let endpoint: string;
203
- export let session: string;
204
- export let playersession: string;
205
- export let lang: string = 'en';
206
- export let local: string = 'en-US';
207
- export let translationurl: string;
208
- export let customerid: string;
209
- export let currency: string;
210
- export let amount: string;
211
- export let assetsurl: string;
212
- export let type: string = TxnType.Deposit;
213
- export let selectedpaymentmethodname: string;
214
- export let clientstyling:string = '';
215
- export let clientstylingurl:string = ''
216
- export let ismobileview:string
217
-
218
- let xPaymentSessionToken: string;
219
- let selectedPaymentMethod: PaymentMethod = {} as PaymentMethod;
220
- let fields: PaymentMethodDetails[] = [];
221
- let prepareFields = {};
222
- let displayNone: boolean = false;
223
- let customStylingContainer: HTMLElement;
224
- let prepareRequest;
225
- let showConfirmModal: boolean = false;
226
- let showReceiptPage: boolean = false;
227
- let redirectUrl: string;
228
- let windowRedirect: Window;
229
- let showRedirectNotification: boolean;
230
- let redirectMode: RedirectionModeStringEnum;
231
- let showRetryNotification: boolean;
232
- let isProcessingTxn: boolean;
233
- let isTranslationLoaded: boolean;
234
- let openedLookup: string | null;
235
- let clickedElem: HTMLElement;
236
- let qrCodeContainer: HTMLElement[] = [];
237
- let flatpickrEl: HTMLElement[] = [];
238
- let qrCodeScriptSrc: string = 'https://cdn.rawgit.com/davidshimjs/qrcodejs/gh-pages/qrcode.min.js';
239
- let blankPageTarget: string = '_blank';
240
- let externalLink: string = '';
241
- let mobileView: boolean = false;
242
- let innerWidth: number;
243
- let formatter = new Intl.NumberFormat(local, {minimumFractionDigits: 2 });
244
- let amountError = '';
245
- let showError = {};
246
- let fieldValidation = {};
247
- let openLookupTop = false;
248
- let maxLookupHeight: number;
249
- let editedAmount: number;
250
- let errorResponseCode: string;
251
- let isDisabled: boolean;
252
- let showErrorModal = false;
253
- let transactionId = '';
254
- let showSpinner: boolean = false;
255
- let abortController = new AbortController();
256
-
257
- $: endpoint && session && selectedpaymentmethodname && currency && initMethod();
258
- $: clientstyling && customStylingContainer && setClientStyling();
259
- $: clientstylingurl && customStylingContainer && setClientStylingURL();
260
- $: lang && setActiveLanguage();
261
- $: lang && translationurl && setTranslationUrl();
262
- $: ismobileview && setDevice()
263
- $: fields.length && qrCodeContainer.length && generateQr();
264
- $: fields.length && flatpickrEl.length && createDatePicker();
265
-
266
- const initMethod = () => {
267
- if (flatpickrEl.length) {
268
- flatpickrEl.forEach(el => {
269
- if (!el) {
270
- return;
271
- }
272
- flatpickr(el).destroy();
273
- })
274
- }
275
- showReceiptPage = false;
276
- showRetryNotification = false;
277
- flatpickrEl = [];
278
- fields = [];
279
- prepareFields = {};
280
- showError = {};
281
- fieldValidation = {};
282
- qrCodeContainer = [];
283
- selectedPaymentMethod = null;
284
- errorResponseCode = '';
285
- showErrorModal = false;
286
- showSpinner = true;
287
- setErrorResponseCode();
288
- getPaymentDetails();
289
- }
290
-
291
- const setDevice = () => {
292
- mobileView = ismobileview === 'true';
293
- }
294
-
295
- const generateQr = () => {
296
- qrCodeContainer.forEach(elem => {
297
- if (elem && elem.innerText) {
298
- const url = elem.innerText
299
- elem.innerText = ''
300
- new QRCode(elem, {
301
- text: url,
302
- width: 250,
303
- height: 250,
304
- });
305
- }
306
- })
307
- }
308
-
309
- const reinitMethod = (e) => {
310
- if (abortController?.signal?.aborted && selectedpaymentmethodname === e.detail.Name) {
311
- initMethod()
312
- }
313
- }
314
-
315
- const createDatePicker = () => {
316
- const dateOptions = {
317
- [FieldTypes.Time]: {
318
- noCalendar: true,
319
- enableTime: true,
320
- allowInput: true
321
- },
322
- [FieldTypes.Date]: {
323
- allowInput: true,
324
- locale: {...FlatpickrLanguages[lang]}
325
- },
326
- [FieldTypes.DateTime]: {
327
- allowInput: true,
328
- enableTime: true,
329
- locale: {...FlatpickrLanguages[lang]}
330
- }
331
- }
332
- flatpickrEl.forEach((el) => {
333
- if(!el) {
334
- return;
335
- }
336
- const field = JSON.parse(el.dataset.field);
337
- const dateFormat = dateTimeFormatsMap.get(field.placeholder);
338
- const timeformat = field.type === FieldTypes.DateTime ? dateTimeFormatsMap.get(field.placeholder.split(' ')[1]) : dateFormat;
339
- flatpickr(el, {...dateOptions[field.type], dateFormat: dateFormat, time_24hr: timeformat === 'H:i', maxDate: field.maxValue, minDate: field.minValue, defaultDate: field.defaultValue,
340
- onReady: (selectedDates, dateStr) => {
341
- prepareFields[field.name] = dateStr;
342
- dateTimeValidation(field);
343
- },
344
- onClose: (selectedDates, dateStr, instance) => {
345
- if(!fieldValidation[field.name]) {
346
- prepareFields[field.name] = dateStr;
347
- } else {
348
- prepareFields[field.name] = '';
349
- }
350
- }
351
- })
352
- });
353
- }
354
-
355
- const setActiveLanguage = ():void => {
356
- setLocale(lang);
357
- }
358
-
359
- const setTranslationUrl = () => {
360
- let url:string = translationurl;
361
- if (url) {
362
- return fetch(url).then((res:any) => res.json())
363
- .then((res) => {
364
- Object.keys(res).forEach((item:any):void => {
365
- addNewMessages(item, res[item]);
366
- isTranslationLoaded = true;
367
- });
368
- }).catch((err:any) => {
369
- isTranslationLoaded = true;
370
- });
371
- }
372
- }
373
-
374
- Object.keys(TRANSLATIONS).forEach((item:any):void => {
375
- addNewMessages(item, TRANSLATIONS[item]);
376
- });
377
-
378
- const getPaymentDetails = () => {
379
- abortPaymentFetch();
380
- abortController = new AbortController();
381
- const signal = abortController.signal;
382
- showSpinner = true;
383
- const url:URL = new URL(`${endpoint}/v1/player/${customerid}/payment/GetPaymentMethod`);
384
- const headers = new Headers();
385
- headers.append("accept", "application/json");
386
- headers.append("Content-Type", "application/json");
387
- headers.append("X-Client-Request-Timestamp", dayjs.utc().format("YYYY-MM-DD HH:mm:ss.SSS"));
388
- const requestParams:RequestInit = {
389
- method: "POST",
390
- mode: "cors",
391
- headers: headers,
392
- body: JSON.stringify({
393
- "PaymentMethodName": selectedpaymentmethodname,
394
- "Currency": currency,
395
- "XPaymentSessionToken": session
396
- })
397
- }
398
- fetch(url, requestParams).then(res => res.json()).then(data => {
399
- if (!signal.aborted) {
400
- if (data.error) {
401
- window.postMessage({type: 'ShowSessionError', error: data.error}, window.location.href)
402
- return;
403
- }
404
- if (data.ResponseCode === ResponseCode.PlayerSessionIsNotValid
405
- || data.ResponseCode === ResponseCode.Maintenance
406
- || data.ResponseCode === ResponseCode.JwtTokenError) {
407
- errorResponseCode = data.ResponseCode;
408
- setErrorResponseCode();
409
- return;
410
- }
411
- if (data.ResponseCode !== ResponseCode.Success) {
412
- errorResponseCode = data.ResponseCode;
413
- return;
414
- }
415
- xPaymentSessionToken = data.XPaymentSessionToken;
416
- selectedPaymentMethod = data.PaymentMethod;
417
- editedAmount = Number(amount);
418
- if (!selectedPaymentMethod.HideAmountField) {
419
- validateAmount();
420
- } else {
421
- amountError = '';
422
- }
423
- fields = selectedPaymentMethod.Fields && selectedPaymentMethod.Fields.map(field => new PaymentMethodDetails(field));
424
- fields.forEach(field => {
425
- if (field?.defaultValue) {
426
- prepareFields[field.name] = field.defaultValue;
427
- }
428
- validateField(field);
429
- })
430
- setConfirmModalInfo();
431
- setErrorResponseCode();
432
- hideMethodsList();
433
- window.postMessage({
434
- type: 'StartSessionCountdown',
435
- xPaymentSessionToken,
436
- selectedPaymentMethodName: selectedpaymentmethodname
437
- }, window.location.href);
438
- }
439
- }).finally(() => { showSpinner = signal.aborted })
440
- }
441
-
442
- const abortPaymentFetch = ():void => {
443
- if (abortController) {
444
- abortController.abort();
445
- }
446
- }
447
-
448
- const setClientStyling = ():void => {
449
- let sheet = document.createElement('style');
450
- sheet.innerHTML = clientstyling;
451
- customStylingContainer.appendChild(sheet);
452
- }
453
-
454
- const setClientStylingURL = ():void => {
455
- displayNone = true;
456
-
457
- let url:URL = new URL(clientstylingurl);
458
- let cssFile:HTMLElement = document.createElement('style');
459
-
460
- fetch(url.href)
461
- .then((res:any) => res.text())
462
- .then((data:any) => {
463
- cssFile.innerHTML = data
464
-
465
- setTimeout(() => { customStylingContainer.appendChild(cssFile) }, 1);
466
- setTimeout(() => { displayNone = false; }, 500);
467
- });
468
- }
469
-
470
- const messageHandler = (e:any) => {
471
- if (e.data.type === 'ErrorResponseCode') {
472
- errorResponseCode = e.data.errorResponseCode;
473
- showReceiptPage = e.data.showErrorOutsideReceiptPage;
474
- }
475
- if (e.data.type === 'ReceiptLoaded') {
476
- closeIframe()
477
- }
478
- if (e.data.type === 'BackCashier') {
479
- backToMethodList()
480
- }
481
- if (e.data.type === 'CloseCashierReceiptPage') {
482
- closeReceiptPage()
483
- }
484
- }
485
-
486
- onMount(() => {
487
- window.addEventListener('closeModal', closeModal, false);
488
- window.addEventListener('confirmModal', confirmTxn, false);
489
- window.addEventListener('closeIframe', closeIframe, false);
490
- window.addEventListener('notificationButtonClick', retryRedirect, false);
491
- window.addEventListener('selectPayMeth', reinitMethod, false)
492
- document.addEventListener('click',closeAllLookups);
493
- window.addEventListener('message', messageHandler, false);
494
- dayjs.extend(customParseFormat);
495
-
496
- return () => {
497
- window.removeEventListener('closeModal', closeModal);
498
- window.removeEventListener('confirmModal', confirmTxn);
499
- window.removeEventListener('closeIframe', closeIframe);
500
- window.removeEventListener('notificationButtonClick', retryRedirect);
501
- window.removeEventListener('selectPayMeth', reinitMethod, false)
502
- window.removeEventListener('message', messageHandler);
503
- }
504
- });
505
-
506
- const closeAllLookups = (e) => {
507
- if (openedLookup) {
508
- showError[openedLookup] = true;
509
- validateField(fields.find(field => field.name === openedLookup));
510
- }
511
- if (!e.composedPath().includes(clickedElem)) {
512
- openedLookup = null;
513
- }
514
- }
515
-
516
- const showLookup = (event, name) => {
517
- if (name === openedLookup) {
518
- showError[openedLookup] = true;
519
- validateField(fields.find(field => field.name === openedLookup));
520
- openedLookup = null
521
- return;
522
- }
523
- event.stopPropagation();
524
- clickedElem = event.composedPath()[0]
525
- const innerContainer = clickedElem.getBoundingClientRect();
526
- const outerContainer = customStylingContainer.getBoundingClientRect()
527
- const clickY = innerContainer.y;
528
- const minLookupHeight = 200;
529
- openLookupTop = (window.innerHeight - clickY) < minLookupHeight;
530
- const topSpace = innerContainer.top - outerContainer.top - innerContainer.height;
531
- const bottomSpace = outerContainer.bottom - innerContainer.bottom - innerContainer.height;
532
- const dropdownSizeBottom = !openLookupTop && bottomSpace < 70 ? minLookupHeight - 50 : bottomSpace;
533
- maxLookupHeight = openLookupTop ? topSpace : dropdownSizeBottom;
534
- openedLookup = name
535
- }
536
-
537
- const prepareTxn = () => {
538
- if (isDisabled) {
539
- return;
540
- }
541
- isProcessingTxn = true;
542
- const url:URL = new URL(`${endpoint}/v1/player/${customerid}/payment/GetPaymentPrepare`);
543
- const headers = new Headers();
544
- headers.append("accept", "application/json");
545
- headers.append("Content-Type", "application/json");
546
- headers.append("X-Client-Request-Timestamp", dayjs.utc().format("YYYY-MM-DD HH:mm:ss.SSS"));
547
- toggleDisableActionOnPage();
548
- const requestParams:RequestInit = {
549
- method: "POST",
550
- mode: "cors",
551
- headers: headers,
552
- body: JSON.stringify({
553
- "XPaymentSessionToken": xPaymentSessionToken,
554
- "Transaction": {
555
- "PaymentMethod": selectedPaymentMethod.Name,
556
- "Amount": editedAmount,
557
- "Currency": currency,
558
- "CustomFields": prepareFields
559
- },
560
- "Account": {}
561
- })
562
- }
563
- fetch(url, requestParams).then((res) => res.json()).then(data => {
564
- if (data.error) {
565
- postMessage({type: 'ShowSessionError', error: data.error}, window.location.href)
566
- return;
567
- }
568
- if (data.ResponseCode !== ResponseCode.Success) {
569
- errorResponseCode = data.ResponseCode
570
- isProcessingTxn = false;
571
- toggleDisableActionOnPage();
572
- if (data.ResponseCode === ResponseCode.PlayerSessionIsNotValid
573
- || data.ResponseCode === ResponseCode.Maintenance
574
- || data.ResponseCode === ResponseCode.JwtTokenError) {
575
- setErrorResponseCode();
576
- } else {
577
- showModal()
578
- }
579
- return;
580
- }
581
- xPaymentSessionToken = data.XPaymentSessionToken;
582
- isProcessingTxn = false;
583
- showConfirmModal = true;
584
- setConfirmModalInfo();
585
- toggleDisableActionOnPage();
586
- window.postMessage({ type: 'StartSessionCountdown', xPaymentSessionToken, selectedPaymentMethodName: selectedPaymentMethod.Name }, window.location.href);
587
- })
588
- }
589
-
590
- const setErrorResponseCode = () => {
591
- window.postMessage({type: 'ErrorResponseCode', errorResponseCode}, window.location.href);
592
- }
593
-
594
- const setConfirmModalInfo = () => {
595
- window.postMessage({type:'ShowConfirmModal', showConfirmModal, editedAmount, hideAmountField: selectedPaymentMethod.HideAmountField}, window.location.href);
596
- }
597
-
598
- const setRedirectInfo = () => {
599
- window.postMessage({type: 'RedirectInfo', redirectMode, redirectUrl}, window.location.href);
600
- }
601
-
602
- const showModal = () => {
603
- showErrorModal = true;
604
- window.postMessage({ type: 'ShowCashierModal', modalErrorMessage: errorResponseCode}, window.location.href)
605
- }
606
-
607
- const backToMethodList = () => {
608
- dispatchEvent(new CustomEvent('backToMethodList', {
609
- bubbles: true,
610
- cancelable: true,
611
- composed: true
612
- }));
613
- hidePaymentDetails()
614
- }
615
-
616
- const toggleDisableActionOnPage = () => {
617
- window.postMessage({type: 'ToggleDisableActionOnPage', disable: isProcessingTxn}, window.location.href)
618
- }
619
-
620
- const hidePaymentDetails = () => {
621
- if (showSpinner) {
622
- abortPaymentFetch()
623
- }
624
- dispatchEvent(new CustomEvent('hidePaymentDetails', {
625
- detail: { hideMethodDetails: mobileView },
626
- bubbles: true,
627
- cancelable: true,
628
- composed: true
629
- }));
630
- }
631
-
632
- const hideMethodsList = () => {
633
- dispatchEvent(new CustomEvent('hideMethodsList', {
634
- detail: { hideMethodsList: mobileView },
635
- bubbles: true,
636
- cancelable: true,
637
- composed: true
638
- }));
639
- }
640
-
641
- const closeIframe = () => {
642
- redirectUrl = null;
643
- showReceiptPage = true;
644
- setRedirectInfo();
645
- }
646
-
647
- const closeModal = () => {
648
- showConfirmModal = false;
649
- }
650
-
651
- const confirmTxn = () => {
652
- isProcessingTxn = true;
653
- const url:URL = new URL(`${endpoint}/v1/player/${customerid}/payment/GetPaymentConfirm`);
654
- const headers = new Headers();
655
- headers.append("accept", "application/json");
656
- headers.append("Content-Type", "application/json");
657
- headers.append("X-Client-Request-Timestamp", dayjs.utc().format("YYYY-MM-DD HH:mm:ss.SSS"));
658
- toggleDisableActionOnPage();
659
- const requestParams:RequestInit = {
660
- method: "POST",
661
- mode: "cors",
662
- headers: headers,
663
- body: JSON.stringify({
664
- "XPaymentSessionToken": xPaymentSessionToken,
665
- })
666
- }
667
- fetch(url, requestParams).then((res) => res.json()).then(data => {
668
- if (data.ResponseCode !== ResponseCode.Success) {
669
- errorResponseCode = data.ResponseCode
670
- isProcessingTxn = false;
671
- toggleDisableActionOnPage();
672
- if (data.ResponseCode === ResponseCode.PlayerSessionIsNotValid
673
- || data.ResponseCode === ResponseCode.Maintenance
674
- || data.ResponseCode === ResponseCode.JwtTokenError) {
675
- setErrorResponseCode();
676
- } else {
677
- showModal()
678
- }
679
- return;
680
- }
681
- xPaymentSessionToken = data.XPaymentSessionToken;
682
- transactionId = data.Transaction.Code;
683
- redirectUrl = data.RedirectUrl;
684
- redirectMode = redirectModeMap.get(data.RedirectionMode) || redirectModeMap.get('Default');
685
- isProcessingTxn = false;
686
- toggleDisableActionOnPage();
687
- setRedirectInfo();
688
- window.postMessage({ type: 'StartSessionCountdown', xPaymentSessionToken, selectedpaymentmethodname: selectedpaymentmethodname }, window.location.href);
689
- if (!redirectUrl) {
690
- showReceiptPage = true;
691
- }
692
- if (redirectMode === RedirectionModeStringEnum.RedirectWithRetry) {
693
- windowRedirect = window.open(data.RedirectUrl, '_blank');
694
- showRedirectNotification = !!windowRedirect;
695
- if (!windowRedirect) {
696
- showRetryNotification = true;
697
- }
698
- }
699
- })
700
- }
701
- const retryRedirect = () => {
702
- windowRedirect = window.open(redirectUrl, '_blank');
703
- showRedirectNotification = true;
704
- showRetryNotification = false;
705
- setRedirectInfo();
706
- }
707
-
708
- const closeReceiptPage = () => {
709
- showReceiptPage = false
710
- }
711
- const openUrlInNewTab = (url) => {
712
- if (!url) {
713
- return
714
- }
715
- window.postMessage({ type: 'NavigateTo', path: url, target: blankPageTarget || null, externalLink: externalLink || false }, window.location.href);
716
- }
717
-
718
- const onLookUpChanged = (field, value) => {
719
- prepareFields[field.name] = value;
720
- fields.filter(el => el.correlationFieldName).forEach(el => validateField(el));
721
- }
722
-
723
- const getValueByFieldName = (values:any[], name:string):string => {
724
- const fieldValue = name ? values.find(el => el.Name === name).Value : '';
725
- return fieldValue;
726
- }
727
-
728
- const showField = (field) => {
729
- if (!field.correlationFieldName) {
730
- return true;
731
- }
732
- const isCorrelatedFieldVisible = field.correlationFieldValue.includes(prepareFields[field.correlationFieldName])
733
- if (!isCorrelatedFieldVisible && prepareFields[field.name]) {
734
- delete prepareFields[field.name]
735
- }
736
- return isCorrelatedFieldVisible
737
- }
738
-
739
- const emptyAmountError = ():string => {
740
- if (!editedAmount) {
741
- return $_('errorEmptyField')
742
- }
743
- return ''
744
- }
745
-
746
- const minAmountError = () => {
747
- if (selectedPaymentMethod.DisplayCurrency.MinAmountLimit > editedAmount) {
748
- return $_('minAmountError', {
749
- values: {
750
- amount: formatter.format(selectedPaymentMethod.DisplayCurrency.MinAmountLimit),
751
- currency: selectedPaymentMethod.DisplayCurrency.Name
752
- }
753
- })
754
- }
755
- return ''
756
- }
757
-
758
- const maxAmountError = () => {
759
- if (selectedPaymentMethod.DisplayCurrency.MaxAmountLimit < editedAmount) {
760
- return $_('maxAmountError', {
761
- values: {
762
- amount: formatter.format(selectedPaymentMethod.DisplayCurrency.MaxAmountLimit),
763
- currency: selectedPaymentMethod.DisplayCurrency.Name
764
- }
765
- })
766
- }
767
- return ''
768
- }
769
-
770
- const amountMultiplierError = () => {
771
- if (selectedPaymentMethod.AmountMultiplier && (editedAmount % selectedPaymentMethod.AmountMultiplier !== 0)) {
772
- return $_('amountMultiplierError', {
773
- values: {
774
- multiplier: selectedPaymentMethod.AmountMultiplier
775
- }
776
- })
777
- }
778
- return ''
779
- }
780
-
781
- const amountIntError = ():string => {
782
- if (selectedPaymentMethod.IsIntegerAmount && !Number.isInteger(editedAmount)) {
783
- return $_('amountIntError')
784
- }
785
- return ''
786
- }
787
-
788
- const amountDecimalError = ():string => {
789
- if (Number(editedAmount).toFixed(2) != +editedAmount) {
790
- return $_('amountDecimalError')
791
- }
792
- return ''
793
- }
794
-
795
- const patternValidator = (pattern, value) => {
796
- if (!pattern) return true;
797
- let regex;
798
- let regexStr;
799
- if (typeof pattern === 'string') {
800
- regexStr = '';
801
- if (pattern.charAt(0) !== '^') regexStr += '^';
802
- regexStr += pattern;
803
- if (pattern.charAt(pattern.length - 1) !== '$') regexStr += '$';
804
- regex = new RegExp(regexStr);
805
- }
806
- else {
807
- regexStr = pattern.toString();
808
- regex = pattern;
809
- }
810
- return regex.test(value);
811
- }
812
-
813
- const patternMatchesError = (field, value):string => {
814
- if (field.format && value && !patternValidator(field.format, value)) {
815
- return $_('invalidFieldError',{ values: { field: field.label }})
816
- }
817
- return ''
818
- }
819
-
820
- const emptyFieldError = (field, value):string => {
821
- if (typeof value !== 'boolean' && field.isRequired && (!value || !value.toString().trim())) {
822
- return $_('errorEmptyField')
823
- }
824
- return ''
825
- }
826
-
827
- const keydownHandler = (event: KeyboardEvent) => {
828
- const invalidKeys = ['+','-','e','E'];
829
- if (invalidKeys.includes(event.key)) {
830
- event.preventDefault();
831
- }
832
- }
833
- const validateAmount = () => {
834
- amountError = emptyAmountError() || minAmountError() ||
835
- maxAmountError() || amountMultiplierError() ||
836
- amountIntError() || amountDecimalError();
837
- }
838
-
839
- const dateTimeValidation = (field) => {
840
- const value = prepareFields[field.name];
841
- const format = field.placeholder;
842
- const inputValue = dayjs(value, format);
843
- const maxValue = dayjs(field.maxValue, format);
844
- const minValue = dayjs(field.minValue, format);
845
- if (inputValue.isBefore(minValue) || inputValue.isAfter(maxValue)) {
846
- fieldValidation[field.name] = $_('invalidFieldError',{ values: { field: field.label }})
847
- return;
848
- }
849
- fieldValidation[field.name] = showField(field) ? (emptyFieldError(field, value) || patternMatchesError(field, value)) : '';
850
- }
851
-
852
- const validateField = (field) => {
853
- const value = prepareFields[field.name]
854
- fieldValidation[field.name] = showField(field) ? (emptyFieldError(field, value) || patternMatchesError(field, value)) : '';
855
- }
856
-
857
- const isSubmitDisabled = (amountError, fieldValidation) => {
858
- isDisabled = !!amountError || Object.values(fieldValidation).some(error => !!error);
859
- return isDisabled;
860
- }
861
-
862
- </script>
863
- <svelte:window bind:innerWidth={innerWidth} />
864
- <svelte:head>
865
- <script src={qrCodeScriptSrc}></script>
866
- </svelte:head>
867
- <div class="CashierMethodDetails" bind:this={customStylingContainer}>
868
- {#if showSpinner}
869
- <cashier-spinner
870
- {clientstylingurl}
871
- {clientstyling}
872
- ></cashier-spinner>
873
- {/if}
874
- {#if selectedPaymentMethod?.Name}
875
- <div class="MethodsDetails" class:DisabledPage={showRetryNotification}>
876
- {#if !showReceiptPage && !errorResponseCode || (errorResponseCode && showErrorModal)}
877
- <form on:submit|preventDefault={prepareTxn} novalidate>
878
- <div class="FieldWrapper">
879
- <div class="FormLogo">
880
- <div class="SelectedLogoWrapper">
881
- <img src={selectedPaymentMethod.Logos[0] && selectedPaymentMethod.Logos[0].LogoUrl} alt={selectedPaymentMethod.Label} />
882
- </div>
883
- <div class="SelectedLogoDescription">
884
- {selectedPaymentMethod.Label || selectedPaymentMethod.Name}
885
- </div>
886
- {#if mobileView}
887
- <div on:click={() => backToMethodList()} class="ChangePaymeth">{$_('change')}</div>
888
- {/if}
889
- </div>
890
- {#if selectedPaymentMethod.Description}
891
- <div class="SelectedMethodDescription">
892
- {selectedPaymentMethod.Description}
893
- </div>
894
- {/if}
895
- {#if !selectedPaymentMethod.HideAmountField}
896
- <div class="Amount" class:Invalid={amountError && showError['amount']}>
897
- <label>
898
- <span class="Required">
899
- {$_('amountLabel')}
900
- </span>
901
- {#if selectedPaymentMethod.IsAmountConfigurable}
902
- <input type="number"
903
- bind:value={editedAmount}
904
- on:input={() => validateAmount()}
905
- on:keydown={(event) => keydownHandler(event)}
906
- on:blur={() => {showError['amount'] = true; validateAmount()}}
907
- placeholder="{$_('amountPlaceholder')}"
908
- >
909
- <span class="Alert">{amountError}</span>
910
- {#if selectedPaymentMethod.DisplayCurrency}
911
- <span class="AmountLimits">
912
- {selectedPaymentMethod.DisplayCurrency.MinAmountLimit ? `${$_('generalMin')} ${formatter.format(selectedPaymentMethod.DisplayCurrency.MinAmountLimit)} ${currency}` : ''}
913
- {selectedPaymentMethod.DisplayCurrency.MaxAmountLimit ? `/ ${$_('generalMax')} ${formatter.format(selectedPaymentMethod.DisplayCurrency.MaxAmountLimit)} ${currency}` : ''}
914
- </span>
915
- {/if}
916
- {:else}
917
- <span class="NonConfigurableAmount">
918
- {formatter.format(amount)} {currency}
919
- </span>
920
- {/if}
921
- </label>
922
- </div>
923
- {/if}
924
- </div>
925
- {#each fields as field, index}
926
- {#if showField(field)}
927
- <div class="FieldWrapper"
928
- class:Hidden={field.type === FieldTypes.Hidden}
929
- class:Invalid={showError[field.name] && fieldValidation[field.name]}>
930
- <label>
931
- {#if field.label && field.type !== FieldTypes.Link && field.type !== FieldTypes.Boolean}
932
- <span class:Required={field.isRequired}>{field.label}</span>
933
- {/if}
934
- {#if field.description && field.description !== field.label && field.type !== FieldTypes.QRCode && field.type !== FieldTypes.Boolean && field.type !== FieldTypes.Link}
935
- <span class="Description">{field.description}</span>
936
- {/if}
937
- {#if field.type === FieldTypes.Text}
938
- <input type="text" bind:value={prepareFields[field.name]}
939
- placeholder="{field.placeholder}"
940
- on:input="{() => { validateField(field) }}"
941
- on:blur="{() => { showError[field.name] = true; validateField(field) }}">
942
- {:else if field.type === FieldTypes.Time || field.type === FieldTypes.Date || field.type === FieldTypes.DateTime}
943
- <div class="DateInput">
944
- <input class="DateTimePicker" type="text" bind:value={ prepareFields[field.name] } pattern={field.format}
945
- data-field={JSON.stringify(field)}
946
- placeholder={field.placeholder}
947
- on:input={() => { showError[field.name] = true; dateTimeValidation(field) }}
948
- on:change={() => { showError[field.name] = true; dateTimeValidation(field) }}
949
- on:blur={() => { showError[field.name] = true; dateTimeValidation(field) }}
950
- bind:this={flatpickrEl[flatpickrEl.length]}
951
- >
952
- <div class="MobileDateInput">{prepareFields[field.name] || field.placeholder}</div>
953
- </div>
954
- {:else if field.type === FieldTypes.Number || field.type === FieldTypes.Money}
955
- <input type="number" placeholder="{field.placeholder}" bind:value={prepareFields[field.name]}
956
- on:input="{() => { validateField(field) }}"
957
- on:blur="{() => { showError[field.name] = true; validateField(field) }}"
958
- >
959
- {:else if field.type === FieldTypes.Password}
960
- <input type="password" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}"
961
- on:input="{() => { validateField(field) }}"
962
- on:blur="{() => { showError[field.name] = true; validateField(field) }}"
963
- >
964
- {:else if field.type === FieldTypes.Hidden}
965
- <input type="hidden" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
966
-
967
- {:else if field.type === FieldTypes.Lookup}
968
- <div class="CustomSelect">
969
- <div class="Selected" id="{index}" on:click="{(e) => showLookup(e, field.name)}"> <span class="SelectedValue">{getValueByFieldName(field.values, prepareFields[field.name])}</span></div>
970
- <div class="OptionList"
971
- class:Opened={openedLookup === field.name}
972
- class:Top={openLookupTop}
973
- style="max-height: {`${maxLookupHeight}px`};"
974
- >
975
- {#each field.values as value}
976
- <div on:click="{() => {onLookUpChanged(field, value.Name); fields = fields}}">
977
- <span>{value.Value}</span>
978
- </div>
979
- {/each}
980
- </div>
981
- </div>
982
- {:else if field.type === FieldTypes.Boolean}
983
- <div class="Checkbox">
984
- <input type="checkbox" bind:checked={prepareFields[field.name]} placeholder="{field.placeholder}"
985
- on:change="{() => { showError[field.name] = true; validateField(field) }}"
986
- >
987
- <span class="Checkmark"></span>
988
- <span class="Description" class:Required={field.isRequired}>{@html field.descriptionWithLink}</span>
989
- </div>
990
- {:else if field.type === FieldTypes.QRCode}
991
- <div class="QRCode" on:click={() => {openUrlInNewTab(field.description)}}>
992
- <div bind:this={qrCodeContainer[qrCodeContainer.length]}>{field.defaultValue}</div>
993
- </div>
994
- {:else if field.type === FieldTypes.Link}
995
- <span>{@html field.descriptionWithLink}</span>
996
- {:else if field.type === FieldTypes.Label}
997
- <span class="Label"></span>
998
- {:else}
999
- <input type="text" bind:value={prepareFields[field.name]} placeholder="{field.placeholder}">
1000
- {/if}
1001
- </label>
1002
- <span class="Alert">{ fieldValidation[field.name] || '' }</span>
1003
- </div>
1004
- {/if}
1005
- {/each}
1006
- {#if !isProcessingTxn}
1007
- <button class="PrimaryButton" type="submit" disabled="{isSubmitDisabled(amountError, fieldValidation)}">
1008
- <svg class="ButtonLock" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
1009
- <path fill-rule="evenodd" clip-rule="evenodd" d="M7.51564 0.574496C6.49714 0.733152 5.5928 1.46162 5.21164 2.43037C5.01714 2.92471 4.98674 3.24368 4.98671 4.78987L4.98668 5.99306L4.55336 6.00671C4.20693 6.01762 4.08258 6.03221 3.93336 6.07946C3.43136 6.23846 3.00318 6.58293 2.73943 7.04C2.70133 7.106 2.63639 7.256 2.59508 7.37334L2.52002 7.58665V13.9067L2.59268 14.12C2.6993 14.4331 2.83849 14.6518 3.09336 14.9067C3.34821 15.1615 3.56693 15.3007 3.88002 15.4073L4.09336 15.48H11.9067L12.12 15.4073C12.4331 15.3007 12.6518 15.1615 12.9067 14.9067C13.1616 14.6518 13.3007 14.4331 13.4074 14.12L13.48 13.9067V7.58665L13.405 7.37334C13.1846 6.74712 12.6999 6.27875 12.0667 6.08C11.9191 6.03371 11.7891 6.0184 11.4467 6.00696L11.0134 5.99253L11.0133 4.78959C11.0133 4.128 11.0008 3.45465 10.9855 3.29334C10.9257 2.66268 10.7188 2.13556 10.3497 1.67368C9.66549 0.817589 8.6023 0.405214 7.51564 0.574496ZM8.46436 1.58665C9.01596 1.7035 9.52999 2.11659 9.79758 2.65809C9.98521 3.03771 9.98202 3.00646 9.99305 4.58L10.003 6H5.99702L6.00699 4.58C6.01802 3.00646 6.01483 3.03771 6.20246 2.65809C6.31793 2.42446 6.43799 2.26065 6.61818 2.09103C6.89043 1.83468 7.21371 1.65496 7.52352 1.58775C7.74977 1.53865 8.23518 1.53809 8.46436 1.58665ZM11.9201 7.0955C12.0975 7.17871 12.2992 7.37412 12.3874 7.54806C12.4231 7.61846 12.465 7.75796 12.4805 7.85803C12.4993 7.97978 12.5061 8.97962 12.501 10.88L12.4934 13.72L12.4082 13.8997C12.26 14.2127 12.0016 14.419 11.6821 14.4796C11.4864 14.5167 4.51364 14.5167 4.31793 14.4796C3.99843 14.419 3.74008 14.2127 3.59183 13.8997L3.50668 13.72L3.49905 10.88C3.49393 8.97728 3.50074 7.97987 3.51964 7.85778C3.57627 7.49218 3.79218 7.21543 4.12918 7.0765L4.28002 7.01431L8.02668 7.0205L11.7734 7.02665L11.9201 7.0955Z" fill="white"/>
1010
- </svg>
1011
- {$_(`${type.toLowerCase()}.makeTxnButton`)}
1012
- {#if !selectedPaymentMethod.HideAmountField}
1013
- <span class="ButtonAmount">{formatter.format(editedAmount || 0)} {currency}</span>
1014
- {/if}
1015
- </button>
1016
- {:else}
1017
- <button class="PrimaryButton">
1018
- <svg class="ButtonSpinner" xmlns="http://www.w3.org/2000/svg" width="15" height="14" viewBox="0 0 15 14" fill="none">
1019
- <path d="M14.0282 6.58425C13.9037 4.05374 12.3688 1.68916 10.0872 0.61058C7.59818 -0.509483 4.56986 -0.0531603 2.49567 1.68916C0.504443 3.34851 -0.408201 6.04496 0.172573 8.57547C0.711862 11.0645 2.6616 13.0972 5.10915 13.7609C8.0545 14.5906 10.7509 13.1802 12.4103 10.7741C10.9169 12.7653 8.63527 14.0928 6.10476 13.6365C3.57424 13.1802 1.50005 11.2719 0.919281 8.78289C0.297024 6.12793 1.54154 3.34851 3.90612 1.97955C6.35366 0.569097 9.79682 1.10839 11.4147 3.51445C11.8295 4.09522 12.1199 4.80045 12.2444 5.50567C12.3688 6.08644 12.3273 6.7087 12.4103 7.28947C12.4933 7.82876 12.9496 8.53399 13.5718 8.16063C14.1111 7.82876 14.0696 7.12354 14.0282 6.58425C14.0696 6.87464 14.0282 6.41831 14.0282 6.58425Z" fill="white"/>
1020
- </svg>
1021
- {$_('processingButton')}
1022
- </button>
1023
- {/if}
1024
- {#if showRetryNotification}
1025
- <cashier-notifications
1026
- {clientstylingurl}
1027
- {clientstyling}
1028
- text="{$_('retryText')}"
1029
- button="{$_('retryButton')}"
1030
- >
1031
- </cashier-notifications>
1032
- {/if}
1033
- </form>
1034
- {/if}
1035
- {#if showRedirectNotification}
1036
- <div class="RedirectionNotification">
1037
- <img src="//static.everymatrix.com/mmstage/cashier/assets/redirect.png" alt="">
1038
- <span class="RedirectionTitle">{$_('redirectTitle')}</span>
1039
- <span class="RedirectionMessage">{$_('redirectMessage')}</span>
1040
- <div class="RedirectionClose" on:click={() => {showRedirectNotification = false}}>{$_('backToPayment')}</div>
1041
- </div>
1042
- {/if}
1043
- {#if showReceiptPage}
1044
- <div class="ReceiptPage">
1045
- <cashier-receipt-page
1046
- {lang}
1047
- {translationurl}
1048
- {local}
1049
- {endpoint}
1050
- {customerid}
1051
- {assetsurl}
1052
- {clientstylingurl}
1053
- {clientstyling}
1054
- showerrors="false"
1055
- showclosebutton="true"
1056
- showcontactbutton="true"
1057
- transactionid="{transactionId}"
1058
- session="{playersession}"
1059
- >
1060
- </cashier-receipt-page>
1061
- </div>
1062
- {/if}
1063
- </div>
1064
- {/if}
1065
- {#if errorResponseCode && !showErrorModal}
1066
- <cashier-error
1067
- {assetsurl}
1068
- {translationurl}
1069
- {clientstylingurl}
1070
- {clientstyling}
1071
- {lang}
1072
- hidebuttons="{`${!mobileView}`}"
1073
- errorcode={errorResponseCode}
1074
- >
1075
- <button slot="button" class="CashierErrorButton" on:click={backToMethodList}>{$_('backToMethodList')}</button>
1076
- </cashier-error>
1077
- {/if}
1078
- </div>
1079
-
1080
-
1081
- <style lang="scss">
1082
-
1083
- $input-height: 40px;
1084
-
1085
- @keyframes loading-spinner {
1086
- from {
1087
- transform: rotate(0deg)
1088
- }
1089
- to {
1090
- transform: rotate(360deg)
1091
- }
1092
- }
1093
- ::-webkit-scrollbar {
1094
- width: 4px;
1095
- }
1096
- ::-webkit-scrollbar-track {
1097
- background: transparent;
1098
- }
1099
- ::-webkit-scrollbar-thumb {
1100
- background: var(--mmw--color-grey-105, #E8E9EB);
1101
- }
1102
- ::-webkit-scrollbar-thumb:hover {
1103
- background: var(--mmw--color-grey-290, #666);
1104
- }
1105
-
1106
- input::-webkit-outer-spin-button,
1107
- input::-webkit-inner-spin-button {
1108
- -webkit-appearance: none;
1109
- margin: 0;
1110
- }
1111
-
1112
- input::-webkit-date-and-time-value {
1113
- visibility: hidden;
1114
- }
1115
-
1116
- input[type=number] {
1117
- -moz-appearance: textfield;
1118
- }
1119
- .CashierMethodDetails {
1120
- width: 100%;
1121
- height: 100%;
1122
- box-sizing: border-box;
1123
- container-name: method-details;
1124
- container-type: inline-size;
1125
- padding: 1px;
1126
- min-height: 200px;
1127
- }
1128
- .ReceiptPage {
1129
- background-color: var(--emw--color-gray-transparency-100, rgb(255, 255, 255));
1130
- border-radius: var(--mmw--border-radius-medium-plus, 6px);
1131
- box-shadow: 0 2px 6px 0 var(--mmw--color-black-transparency-10, rgba(0, 0, 0, .1));
1132
- padding: 0 var(--emw--spacing-small, 12px);
1133
- margin-bottom: var(--emw--spacing-small-minus, 10px);
1134
- }
1135
- .MethodsDetails {
1136
- position: relative;
1137
- display: flex;
1138
- flex-direction: column;
1139
- height: 100%;
1140
- gap: var(--mmw--spacing-2x-small-plus, 5px);
1141
- &:has(.RedirectionNotification) form {
1142
- visibility: hidden;
1143
- }
1144
- &.DisabledPage:after {
1145
- content: '';
1146
- position: absolute;
1147
- height: 100%;
1148
- width: 100%;
1149
- z-index: 1;
1150
- top: 0;
1151
- left: 0;
1152
- background-color: var(--emw--color-background, rgba(255, 255, 255, 0.5));
1153
- }
1154
- }
1155
- .FormLogo {
1156
- align-items: center;
1157
- display: flex;
1158
- height: 50px;
1159
- border-bottom: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1160
- }
1161
-
1162
- .SelectedLogoDescription {
1163
- color: var(--mmw--color-grey-10, #111);
1164
- font-size: var(--emw--font-size-small, 14px);
1165
- margin: var(--mmw--spacing-x-small-minus, 7px) var(--mmw--spacing-2x-small-plus, 5px) var(--mmw--spacing-x-small-minus, 7px) var(--mmw--spacing-x-small-minus, 7px);
1166
- word-break: break-word;
1167
- }
1168
- .SelectedLogoWrapper {
1169
- width: 56px;
1170
- height: 32px;
1171
- flex-shrink: 0;
1172
- background: var(--emw--color-background, #fff);
1173
- border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1174
- border-radius: var(--mmw--border-radius-medium-plus, 6px);
1175
-
1176
- img {
1177
- max-height: 32px;
1178
- max-width: 56px;
1179
- }
1180
- }
1181
-
1182
- .ChangePaymeth {
1183
- margin-left: auto;
1184
- cursor: pointer;
1185
- color: var(--mmw--color-grey-10, #111);
1186
- font-size: var(--emw--font-size-small, 14px);
1187
- text-decoration-line: underline;
1188
- }
1189
-
1190
- .SelectedMethodDescription {
1191
- color: var(--mmw--color-grey-290, #666);
1192
- font-size: var(--emw--font-size-x-small, 12px);
1193
- margin: var(--emw--spacing-small-minus, 10px) 0 var(--mmw--spacing-2x-small-plus, 5px);
1194
- line-height: var(--emw--font-size-x-small, 12px);
1195
- white-space: pre-line;
1196
- }
1197
- .RedirectionNotification {
1198
- height: 100%;
1199
- width: 100%;
1200
- position: absolute;
1201
- display: flex;
1202
- flex-direction: column;
1203
- align-items: center;
1204
- justify-content: center;
1205
- gap: var(--emw--spacing-large, 20px);
1206
- }
1207
-
1208
- .RedirectionClose {
1209
- display: flex;
1210
- width: 234px;
1211
- height: 36px;
1212
- flex-direction: column;
1213
- justify-content: center;
1214
- flex-shrink: 0;
1215
- color: var(--emw--color-white, #FFF);
1216
- cursor: pointer;
1217
- text-align: center;
1218
- font-size: var(--emw--font-size-x-small, 12px);
1219
- font-style: normal;
1220
- font-weight: var(--emw--font-weight-semibold, 500);
1221
- line-height: normal;
1222
- text-transform: uppercase;
1223
- border-radius: var(--emw--border-radius-medium, 4px);
1224
- background: var(--emw--color-primary, #7EC51E);
1225
- }
1226
-
1227
- .RedirectionTitle {
1228
- color: var(--mmw--color-grey-10, #111);
1229
- font-size: var(--emw--font-size-x-small, 12px);
1230
- font-style: normal;
1231
- text-transform: none;
1232
- font-weight: var(--mmw--font-weight-semibold-plus, 600);
1233
- }
1234
- .RedirectionMessage {
1235
- color: var(--mmw--color-grey-290, #666);
1236
- font-size: var(--emw--font-size-x-small, 12px);
1237
- font-style: normal;
1238
- text-transform: none;
1239
- }
1240
- .FieldWrapper, label{
1241
- display: flex;
1242
- flex-direction: column ;
1243
- }
1244
- .FieldWrapper {
1245
- background-color: var(--emw--color-gray-transparency-100, rgba(255, 255, 255, 1));
1246
- border-radius: var(--mmw--border-radius-medium-plus, 6px);
1247
- box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
1248
- padding: 0 var(--emw--spacing-medium, 15px) var(--emw--spacing-medium, 15px);
1249
- margin-bottom: var(--emw--spacing-small-minus, 10px);
1250
- &:has(.QRCode, .Label) {
1251
- box-shadow: none;
1252
- background: transparent;
1253
- }
1254
- &.Hidden {
1255
- height: 0;
1256
- visibility: hidden;
1257
- margin: 0;
1258
- padding: 0;
1259
- }
1260
- &.Invalid:has(.Checkbox) {
1261
- border: 1px solid var(--emw--color-error, #FE0101);
1262
- }
1263
- }
1264
- .Alert {
1265
- display: none;
1266
- }
1267
- .Invalid {
1268
- input, .Selected {
1269
- border-color: var(--emw--color-error, #FE0101);
1270
- }
1271
- .Alert {
1272
- display: inline-block;
1273
- }
1274
- .AmountLimits {
1275
- display: none;
1276
- }
1277
- }
1278
- .Alert {
1279
- color: var(--emw--color-error, #FE0101);
1280
- font-size: var(--emw--font-size-x-small, 12px);
1281
- margin: var(--mmw--spacing-2x-small-plus, 5px) 0 0 var(--emw--spacing-3x-small, 2px);
1282
- line-height: var(--emw--font-size-x-small, 12px);
1283
- }
1284
- .AmountLimits {
1285
- color: var(--mmw--color-grey-290, #666);
1286
- font-size: var(--emw--font-size-x-small, 12px);
1287
- margin: var(--mmw--spacing-2x-small-plus, 5px) 0 0 var(--emw--spacing-3x-small, 2px);
1288
- line-height: var(--emw--font-size-x-small, 12px);
1289
- }
1290
- input, .Selected {
1291
- border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1292
- border-radius: var(--emw--border-radius-medium, 4px);
1293
- height: $input-height;
1294
- line-height: var(--emw--size-small, 14px);
1295
- color: var(--mmw--color-grey-10, #111);
1296
- padding: 0 var(--emw--spacing-medium, 15px);
1297
- font-style: inherit;
1298
- font-family: inherit;
1299
- &:focus {
1300
- outline: none;
1301
- }
1302
- }
1303
-
1304
- label {
1305
- color: var(--mmw--color-grey-10, #111);
1306
- font-size: var(--emw--size-small, 14px);
1307
- margin-top: var(--mmw--spacing-x-small-minus, 7px);
1308
- line-height: 27px;
1309
- span.Required:before {
1310
- content: '*';
1311
- display: inline-block;
1312
- margin-right: var(--emw--spacing-3x-small, 2px);
1313
- }
1314
- }
1315
- .Description {
1316
- color: var(--mmw--color-grey-290, #666);
1317
- font-size: var(--emw--font-size-x-small, 12px);
1318
- margin: 0 0 var(--mmw--spacing-2x-small-plus, 5px) var(--emw--spacing-3x-small, 2px);
1319
- line-height: var(--emw--font-size-x-small, 12px);
1320
- }
1321
- .PrimaryButton {
1322
- color: var(--emw--color-white, #FFF);
1323
- text-align: center;
1324
- font-size: var(--emw--font-size-x-small, 12px);
1325
- font-style: normal;
1326
- font-weight: var(--emw--font-weight-normal, 400);
1327
- font-family: inherit;
1328
- height: 46px;
1329
- border-radius: 50px;
1330
- line-height: normal;
1331
- border: none;
1332
- background: var(--emw--color-primary, #7EC51E);
1333
- width: 100%;
1334
- margin: var(--emw--spacing-small, 12px) 0;
1335
- cursor: pointer;
1336
- display: flex;
1337
- align-items: center;
1338
- justify-content: center;
1339
- gap: var(--mmw--spacing-2x-small-plus, 5px);
1340
- &:has(.ButtonSpinner),
1341
- &:has(.ButtonSpinner):hover,
1342
- &:active {
1343
- background: var(--mmw--color-main-button-active, #5C950F);
1344
- }
1345
- .ButtonAmount {
1346
- font-weight: var(--mmw--font-weight-semibold-plus, 600);
1347
- }
1348
- .ButtonSpinner {
1349
- animation: loading-spinner 1s linear infinite;
1350
- }
1351
- &[disabled] {
1352
- background: var(--mmw--color-disabled, #99999980);
1353
- cursor: auto;
1354
- pointer-events: none;
1355
- }
1356
- &:hover {
1357
- background: var(--mmw--color-main-button-hover, #71B11B);
1358
- }
1359
- }
1360
- .CashierErrorButton {
1361
- width: 100%;
1362
- height: 36px;
1363
- color: var(--emw--color-white, #FFF);
1364
- text-align: center;
1365
- cursor: pointer;
1366
- font-size: var(--emw--font-size-x-small, 12px);
1367
- font-style: normal;
1368
- font-weight: var(--emw--font-weight-semibold, 500);
1369
- font-family: inherit;
1370
- line-height: 36px;
1371
- border: none;
1372
- border-radius: var(--emw--border-radius-medium, 4px);
1373
- background: var(--emw--color-primary, #7EC51E);
1374
- &:hover {
1375
- background: var(--mmw--color-main-button-hover, #71B11B);
1376
- }
1377
- &:active {
1378
- background: var(--mmw--color-main-button-active, #5C950F);
1379
- }
1380
- }
1381
- .QRCode {
1382
- width: 250px;
1383
- margin: auto;
1384
- }
1385
- .Checkbox {
1386
- display: flex;
1387
- position: relative;
1388
- margin-top: var(--emw--spacing-small, 12px);
1389
-
1390
- .Description {
1391
- margin: 0 0 0 var(--emw--spacing-large, 20px);
1392
- cursor: pointer;
1393
- line-height: var( --emw--font-size-medium, 16px);
1394
- }
1395
-
1396
- .Checkmark {
1397
- position: absolute;
1398
- top: 2px;
1399
- left: 0;
1400
- height: 12px;
1401
- width: 12px;
1402
- border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1403
- border-radius: var(--emw--border-radius-medium, 4px);
1404
- background-color: var(--emw--color-white, #FFF);
1405
- cursor: pointer;
1406
-
1407
- &:after {
1408
- content: "";
1409
- position: absolute;
1410
- display: none;
1411
- }
1412
-
1413
- &:after {
1414
- left: 4px;
1415
- top: 0;
1416
- width: 2px;
1417
- height: 8px;
1418
- border: solid var(--emw--color-white, #FFF);
1419
- border-width: 0 2px 2px 0;
1420
- -webkit-transform: rotate(45deg);
1421
- -ms-transform: rotate(45deg);
1422
- transform: rotate(45deg);
1423
- }
1424
- }
1425
- input {
1426
- position: absolute;
1427
- opacity: 0;
1428
- cursor: pointer;
1429
- height: 0;
1430
- width: 0;
1431
-
1432
- &:checked ~ .Checkmark {
1433
- background-color: var(--emw--color-primary, #7EC51E);
1434
- border-color: var(--emw--color-primary, #7EC51E);
1435
- }
1436
-
1437
- &:checked ~ .Checkmark:after {
1438
- display: block;
1439
- }
1440
- }
1441
- }
1442
- .DateInput {
1443
- position: relative;
1444
- .MobileDateInput {
1445
- display: none;
1446
- }
1447
- &:has(.flatpickr-mobile) {
1448
- .DateTimePicker {
1449
- -webkit-appearance: none;
1450
- -moz-appearance: none;
1451
- background: none;
1452
- width: -webkit-fill-available;
1453
- font-size: 0;
1454
- width: -moz-available;
1455
- }
1456
- .MobileDateInput {
1457
- display: block;
1458
- position: absolute;
1459
- top: 50%;
1460
- transform: translateY(-50%);
1461
- left: 15px;
1462
- }
1463
- }
1464
- }
1465
-
1466
- .DateTimePicker {
1467
- width: -webkit-fill-available;
1468
- width: -moz-available;
1469
- }
1470
- .CustomSelect {
1471
- width: 100%;
1472
- position: relative;
1473
- }
1474
- .Selected {
1475
- display: flex;
1476
- align-items: center;
1477
- cursor: pointer;
1478
- .SelectedValue {
1479
- max-width: 95%;
1480
- }
1481
- &:after {
1482
- position: absolute;
1483
- content: "";
1484
- top: 19px;
1485
- right: 10px;
1486
- width: 0;
1487
- height: 0;
1488
- border: 6px solid transparent;
1489
- border-color: var(--mmw--color-border, rgb(168 169 170)) transparent transparent transparent;
1490
- }
1491
- }
1492
- .OptionList {
1493
- display: none;
1494
- position: absolute;
1495
- left: 0;
1496
- right: 0;
1497
- z-index: 3;
1498
- background-color: var(--emw--color-white, #fff);
1499
- border: 1px solid var(--mmw--color-grey-105, #E8E9EB);
1500
- border-radius: var(--emw--border-radius-medium, 4px);
1501
- margin-top: var(--mmw--spacing-2x-small-plus, 5px);
1502
- overflow: auto;
1503
- box-shadow: 0 2px 6px 0 rgba(0, 0, 0, 0.1);
1504
- &.Top {
1505
- transform: translate(0, calc(-1 * (100% + $input-height + 10px)));
1506
- }
1507
- div {
1508
- padding: var(--emw--spacing-x-small, 8px) var(--emw--spacing-medium, 16px);
1509
- cursor: pointer;
1510
- user-select: none;
1511
- line-height: calc(var(--emw--size-small, 14px) + 3px);
1512
- font-size: var(--emw--size-small, 14px);
1513
- &:hover {
1514
- background-color: var(--emw--color-gray-50, #F9F9F9);
1515
- }
1516
- }
1517
- &.Opened {
1518
- display: block;
1519
- }
1520
- }
1521
- @container method-details (width < 450px) {
1522
- .FormLogo .SelectedLogoDescription {
1523
- font-size: var(--emw--font-size-x-small, 12px);
1524
- display: -webkit-box;
1525
- -webkit-line-clamp: 2;
1526
- -webkit-box-orient: vertical;
1527
- overflow: hidden;
1528
- text-overflow: ellipsis;
1529
- }
1530
-
1531
- label, input, .Description, .FormLogo .ChangePaymeth, .OptionList div {
1532
- font-size: var(--emw--font-size-x-small, 12px);
1533
- }
1534
- .SelectedMethodDescription, .AmountLimits {
1535
- font-size: var(--emw--font-size-2x-small, 10px);
1536
- }
1537
-
1538
- }
1539
- </style>