@motopays/pay-form 2.3.1-rc.2 → 2.4.0-rc.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.
Files changed (4) hide show
  1. package/CHANGELOG.md +300 -272
  2. package/README.md +640 -640
  3. package/index.js +1 -1
  4. package/package.json +24 -24
package/README.md CHANGED
@@ -1,641 +1,641 @@
1
- # @motopays/pay-form
2
-
3
- **This product was developed using Angular and tested on Angular. Integration with other frameworks may cause potential issues. If any problems arise, please contact support to find a compatible solution for your framework.**
4
-
5
- ## Installation
6
-
7
- ```
8
- npm i @motopays/pay-form
9
- #or
10
- yarn add @motopays/pay-form
11
- ```
12
-
13
- ## Usage
14
-
15
- ### Html + JS
16
- ```html
17
- <head>
18
- ...
19
- <link rel="stylesheet" href="motopays/pay-form/styles.css" />
20
- ...
21
- </head>
22
- <body>
23
- ...
24
- <div id="moto-payment-form"></div>
25
- ...
26
- </body>
27
- <script src="motopays/pay-form/index.js" type="text/javascript"></script>
28
- <script type="text/javascript">
29
- async function createInvoice(request) {
30
- //create invoice
31
- }
32
-
33
- async function makePayment(request) {
34
- //make payment
35
- }
36
-
37
- const targetElement = document.getElementById("moto-payment-form");
38
- const paymentFormElement = document.createElement("moto-payment-form");
39
- paymentFormElement.id = "moto-payment-form";
40
-
41
- paymentFormElement.payment = {...};
42
- paymentFormElement.settings = {...};
43
- paymentFormElement.createInvoice = createInvoice;
44
- paymentFormElement.makePayment = makePayment;
45
-
46
- paymentFormElement.addEventListener("close", (event) => {
47
- console.log(event);
48
- });
49
- paymentFormElement.addEventListener("analyticsTracked", (event) => {
50
- console.log(event);
51
- });
52
- paymentFormElement.addEventListener("paid", (event) => {
53
- console.log(event);
54
- });
55
- paymentFormElement.addEventListener("error", (event) => {
56
- console.log(event);
57
- });
58
-
59
- targetElement.parentNode.replaceChild(formElement, targetElement);
60
- </script>
61
- ```
62
-
63
- ### React
64
- ```typescript
65
- import './App.css';
66
- import '@motopays/pay-form/index.js';
67
- import { IPaymentSettings, ISettings } from '@motopays/pay-form/index.js';
68
- import '@motopays/pay-form/styles.css';
69
- import { useEffect, useRef } from 'react';
70
-
71
- interface MotoPaymentFormProps extends React.HTMLAttributes<HTMLElement> {
72
- payment: string;
73
- settings: string;
74
- }
75
-
76
- declare global {
77
- namespace JSX {
78
- interface IntrinsicElements {
79
- 'moto-payment-form': React.DetailedHTMLProps<
80
- MotoPaymentFormProps,
81
- HTMLElement
82
- >;
83
- }
84
- }
85
- }
86
-
87
- const handleClose = () => console.log('close');
88
- const handleAnalyticsTracked = (e: any) => console.log(e);
89
- const handleError = (e: any) => console.log(e);
90
- const handlePaid = (e: any) => console.log(e);
91
-
92
- function App() {
93
- const motoPaymentFormRef = useRef<HTMLElement>(null);
94
-
95
- useEffect(() => {
96
- const motoPaymentFormElement = motoPaymentFormRef.current;
97
-
98
- if (motoPaymentFormElement) {
99
- motoPaymentFormElement.addEventListener('close', handleClose);
100
- motoPaymentFormElement.addEventListener('analyticsTracked', handleAnalyticsTracked);
101
- motoPaymentFormElement.addEventListener('paid', handlePaid);
102
- motoPaymentFormElement.addEventListener('error', handleError);
103
-
104
- return () => {
105
- motoPaymentFormElement.removeEventListener('close', handleClose);
106
- motoPaymentFormElement.removeEventListener('analyticsTracked', handleAnalyticsTracked);
107
- motoPaymentFormElement.removeEventListener('paid', handlePaid);
108
- motoPaymentFormElement.removeEventListener('error', handleError);
109
- };
110
- }
111
- }, []);
112
-
113
- const payment: IPaymentSettings = {...};
114
- const settings: ISettings = {...};
115
- const paymentJSON: string = JSON.stringify(payment);
116
- const settingsJSON: string = JSON.stringify(settings);
117
-
118
- return (
119
- <div className="App">
120
- <moto-payment-form ref={motoPaymentFormRef} payment={paymentJSON} settings={settingsJSON}></moto-payment-form>
121
- </div>
122
- );
123
- }
124
-
125
- export default App;
126
-
127
- ```
128
-
129
- ### Angular
130
- ```typescript
131
- import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
132
- import '@motopays/pay-form/index.js';
133
- import '@motopays/pay-form/styles.css';
134
- import { IPaymentSettings, ISettings } from '@motopays/pay-form/index.js';
135
-
136
- @Component({
137
- selector: 'app-root',
138
- standalone: true,
139
- template: `
140
- <moto-payment-form
141
- [payment]="payment"
142
- [settings]="settings"
143
- [createInvoice]="createInvoice"
144
- [makePayment]="makePayment"
145
- (close)="onClose()"
146
- (analyticsTracked)="onAnalyticsTracked($event)"
147
- (error)="onError($event)"
148
- (paid)="onPaid($event)">
149
- </moto-payment-form>
150
- `,
151
- styleUrl: './app.component.scss',
152
- schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
153
- })
154
- export class AppComponent {
155
- protected payment: IPaymentSettings = {...};
156
- protected settings: ISettings = {...};
157
-
158
- constructor() {
159
- this.createInvoice = this.createInvoice.bind(this);
160
- this.makePayment = this.makePayment.bind(this);
161
- }
162
-
163
- protected createInvoice(request: IPaymentRequest): Promise<IPaymentRequest | IInvoiceRequest> {
164
- //create invoice
165
- }
166
-
167
- protected makePayment(request: IPaymentRequest): Promise<IPaymentResponse> {
168
- //make payment
169
- }
170
-
171
- protected onClose(): void {
172
- console.log('close');
173
- }
174
-
175
- protected onAnalyticsTracked(e: any): void {
176
- console.log(e);
177
- }
178
-
179
- protected onPaid(e: any): void {
180
- console.log(e);
181
- }
182
-
183
- protected onError(e: any): void {
184
- console.log(e);
185
- }
186
- }
187
- ```
188
-
189
- ### Payment interface
190
-
191
- | Field | Type | Description |
192
- | ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
193
- | userId **\*required** | string | External end-user Id generated on the merchant side (not Motopays) |
194
- | paymentId **\*required** | string | External unique payment Id generated on the merchant side (not Motopays) |
195
- | amount **\*required** | number | Payment amount |
196
- | currency **\*required** | string | Payment currency in ISO_4217 format. For example: gbp, eur, usd |
197
- | merchantId **\*required** | string | Merchant's identifier, issued by Motopays. |
198
- | email **\*required** | string | End-customer e-mail. |
199
- | userAuthToken | string | End-user authorization token for accessing cards that have previously been used, as well as for accessing Apple Pay |
200
- | amountType | TAmountType | Type of amount can be only one of the following values: { 'gross-without-gst', 'net', 'gross' } |
201
- | tax | number | Payment tax |
202
- | orderType | TOrderType | Type of order can be only one of the following values: { 'regular', 'free-trial', 'gems' } |
203
- | initiator | TPaymentInitiator | Identifies who of 2 types initiated the payment. Currently accepted: {'customer', 'merchant'} |
204
- | webhookUrl | string | URL where the Motopays will send hooks about the payment status changes |
205
- | returnUrl | string | The URL to which the user will be redirected after completing some types of payment, such as PayPal |
206
- | description | string | Short order description for the customer |
207
- | details | ISimple<any> | Additional information about payment |
208
- | phoneNumber | string | End-customer phone number (can be changed if a customer fill the number by themselves) |
209
- | ipAddress | string | End-customer ip address |
210
- | billingAddress | BillingAddress | The address linked to a customer bank account |
211
- | billingAddress.addressLine | string | Street, building apartment and etc in one line |
212
- | billingAddress.city | string | City of a customer bank account |
213
- | billingAddress.state | string | State of a customer bank account |
214
- | billingAddress.country | string | Country of a customer bank account (ISO 3166-1 alpha-2 country code). Example: US |
215
- | billingAddress.zip | string | Zip of a customer bank account |
216
- | signature | string | The signature of the payment. For details contact technical support |
217
-
218
- ### Settings interface
219
-
220
- | Field | Type | Description |
221
- |-----------------------------|---------|-----------------------------------------------------------------------------|
222
- | urls **\*required** | IServicesUrls | The necessary services urls |
223
- | urls.processing **\*required** | string | The processing service URL |
224
- | urls.billingProfiles **\*required** | string | The billing profiles service URL |
225
- | isSignatureRequired | boolean | Whether to show an error and deny access to the payment form if the signature field in the payment model is not set |
226
- | isCloseButtonVisible | boolean | Whether to show a window close button in the top right corner of the screen |
227
- | isHeaderVisible | boolean | Whether to show a header in the top of the screen |
228
- | isTaxVisible | boolean | Whether to show a tax description (taxDescription field in the ILanguage model) |
229
- | closePaymentRedirect | boolean | Whether to close a window that was open on 3ds or apm pages after a redirect to returnUrl |
230
- | isProblemTipsListVisible | boolean | Whether to show tips on the payment result page when the payment is rejected, if tips exist for the error status code that occurred |
231
- | languageSettings | ILanguageSettings | The language settings
232
- | languageSettings.code | TLanguageCode | The code of language. Currently accepted: { 'en-US', 'es-ES', 'fr-FR' }. It's also possible to add another code by adding custom language to languageSettings.languages
233
- | languageSettings.languages | Partial<Record<TLanguageCode, ILanguage>> | Languages by codes
234
- | components | TComponentType[] | Components that will be on the form, as well as their order, which depends on the position of the components in the array. Currently accepted: {'available-card-brands', 'card-list', 'requisites', 'phone-number', 'charge-terms', 'pay-button', 'apm-list', 'user-preferences', 'merchant-info', 'protected-by', 'no-methods'}
235
- | resultComponentsStructure | IResultComponentsStructure | Components that will be on the result page of the form, as well as their order, which depends on the position of the components in the array
236
- | resultComponentsStructure<br>.aboveResult | TComponentType[] | Components that will be on the result page of the form above the result, as well as their order, which depends on the position of the components in the array
237
- | resultComponentsStructure<br>.belowResult | TComponentType[] | Components that will be on the result page of the form below the result, as well as their order, which depends on the position of the components in the array
238
- | merchantInfo | IMerchantInfoSettings | The information displays in merchant info section |
239
- | merchantInfo.text | Partial<Record<TLanguageCode, string>> | The information about a merchant multilingual support and linkify. Read more about linkify in the Linkify section |
240
- | merchantInfo.links | ILink[] | The array of merchant links. For example, Policy and Terms |
241
- | chargeTerms | IChargeTermsSettings | The charge terms section |
242
- | chargeTerms.checkboxes | Partial<Record<TLanguageCode, string>>[] | The user must select all the checkboxes to proceed with the payment. Without selecting these checkboxes, the payment cannot be made. Multilingual support and linkify. Read more about linkify in the Linkify section |
243
- | chargeTerms.text | Partial<Record<TLanguageCode, string>> | The text of charge terms. For example, description of terms and policy. Multilingual support and linkify. Read more about linkify in the Linkify section |
244
- | userPreferences | IUserPreferencesSettings | The user preferences section |
245
- | userPreferences.text | Partial<Record<TLanguageCode, string>> | The text of user preferences. For example, description of autorefill plan. Multilingual support and linkify. Read more about linkify in the Linkify section |
246
- | userPreferences.checkboxes | IUserPreferenceCheckbox[] | The text of user preferences. For example, description of autorefill plan. Multilingual support and linkify. Read more about linkify in the Linkify section |
247
- | availableCardBrands | string[] or CreditCardTypeCardBrandId[] | The сard brands for which icons will be displayed on the form as card payment methods. Currently accepted: {american-express, discover, jcb, maestro, mastercard, unionpay, visa} |
248
- | requiredFieldsBehavior | IRequiredFieldsBehavior | Configuration of the display of required fields for the user to manage the user's focus on them |
249
- | requiredFieldsBehavior<br>.showStars | boolean | Show the stars on labels of required fields |
250
- | requiredFieldsBehavior<br>.buttonStateUntilFilled | TButtonStateUntilFilled | If 'disabled', the payment buttons remain disabled until the user fills in all the required fields. If 'enabled', then when one of the buttons is pressed (the buttons are enabled), the required fields will be marked as invalid (red color) for the user. If 'hidden-enabled', then when one of the buttons is pressed (the buttons are enabled but have styles as disabled), the required fields will be marked as invalid (red color) for the user. Current accepted: { enabled, disabled, hidden-enabled } |
251
- | requiredFieldsBehavior<br>.markAsInvalidUntilCorrect | boolean | If true, then all unfilled or incorrectly filled required fields will initially appear as invalid (red color) to the user until they are filled and correct. If the value is false, the required fields will only be shown as invalid in the event that the user presses the payment button when the buttons are enabled |
252
- | events | IEvents | The events configuration |
253
- | events.analytics | { optional: boolean; required: boolean; } | The analytics events configuration. Optional is responsible for 'focus' events. Required is responsible for 'click' events. Read more about analytics events in the Analytics section |
254
- | events.error | boolean | The error events configuration. If true, the error events will be emitted; otherwise, they will not |
255
- | apmsCollapse | boolean | The apms collapse configuration. If true, the 'or use alternative methods' text will be clickable and will control whether the apms are shown or not. By default, if true, the apms will be collapsed. |
256
- | paymentFlow | IPaymentFlowSettings | The payment flow configuration |
257
- | paymentFlow.tokenizeCard | boolean | If true, than for not 'default' paymentFlow.type card requisites will be tokenized (only for 'invoice-overridden' and 'payment-overridden' paymentFlow.type) |
258
- | paymentFlow.type | TPaymentFlow | If 'invoice-overridden' and createInvoice callback provided to the payment form, the createInvoice callback will be called with the invoice generated by the payment form. After receiving the invoice from the createInvoice callback, the payment process will proceed according to the default scenario. If 'payment-overridden' and makePayment callback provided to the payment form, the entire payment process will be handled through the makePayment callback with the invoice generated by the payment form |
259
-
260
- ### Example
261
-
262
- #### Payment
263
-
264
- ```typescript
265
- const payment: IPaymentSettings = {
266
- amount: 10,
267
- currency: 'usd',
268
- email: 'random@gmail.com',
269
- merchantId: '22504',
270
- paymentId: 'IS949832NF29',
271
- userId: 'OIDSF0202JFS',
272
- amountType: 'net',
273
- tax: 3,
274
- orderType: 'gems',
275
- userAuthToken: 'testestest.testestest.testestest',
276
- billingAddress: {
277
- addressLine: "main street 1",
278
- city: "Paris",
279
- country: "US",
280
- state: "NY",
281
- zip: "220125"
282
- },
283
- description: 'my description',
284
- initiator: 'customer',
285
- details: {
286
- myField: 21
287
- },
288
- ipAddress: '12.12.12.12',
289
- phoneNumber: '+995234234234',
290
- returnUrl: 'https://my.return.com',
291
- signature: '0saidmc0smac',
292
- webhookUrl: 'https://my.webhook.com'
293
- }
294
- ```
295
-
296
- #### Settings
297
-
298
- ```typescript
299
- const settings: ISettings = {
300
- urls: {
301
- processing: 'https://my.processing.com',
302
- billingProfiles: 'https://my.billingprofiles.com',
303
- },
304
- apmsCollapse: false,
305
- availableCardBrands: ['visa', 'american-express', 'mastercard', 'diners-club', 'jcb'],
306
- chargeTerms: {
307
- text: {
308
- 'en-US': 'My charge terms { href: "https://google.com", text: "Google" } the ending of text',
309
- 'es-ES': 'My charge terms { href: "https://google.com", text: "Google es-ES" } the ending of text es-ES',
310
- 'custom': 'custom charge terms text'
311
- },
312
- checkboxes: [
313
- {
314
- 'en-US': 'Charge terms { href: "https://google.com", text: "Google" } checkbox',
315
- 'es-ES': 'Charge terms { href: "https://google.com", text: "Google es-ES" } checkbox es-ES',
316
- 'custom': 'custom'
317
- }
318
- ]
319
- },
320
- closePaymentRedirect: true,
321
- components: [
322
- 'available-card-brands',
323
- 'no-methods',
324
- 'card-list',
325
- 'requisites',
326
- //'phone-number',
327
- 'charge-terms',
328
- 'pay-button',
329
- 'apm-list',
330
- 'user-preferences',
331
- 'merchant-info',
332
- 'protected-by'
333
- ],
334
- events: {
335
- analytics: {
336
- optional: true,
337
- required: true,
338
- },
339
- error: true
340
- },
341
- isCloseButtonVisible: true,
342
- isHeaderVisible: true,
343
- isProblemTipsListVisible: true,
344
- isSignatureRequired: false,
345
- isTaxVisible: true,
346
- languageSettings: {
347
- code: 'custom',
348
- languages: {
349
- 'custom': {
350
- apms: {
351
- or: 'custom',
352
- orUseAlternative: 'custom'
353
- },
354
- availableCardBrandsHeader: 'custom',
355
- close: 'custom',
356
- errors: {
357
- invalidCardExpiration: 'custom',
358
- invalidCardHolder: 'custom',
359
- invalidCardNumber: 'custom',
360
- invalidCvv: 'custom',
361
- invalidPhoneNumber: 'custom',
362
- notCheckedCheckboxes: 'custom'
363
- },
364
- existingCards: {
365
- addNewCard: 'custom',
366
- manageCardsHeader: 'custom',
367
- removeCard: 'custom'
368
- },
369
- header: 'custom',
370
- noAvailablePaymentMethods: 'custom',
371
- notifications: {
372
- cardDeleted: {
373
- text: 'custom',
374
- title: 'custom'
375
- },
376
- error: {
377
- default: {
378
- text: 'custom',
379
- title: 'custom'
380
- }
381
- }
382
- },
383
- pay: 'custom',
384
- taxDescription: 'custom',
385
- paymentProcessing: 'custom',
386
- paymentResult: {
387
- success: 'custom',
388
- failure: {
389
- main: 'custom',
390
- paymentFailed: 'custom'
391
- }
392
- },
393
- phone: {
394
- header: 'custom',
395
- placeholder: 'custom'
396
- },
397
- requisites: {
398
- cardExpirationPlaceholder: 'custom',
399
- cardHolderHeader: 'custom',
400
- cardHolderPlaceholder: 'custom',
401
- cardNumberPlaceholder: 'custom',
402
- cvvHint: 'custom',
403
- paymentDetailsHeader: 'custom',
404
- cvvPlaceholder: {
405
- CID: 'custom',
406
- CVC: 'custom',
407
- CVE: 'custom',
408
- CVN: 'custom',
409
- CVP2: 'custom',
410
- CVV: 'custom'
411
- }
412
- },
413
- totalHeader: 'custom',
414
- transactionProtectedBy: 'custom'
415
- }
416
- }
417
- },
418
- merchantInfo: {
419
- text: {
420
- 'en-US': 'Merchant info { href: "https://google.com", text: "Google" } merchant info { href: "https://google.com", text: "Google" } Merchant info',
421
- 'es-ES': 'Merchant info { href: "https://google.com", text: "Google es-ES" } merchant info { href: "https://google.com", text: "Google es-ES" } Merchant info es-ES',
422
- 'custom': 'custom merchant info'
423
- },
424
- links: [
425
- {
426
- href: 'https://google.com',
427
- text: {
428
- 'en-US': 'google',
429
- 'es-ES': 'google (es-ES)',
430
- 'custom': 'custom link'
431
- }
432
- }
433
- ]
434
- },
435
- requiredFieldsBehavior: {
436
- buttonStateUntilFilled: 'enabled',
437
- markAsInvalidUntilCorrect: false,
438
- showStars: true
439
- },
440
- resultComponentsStructure: {
441
- aboveResult: [],
442
- belowResult: ['merchant-info', 'protected-by']
443
- },
444
- userPreferences: {
445
- text: {
446
- 'en-US': 'User preferences text { href: "https://google.com", text: "Google" } User preferences text',
447
- 'es-ES': 'User preferences text { href: "https://google.com", text: "Google es-ES" } User preferences text es-ES',
448
- 'custom': 'custom user preferences text'
449
- },
450
- checkboxes: [
451
- {
452
- name: 'user_preference_name',
453
- text: {
454
- 'en-US': 'User preference { href: "https://google.com", text: "Google" } checkbox',
455
- 'es-ES': 'User preference { href: "https://google.com", text: "Google es-ES" } checkbox es-ES',
456
- 'custom': 'custom user preferences checkbox'
457
- },
458
- defaultValue: false
459
- }
460
- ]
461
- },
462
- paymentFlow: {
463
- tokenizeCard: false,
464
- type: 'default'
465
- }
466
- };
467
- ```
468
-
469
- ### Output events
470
-
471
- | Event | Type | Description |
472
- | ----- | ---------------- | -------------------------------------------- |
473
- | close | void | triggered by clicking on the closing icon |
474
- | paid | IPaymentResponse | triggered after receiving a payment response |
475
- | error | any | triggered by error events |
476
- | analyticsTracked | TAnalyticsServiceAction | triggered by analytics events |
477
-
478
- ### Payment Result Structure
479
-
480
- ```javascript
481
- IPaymentResponse {
482
- action?: {
483
- name: string;
484
- data: IThreeDsData | IRedirectData | any;
485
- }
486
- ip: string;
487
- merchant: string;
488
- order: {
489
- invoiceId: string;
490
- details: string;
491
- }
492
- payment: {
493
- paymentId: string;
494
- state: TPaymentState; //on of strings: completed, rejected, needAction
495
- rebillAnchor: string;
496
- info: {
497
- completeProcessingTime?: Date;
498
- currency: string;
499
- paymentType: string;
500
- paymentSystem: string;
501
- paymentRequisites?: string;
502
- price: number
503
- }
504
- rejectionDetails?: {
505
- hardDecline: boolean;
506
- message?: string;
507
- problemSolvingTips: string[];
508
- rejectionCode: number;
509
- }
510
- }
511
- taxInfo: {
512
- abbreviation: string;
513
- price: number;
514
- priceNet: number;
515
- tax: number;
516
- }
517
- user: {
518
- id: string;
519
- }
520
- signature: string;
521
- }
522
-
523
- IThreeDsData {
524
- paReq: string;
525
- acsurl: string;
526
- termUrl: string;
527
- md: string;
528
- }
529
-
530
- IRedirectData {
531
- location: string;
532
- }
533
- ```
534
-
535
- ### Analytics
536
- For receiving analytics listen analyticsTracked events.
537
-
538
- 'init-start' - the form has started initialization. Payload: void.<br>
539
- 'loading-finish' - the form has finished initialization and loading. Payload: void.<br>
540
- 'card-number-field-focus' - the card number field has been focused. Payload: void.<br>
541
- 'expiration-date-field-focused' - the expiration date field has been focused. Payload: void.<br>
542
- 'cvv-field-focused' - the cvv field has been focused. Payload: void.<br>
543
- 'card-holder-field-focused' - the card holder field has been focused. Payload: void.<br>
544
- 'charge-term-checkbox-<number>-focus' - the charge term checkbox has been focused. Payload: IChargeTermsAnalytics.<br>
545
- 'charge-term-checkbox-<number>-check' - the charge term checkbox has been checked. Payload: IChargeTermsAnalytics.<br>
546
- 'charge-term-checkbox-<number>-uncheck' - the charge term checkbox has been unchecked. Payload: IChargeTermsAnalytics.<br>
547
- 'user-preference-checkbox-<number>-focus' - the user preference checkbox has been focused. Payload: IUserPreferencesAnalytics.<br>
548
- 'user-preference-checkbox-<number>-check' - the user preference checkbox has been checked. Payload: IUserPreferencesAnalytics.<br>
549
- 'user-preference-checkbox-<number>-uncheck' - the user preference checkbox has been unchecked. Payload: IUserPreferencesAnalytics.<br>
550
- 'pay-button-focus' - the 'Pay' button has been focused (payment by card). Payload: void.<br>
551
- 'pay-button-click' - the 'Pay' button has been clicked (payment by card). Payload: void.<br>
552
- '<apm>-button-focus' - the apm payment button has been focused. Payload: void.<br>
553
- '<apm>-button-click' - the apm payment button has been clicked. Payload: void.<br>
554
- 'add-card-button-focus' - the "Add New Card" button has been focused. Payload: void.<br>
555
- 'add-card-button-click' - the "Add New Card" button has been clicked. Payload: void.<br>
556
- 'card-options-button-click' - the card options button has been clicked (existing card menu visualized as 3 vertical dots). Payload: ICardAnalytics.<br>
557
- 'cards-toggle-button-click' - the cards toggle button has been clicked (show or collapse card list). Payload: ICardListAnalytics.<br>
558
- 'remove-card-button-click' - the card removing button has been clicked. Payload: ICardAnalytics.<br>
559
- 'select-card-button-click' - the card selecting button has been clicked. Payload: ICardAnalytics.<br>
560
- 'apms-show-button-click' - the apm collapse text has been clicked. Payload: ICardAnalytics.<br>
561
-
562
- Examples of dynamic event types (number inserting):
563
- &emsp;1. Example of the first checkbox: 'charge-term-checkbox-0-check'
564
- &emsp;2. Example of the second checkbox: 'charge-term-checkbox-1-check'
565
-
566
- Examples of dynamic event types (apm inserting):
567
- &emsp;1. 'coinbase-button-click'
568
- &emsp;2. 'moto-button-click'
569
-
570
- ```javascript
571
- type TAnalyticsServiceAction =
572
- | ServiceAction<'init-start'>
573
- | ServiceAction<'loading-finish'>
574
- | ServiceAction<'card-number-field-focus'>
575
- | ServiceAction<'expiration-date-field-focus'>
576
- | ServiceAction<'cvv-field-focus'>
577
- | ServiceAction<'card-holder-field-focus'>
578
- | ServiceAction<'number-field-focus'> //
579
- | ServiceAction<
580
- `charge-term-checkbox${`-${number}`}-focus`,
581
- IChargeTermsAnalytics
582
- >
583
- | ServiceAction<
584
- `charge-term-checkbox${`-${number}`}-check`,
585
- IChargeTermsAnalytics
586
- >
587
- | ServiceAction<
588
- `charge-term-checkbox${`-${number}`}-uncheck`,
589
- IChargeTermsAnalytics
590
- >
591
- | ServiceAction<
592
- `user-preference-checkbox${`-${number}`}-focus`,
593
- IUserPreferencesAnalytics
594
- >
595
- | ServiceAction<
596
- `user-preference-checkbox${`-${number}`}-check`,
597
- IUserPreferencesAnalytics
598
- >
599
- | ServiceAction<
600
- `user-preference-checkbox${`-${number}`}-uncheck`,
601
- IUserPreferencesAnalytics
602
- >
603
- | ServiceAction<'pay-button-focus'>
604
- | ServiceAction<'pay-button-click'>
605
- | ServiceAction<`${string}-button-focus`>
606
- | ServiceAction<`${string}-button-click`>
607
- | ServiceAction<'add-card-button-focus'>
608
- | ServiceAction<'add-card-button-click'>
609
- | ServiceAction<'card-options-button-click', ICardAnalytics>
610
- | ServiceAction<'cards-toggle-button-click', ICardListAnalytics>
611
- | ServiceAction<'remove-card-button-click', ICardAnalytics>
612
- | ServiceAction<'select-card-button-click', ICardAnalytics>
613
- | ServiceAction<'apms-show-button-click', ICardAnalytics>;
614
-
615
-
616
- //payload types
617
- interface ICardListAnalytics {
618
- toggle: boolean;
619
- }
620
-
621
- interface ICardAnalytics {
622
- last4Digits: string;
623
- }
624
-
625
- interface IChargeTermsAnalytics {
626
- text: string;
627
- }
628
-
629
- interface IUserPreferencesAnalytics {
630
- name: string;
631
- text: string;
632
- }
633
- ```
634
-
635
- ### Linkify
636
- Text elements, which are described in the documentation as linkify, can be transformed into text with links. The link object starts with the '{' character and ends with the '}' character. The href field specifies the URL to navigate to when clicked, and the text field specifies the text that will be displayed to the user as the link.
637
- Example: 'My text { href: "https://google.com", text: "Link1" } the ending of text. The continuation of the text { href: "https://google.com", text: "Link1" }.'
638
-
639
- ### Webpack 5 Issues
640
-
1
+ # @motopays/pay-form
2
+
3
+ **This product was developed using Angular and tested on Angular. Integration with other frameworks may cause potential issues. If any problems arise, please contact support to find a compatible solution for your framework.**
4
+
5
+ ## Installation
6
+
7
+ ```
8
+ npm i @motopays/pay-form
9
+ #or
10
+ yarn add @motopays/pay-form
11
+ ```
12
+
13
+ ## Usage
14
+
15
+ ### Html + JS
16
+ ```html
17
+ <head>
18
+ ...
19
+ <link rel="stylesheet" href="motopays/pay-form/styles.css" />
20
+ ...
21
+ </head>
22
+ <body>
23
+ ...
24
+ <div id="moto-payment-form"></div>
25
+ ...
26
+ </body>
27
+ <script src="motopays/pay-form/index.js" type="text/javascript"></script>
28
+ <script type="text/javascript">
29
+ async function createInvoice(request) {
30
+ //create invoice
31
+ }
32
+
33
+ async function makePayment(request) {
34
+ //make payment
35
+ }
36
+
37
+ const targetElement = document.getElementById("moto-payment-form");
38
+ const paymentFormElement = document.createElement("moto-payment-form");
39
+ paymentFormElement.id = "moto-payment-form";
40
+
41
+ paymentFormElement.payment = {...};
42
+ paymentFormElement.settings = {...};
43
+ paymentFormElement.createInvoice = createInvoice;
44
+ paymentFormElement.makePayment = makePayment;
45
+
46
+ paymentFormElement.addEventListener("close", (event) => {
47
+ console.log(event);
48
+ });
49
+ paymentFormElement.addEventListener("analyticsTracked", (event) => {
50
+ console.log(event);
51
+ });
52
+ paymentFormElement.addEventListener("paid", (event) => {
53
+ console.log(event);
54
+ });
55
+ paymentFormElement.addEventListener("error", (event) => {
56
+ console.log(event);
57
+ });
58
+
59
+ targetElement.parentNode.replaceChild(formElement, targetElement);
60
+ </script>
61
+ ```
62
+
63
+ ### React
64
+ ```typescript
65
+ import './App.css';
66
+ import '@motopays/pay-form/index.js';
67
+ import { IPaymentSettings, ISettings } from '@motopays/pay-form/index.js';
68
+ import '@motopays/pay-form/styles.css';
69
+ import { useEffect, useRef } from 'react';
70
+
71
+ interface MotoPaymentFormProps extends React.HTMLAttributes<HTMLElement> {
72
+ payment: string;
73
+ settings: string;
74
+ }
75
+
76
+ declare global {
77
+ namespace JSX {
78
+ interface IntrinsicElements {
79
+ 'moto-payment-form': React.DetailedHTMLProps<
80
+ MotoPaymentFormProps,
81
+ HTMLElement
82
+ >;
83
+ }
84
+ }
85
+ }
86
+
87
+ const handleClose = () => console.log('close');
88
+ const handleAnalyticsTracked = (e: any) => console.log(e);
89
+ const handleError = (e: any) => console.log(e);
90
+ const handlePaid = (e: any) => console.log(e);
91
+
92
+ function App() {
93
+ const motoPaymentFormRef = useRef<HTMLElement>(null);
94
+
95
+ useEffect(() => {
96
+ const motoPaymentFormElement = motoPaymentFormRef.current;
97
+
98
+ if (motoPaymentFormElement) {
99
+ motoPaymentFormElement.addEventListener('close', handleClose);
100
+ motoPaymentFormElement.addEventListener('analyticsTracked', handleAnalyticsTracked);
101
+ motoPaymentFormElement.addEventListener('paid', handlePaid);
102
+ motoPaymentFormElement.addEventListener('error', handleError);
103
+
104
+ return () => {
105
+ motoPaymentFormElement.removeEventListener('close', handleClose);
106
+ motoPaymentFormElement.removeEventListener('analyticsTracked', handleAnalyticsTracked);
107
+ motoPaymentFormElement.removeEventListener('paid', handlePaid);
108
+ motoPaymentFormElement.removeEventListener('error', handleError);
109
+ };
110
+ }
111
+ }, []);
112
+
113
+ const payment: IPaymentSettings = {...};
114
+ const settings: ISettings = {...};
115
+ const paymentJSON: string = JSON.stringify(payment);
116
+ const settingsJSON: string = JSON.stringify(settings);
117
+
118
+ return (
119
+ <div className="App">
120
+ <moto-payment-form ref={motoPaymentFormRef} payment={paymentJSON} settings={settingsJSON}></moto-payment-form>
121
+ </div>
122
+ );
123
+ }
124
+
125
+ export default App;
126
+
127
+ ```
128
+
129
+ ### Angular
130
+ ```typescript
131
+ import { CUSTOM_ELEMENTS_SCHEMA, Component } from '@angular/core';
132
+ import '@motopays/pay-form/index.js';
133
+ import '@motopays/pay-form/styles.css';
134
+ import { IPaymentSettings, ISettings } from '@motopays/pay-form/index.js';
135
+
136
+ @Component({
137
+ selector: 'app-root',
138
+ standalone: true,
139
+ template: `
140
+ <moto-payment-form
141
+ [payment]="payment"
142
+ [settings]="settings"
143
+ [createInvoice]="createInvoice"
144
+ [makePayment]="makePayment"
145
+ (close)="onClose()"
146
+ (analyticsTracked)="onAnalyticsTracked($event)"
147
+ (error)="onError($event)"
148
+ (paid)="onPaid($event)">
149
+ </moto-payment-form>
150
+ `,
151
+ styleUrl: './app.component.scss',
152
+ schemas: [ CUSTOM_ELEMENTS_SCHEMA ]
153
+ })
154
+ export class AppComponent {
155
+ protected payment: IPaymentSettings = {...};
156
+ protected settings: ISettings = {...};
157
+
158
+ constructor() {
159
+ this.createInvoice = this.createInvoice.bind(this);
160
+ this.makePayment = this.makePayment.bind(this);
161
+ }
162
+
163
+ protected createInvoice(request: IPaymentRequest): Promise<IPaymentRequest | IInvoiceRequest> {
164
+ //create invoice
165
+ }
166
+
167
+ protected makePayment(request: IPaymentRequest): Promise<IPaymentResponse> {
168
+ //make payment
169
+ }
170
+
171
+ protected onClose(): void {
172
+ console.log('close');
173
+ }
174
+
175
+ protected onAnalyticsTracked(e: any): void {
176
+ console.log(e);
177
+ }
178
+
179
+ protected onPaid(e: any): void {
180
+ console.log(e);
181
+ }
182
+
183
+ protected onError(e: any): void {
184
+ console.log(e);
185
+ }
186
+ }
187
+ ```
188
+
189
+ ### Payment interface
190
+
191
+ | Field | Type | Description |
192
+ | ------------------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
193
+ | userId **\*required** | string | External end-user Id generated on the merchant side (not Motopays) |
194
+ | paymentId **\*required** | string | External unique payment Id generated on the merchant side (not Motopays) |
195
+ | amount **\*required** | number | Payment amount |
196
+ | currency **\*required** | string | Payment currency in ISO_4217 format. For example: gbp, eur, usd |
197
+ | merchantId **\*required** | string | Merchant's identifier, issued by Motopays. |
198
+ | email **\*required** | string | End-customer e-mail. |
199
+ | userAuthToken | string | End-user authorization token for accessing cards that have previously been used, as well as for accessing Apple Pay |
200
+ | amountType | TAmountType | Type of amount can be only one of the following values: { 'gross-without-gst', 'net', 'gross' } |
201
+ | tax | number | Payment tax |
202
+ | orderType | TOrderType | Type of order can be only one of the following values: { 'regular', 'free-trial', 'gems' } |
203
+ | initiator | TPaymentInitiator | Identifies who of 2 types initiated the payment. Currently accepted: {'customer', 'merchant'} |
204
+ | webhookUrl | string | URL where the Motopays will send hooks about the payment status changes |
205
+ | returnUrl | string | The URL to which the user will be redirected after completing some types of payment, such as PayPal |
206
+ | description | string | Short order description for the customer |
207
+ | details | ISimple<any> | Additional information about payment |
208
+ | phoneNumber | string | End-customer phone number (can be changed if a customer fill the number by themselves) |
209
+ | ipAddress | string | End-customer ip address |
210
+ | billingAddress | BillingAddress | The address linked to a customer bank account |
211
+ | billingAddress.addressLine | string | Street, building apartment and etc in one line |
212
+ | billingAddress.city | string | City of a customer bank account |
213
+ | billingAddress.state | string | State of a customer bank account |
214
+ | billingAddress.country | string | Country of a customer bank account (ISO 3166-1 alpha-2 country code). Example: US |
215
+ | billingAddress.zip | string | Zip of a customer bank account |
216
+ | signature | string | The signature of the payment. For details contact technical support |
217
+
218
+ ### Settings interface
219
+
220
+ | Field | Type | Description |
221
+ |-----------------------------|---------|-----------------------------------------------------------------------------|
222
+ | urls **\*required** | IServicesUrls | The necessary services urls |
223
+ | urls.processing **\*required** | string | The processing service URL |
224
+ | urls.billingProfiles **\*required** | string | The billing profiles service URL |
225
+ | isSignatureRequired | boolean | Whether to show an error and deny access to the payment form if the signature field in the payment model is not set |
226
+ | isCloseButtonVisible | boolean | Whether to show a window close button in the top right corner of the screen |
227
+ | isHeaderVisible | boolean | Whether to show a header in the top of the screen |
228
+ | isTaxVisible | boolean | Whether to show a tax description (taxDescription field in the ILanguage model) |
229
+ | closePaymentRedirect | boolean | Whether to close a window that was open on 3ds or apm pages after a redirect to returnUrl |
230
+ | isProblemTipsListVisible | boolean | Whether to show tips on the payment result page when the payment is rejected, if tips exist for the error status code that occurred |
231
+ | languageSettings | ILanguageSettings | The language settings
232
+ | languageSettings.code | TLanguageCode | The code of language. Currently accepted: { 'en-US', 'es-ES', 'fr-FR' }. It's also possible to add another code by adding custom language to languageSettings.languages
233
+ | languageSettings.languages | Partial<Record<TLanguageCode, ILanguage>> | Languages by codes
234
+ | components | TComponentType[] | Components that will be on the form, as well as their order, which depends on the position of the components in the array. Currently accepted: {'available-card-brands', 'card-list', 'requisites', 'phone-number', 'charge-terms', 'pay-button', 'apm-list', 'user-preferences', 'merchant-info', 'protected-by', 'no-methods'}
235
+ | resultComponentsStructure | IResultComponentsStructure | Components that will be on the result page of the form, as well as their order, which depends on the position of the components in the array
236
+ | resultComponentsStructure<br>.aboveResult | TComponentType[] | Components that will be on the result page of the form above the result, as well as their order, which depends on the position of the components in the array
237
+ | resultComponentsStructure<br>.belowResult | TComponentType[] | Components that will be on the result page of the form below the result, as well as their order, which depends on the position of the components in the array
238
+ | merchantInfo | IMerchantInfoSettings | The information displays in merchant info section |
239
+ | merchantInfo.text | Partial<Record<TLanguageCode, string>> | The information about a merchant multilingual support and linkify. Read more about linkify in the Linkify section |
240
+ | merchantInfo.links | ILink[] | The array of merchant links. For example, Policy and Terms |
241
+ | chargeTerms | IChargeTermsSettings | The charge terms section |
242
+ | chargeTerms.checkboxes | Partial<Record<TLanguageCode, string>>[] | The user must select all the checkboxes to proceed with the payment. Without selecting these checkboxes, the payment cannot be made. Multilingual support and linkify. Read more about linkify in the Linkify section |
243
+ | chargeTerms.text | Partial<Record<TLanguageCode, string>> | The text of charge terms. For example, description of terms and policy. Multilingual support and linkify. Read more about linkify in the Linkify section |
244
+ | userPreferences | IUserPreferencesSettings | The user preferences section |
245
+ | userPreferences.text | Partial<Record<TLanguageCode, string>> | The text of user preferences. For example, description of autorefill plan. Multilingual support and linkify. Read more about linkify in the Linkify section |
246
+ | userPreferences.checkboxes | IUserPreferenceCheckbox[] | The text of user preferences. For example, description of autorefill plan. Multilingual support and linkify. Read more about linkify in the Linkify section |
247
+ | availableCardBrands | string[] or CreditCardTypeCardBrandId[] | The сard brands for which icons will be displayed on the form as card payment methods. Currently accepted: {american-express, discover, jcb, maestro, mastercard, unionpay, visa} |
248
+ | requiredFieldsBehavior | IRequiredFieldsBehavior | Configuration of the display of required fields for the user to manage the user's focus on them |
249
+ | requiredFieldsBehavior<br>.showStars | boolean | Show the stars on labels of required fields |
250
+ | requiredFieldsBehavior<br>.buttonStateUntilFilled | TButtonStateUntilFilled | If 'disabled', the payment buttons remain disabled until the user fills in all the required fields. If 'enabled', then when one of the buttons is pressed (the buttons are enabled), the required fields will be marked as invalid (red color) for the user. If 'hidden-enabled', then when one of the buttons is pressed (the buttons are enabled but have styles as disabled), the required fields will be marked as invalid (red color) for the user. Current accepted: { enabled, disabled, hidden-enabled } |
251
+ | requiredFieldsBehavior<br>.markAsInvalidUntilCorrect | boolean | If true, then all unfilled or incorrectly filled required fields will initially appear as invalid (red color) to the user until they are filled and correct. If the value is false, the required fields will only be shown as invalid in the event that the user presses the payment button when the buttons are enabled |
252
+ | events | IEvents | The events configuration |
253
+ | events.analytics | { optional: boolean; required: boolean; } | The analytics events configuration. Optional is responsible for 'focus' events. Required is responsible for 'click' events. Read more about analytics events in the Analytics section |
254
+ | events.error | boolean | The error events configuration. If true, the error events will be emitted; otherwise, they will not |
255
+ | apmsCollapse | boolean | The apms collapse configuration. If true, the 'or use alternative methods' text will be clickable and will control whether the apms are shown or not. By default, if true, the apms will be collapsed. |
256
+ | paymentFlow | IPaymentFlowSettings | The payment flow configuration |
257
+ | paymentFlow.tokenizeCard | boolean | If true, than for not 'default' paymentFlow.type card requisites will be tokenized (only for 'invoice-overridden' and 'payment-overridden' paymentFlow.type) |
258
+ | paymentFlow.type | TPaymentFlow | If 'invoice-overridden' and createInvoice callback provided to the payment form, the createInvoice callback will be called with the invoice generated by the payment form. After receiving the invoice from the createInvoice callback, the payment process will proceed according to the default scenario. If 'payment-overridden' and makePayment callback provided to the payment form, the entire payment process will be handled through the makePayment callback with the invoice generated by the payment form |
259
+
260
+ ### Example
261
+
262
+ #### Payment
263
+
264
+ ```typescript
265
+ const payment: IPaymentSettings = {
266
+ amount: 10,
267
+ currency: 'usd',
268
+ email: 'random@gmail.com',
269
+ merchantId: '22504',
270
+ paymentId: 'IS949832NF29',
271
+ userId: 'OIDSF0202JFS',
272
+ amountType: 'net',
273
+ tax: 3,
274
+ orderType: 'gems',
275
+ userAuthToken: 'testestest.testestest.testestest',
276
+ billingAddress: {
277
+ addressLine: "main street 1",
278
+ city: "Paris",
279
+ country: "US",
280
+ state: "NY",
281
+ zip: "220125"
282
+ },
283
+ description: 'my description',
284
+ initiator: 'customer',
285
+ details: {
286
+ myField: 21
287
+ },
288
+ ipAddress: '12.12.12.12',
289
+ phoneNumber: '+995234234234',
290
+ returnUrl: 'https://my.return.com',
291
+ signature: '0saidmc0smac',
292
+ webhookUrl: 'https://my.webhook.com'
293
+ }
294
+ ```
295
+
296
+ #### Settings
297
+
298
+ ```typescript
299
+ const settings: ISettings = {
300
+ urls: {
301
+ processing: 'https://my.processing.com',
302
+ billingProfiles: 'https://my.billingprofiles.com',
303
+ },
304
+ apmsCollapse: false,
305
+ availableCardBrands: ['visa', 'american-express', 'mastercard', 'diners-club', 'jcb'],
306
+ chargeTerms: {
307
+ text: {
308
+ 'en-US': 'My charge terms { href: "https://google.com", text: "Google" } the ending of text',
309
+ 'es-ES': 'My charge terms { href: "https://google.com", text: "Google es-ES" } the ending of text es-ES',
310
+ 'custom': 'custom charge terms text'
311
+ },
312
+ checkboxes: [
313
+ {
314
+ 'en-US': 'Charge terms { href: "https://google.com", text: "Google" } checkbox',
315
+ 'es-ES': 'Charge terms { href: "https://google.com", text: "Google es-ES" } checkbox es-ES',
316
+ 'custom': 'custom'
317
+ }
318
+ ]
319
+ },
320
+ closePaymentRedirect: true,
321
+ components: [
322
+ 'available-card-brands',
323
+ 'no-methods',
324
+ 'card-list',
325
+ 'requisites',
326
+ //'phone-number',
327
+ 'charge-terms',
328
+ 'pay-button',
329
+ 'apm-list',
330
+ 'user-preferences',
331
+ 'merchant-info',
332
+ 'protected-by'
333
+ ],
334
+ events: {
335
+ analytics: {
336
+ optional: true,
337
+ required: true,
338
+ },
339
+ error: true
340
+ },
341
+ isCloseButtonVisible: true,
342
+ isHeaderVisible: true,
343
+ isProblemTipsListVisible: true,
344
+ isSignatureRequired: false,
345
+ isTaxVisible: true,
346
+ languageSettings: {
347
+ code: 'custom',
348
+ languages: {
349
+ 'custom': {
350
+ apms: {
351
+ or: 'custom',
352
+ orUseAlternative: 'custom'
353
+ },
354
+ availableCardBrandsHeader: 'custom',
355
+ close: 'custom',
356
+ errors: {
357
+ invalidCardExpiration: 'custom',
358
+ invalidCardHolder: 'custom',
359
+ invalidCardNumber: 'custom',
360
+ invalidCvv: 'custom',
361
+ invalidPhoneNumber: 'custom',
362
+ notCheckedCheckboxes: 'custom'
363
+ },
364
+ existingCards: {
365
+ addNewCard: 'custom',
366
+ manageCardsHeader: 'custom',
367
+ removeCard: 'custom'
368
+ },
369
+ header: 'custom',
370
+ noAvailablePaymentMethods: 'custom',
371
+ notifications: {
372
+ cardDeleted: {
373
+ text: 'custom',
374
+ title: 'custom'
375
+ },
376
+ error: {
377
+ default: {
378
+ text: 'custom',
379
+ title: 'custom'
380
+ }
381
+ }
382
+ },
383
+ pay: 'custom',
384
+ taxDescription: 'custom',
385
+ paymentProcessing: 'custom',
386
+ paymentResult: {
387
+ success: 'custom',
388
+ failure: {
389
+ main: 'custom',
390
+ paymentFailed: 'custom'
391
+ }
392
+ },
393
+ phone: {
394
+ header: 'custom',
395
+ placeholder: 'custom'
396
+ },
397
+ requisites: {
398
+ cardExpirationPlaceholder: 'custom',
399
+ cardHolderHeader: 'custom',
400
+ cardHolderPlaceholder: 'custom',
401
+ cardNumberPlaceholder: 'custom',
402
+ cvvHint: 'custom',
403
+ paymentDetailsHeader: 'custom',
404
+ cvvPlaceholder: {
405
+ CID: 'custom',
406
+ CVC: 'custom',
407
+ CVE: 'custom',
408
+ CVN: 'custom',
409
+ CVP2: 'custom',
410
+ CVV: 'custom'
411
+ }
412
+ },
413
+ totalHeader: 'custom',
414
+ transactionProtectedBy: 'custom'
415
+ }
416
+ }
417
+ },
418
+ merchantInfo: {
419
+ text: {
420
+ 'en-US': 'Merchant info { href: "https://google.com", text: "Google" } merchant info { href: "https://google.com", text: "Google" } Merchant info',
421
+ 'es-ES': 'Merchant info { href: "https://google.com", text: "Google es-ES" } merchant info { href: "https://google.com", text: "Google es-ES" } Merchant info es-ES',
422
+ 'custom': 'custom merchant info'
423
+ },
424
+ links: [
425
+ {
426
+ href: 'https://google.com',
427
+ text: {
428
+ 'en-US': 'google',
429
+ 'es-ES': 'google (es-ES)',
430
+ 'custom': 'custom link'
431
+ }
432
+ }
433
+ ]
434
+ },
435
+ requiredFieldsBehavior: {
436
+ buttonStateUntilFilled: 'enabled',
437
+ markAsInvalidUntilCorrect: false,
438
+ showStars: true
439
+ },
440
+ resultComponentsStructure: {
441
+ aboveResult: [],
442
+ belowResult: ['merchant-info', 'protected-by']
443
+ },
444
+ userPreferences: {
445
+ text: {
446
+ 'en-US': 'User preferences text { href: "https://google.com", text: "Google" } User preferences text',
447
+ 'es-ES': 'User preferences text { href: "https://google.com", text: "Google es-ES" } User preferences text es-ES',
448
+ 'custom': 'custom user preferences text'
449
+ },
450
+ checkboxes: [
451
+ {
452
+ name: 'user_preference_name',
453
+ text: {
454
+ 'en-US': 'User preference { href: "https://google.com", text: "Google" } checkbox',
455
+ 'es-ES': 'User preference { href: "https://google.com", text: "Google es-ES" } checkbox es-ES',
456
+ 'custom': 'custom user preferences checkbox'
457
+ },
458
+ defaultValue: false
459
+ }
460
+ ]
461
+ },
462
+ paymentFlow: {
463
+ tokenizeCard: false,
464
+ type: 'default'
465
+ }
466
+ };
467
+ ```
468
+
469
+ ### Output events
470
+
471
+ | Event | Type | Description |
472
+ | ----- | ---------------- | -------------------------------------------- |
473
+ | close | void | triggered by clicking on the closing icon |
474
+ | paid | IPaymentResponse | triggered after receiving a payment response |
475
+ | error | any | triggered by error events |
476
+ | analyticsTracked | TAnalyticsServiceAction | triggered by analytics events |
477
+
478
+ ### Payment Result Structure
479
+
480
+ ```javascript
481
+ IPaymentResponse {
482
+ action?: {
483
+ name: string;
484
+ data: IThreeDsData | IRedirectData | any;
485
+ }
486
+ ip: string;
487
+ merchant: string;
488
+ order: {
489
+ invoiceId: string;
490
+ details: string;
491
+ }
492
+ payment: {
493
+ paymentId: string;
494
+ state: TPaymentState; //on of strings: completed, rejected, needAction
495
+ rebillAnchor: string;
496
+ info: {
497
+ completeProcessingTime?: Date;
498
+ currency: string;
499
+ paymentType: string;
500
+ paymentSystem: string;
501
+ paymentRequisites?: string;
502
+ price: number
503
+ }
504
+ rejectionDetails?: {
505
+ hardDecline: boolean;
506
+ message?: string;
507
+ problemSolvingTips: string[];
508
+ rejectionCode: number;
509
+ }
510
+ }
511
+ taxInfo: {
512
+ abbreviation: string;
513
+ price: number;
514
+ priceNet: number;
515
+ tax: number;
516
+ }
517
+ user: {
518
+ id: string;
519
+ }
520
+ signature: string;
521
+ }
522
+
523
+ IThreeDsData {
524
+ paReq: string;
525
+ acsurl: string;
526
+ termUrl: string;
527
+ md: string;
528
+ }
529
+
530
+ IRedirectData {
531
+ location: string;
532
+ }
533
+ ```
534
+
535
+ ### Analytics
536
+ For receiving analytics listen analyticsTracked events.
537
+
538
+ 'init-start' - the form has started initialization. Payload: void.<br>
539
+ 'loading-finish' - the form has finished initialization and loading. Payload: void.<br>
540
+ 'card-number-field-focus' - the card number field has been focused. Payload: void.<br>
541
+ 'expiration-date-field-focused' - the expiration date field has been focused. Payload: void.<br>
542
+ 'cvv-field-focused' - the cvv field has been focused. Payload: void.<br>
543
+ 'card-holder-field-focused' - the card holder field has been focused. Payload: void.<br>
544
+ 'charge-term-checkbox-<number>-focus' - the charge term checkbox has been focused. Payload: IChargeTermsAnalytics.<br>
545
+ 'charge-term-checkbox-<number>-check' - the charge term checkbox has been checked. Payload: IChargeTermsAnalytics.<br>
546
+ 'charge-term-checkbox-<number>-uncheck' - the charge term checkbox has been unchecked. Payload: IChargeTermsAnalytics.<br>
547
+ 'user-preference-checkbox-<number>-focus' - the user preference checkbox has been focused. Payload: IUserPreferencesAnalytics.<br>
548
+ 'user-preference-checkbox-<number>-check' - the user preference checkbox has been checked. Payload: IUserPreferencesAnalytics.<br>
549
+ 'user-preference-checkbox-<number>-uncheck' - the user preference checkbox has been unchecked. Payload: IUserPreferencesAnalytics.<br>
550
+ 'pay-button-focus' - the 'Pay' button has been focused (payment by card). Payload: void.<br>
551
+ 'pay-button-click' - the 'Pay' button has been clicked (payment by card). Payload: void.<br>
552
+ '<apm>-button-focus' - the apm payment button has been focused. Payload: void.<br>
553
+ '<apm>-button-click' - the apm payment button has been clicked. Payload: void.<br>
554
+ 'add-card-button-focus' - the "Add New Card" button has been focused. Payload: void.<br>
555
+ 'add-card-button-click' - the "Add New Card" button has been clicked. Payload: void.<br>
556
+ 'card-options-button-click' - the card options button has been clicked (existing card menu visualized as 3 vertical dots). Payload: ICardAnalytics.<br>
557
+ 'cards-toggle-button-click' - the cards toggle button has been clicked (show or collapse card list). Payload: ICardListAnalytics.<br>
558
+ 'remove-card-button-click' - the card removing button has been clicked. Payload: ICardAnalytics.<br>
559
+ 'select-card-button-click' - the card selecting button has been clicked. Payload: ICardAnalytics.<br>
560
+ 'apms-show-button-click' - the apm collapse text has been clicked. Payload: ICardAnalytics.<br>
561
+
562
+ Examples of dynamic event types (number inserting):
563
+ &emsp;1. Example of the first checkbox: 'charge-term-checkbox-0-check'
564
+ &emsp;2. Example of the second checkbox: 'charge-term-checkbox-1-check'
565
+
566
+ Examples of dynamic event types (apm inserting):
567
+ &emsp;1. 'coinbase-button-click'
568
+ &emsp;2. 'moto-button-click'
569
+
570
+ ```javascript
571
+ type TAnalyticsServiceAction =
572
+ | ServiceAction<'init-start'>
573
+ | ServiceAction<'loading-finish'>
574
+ | ServiceAction<'card-number-field-focus'>
575
+ | ServiceAction<'expiration-date-field-focus'>
576
+ | ServiceAction<'cvv-field-focus'>
577
+ | ServiceAction<'card-holder-field-focus'>
578
+ | ServiceAction<'number-field-focus'> //
579
+ | ServiceAction<
580
+ `charge-term-checkbox${`-${number}`}-focus`,
581
+ IChargeTermsAnalytics
582
+ >
583
+ | ServiceAction<
584
+ `charge-term-checkbox${`-${number}`}-check`,
585
+ IChargeTermsAnalytics
586
+ >
587
+ | ServiceAction<
588
+ `charge-term-checkbox${`-${number}`}-uncheck`,
589
+ IChargeTermsAnalytics
590
+ >
591
+ | ServiceAction<
592
+ `user-preference-checkbox${`-${number}`}-focus`,
593
+ IUserPreferencesAnalytics
594
+ >
595
+ | ServiceAction<
596
+ `user-preference-checkbox${`-${number}`}-check`,
597
+ IUserPreferencesAnalytics
598
+ >
599
+ | ServiceAction<
600
+ `user-preference-checkbox${`-${number}`}-uncheck`,
601
+ IUserPreferencesAnalytics
602
+ >
603
+ | ServiceAction<'pay-button-focus'>
604
+ | ServiceAction<'pay-button-click'>
605
+ | ServiceAction<`${string}-button-focus`>
606
+ | ServiceAction<`${string}-button-click`>
607
+ | ServiceAction<'add-card-button-focus'>
608
+ | ServiceAction<'add-card-button-click'>
609
+ | ServiceAction<'card-options-button-click', ICardAnalytics>
610
+ | ServiceAction<'cards-toggle-button-click', ICardListAnalytics>
611
+ | ServiceAction<'remove-card-button-click', ICardAnalytics>
612
+ | ServiceAction<'select-card-button-click', ICardAnalytics>
613
+ | ServiceAction<'apms-show-button-click', ICardAnalytics>;
614
+
615
+
616
+ //payload types
617
+ interface ICardListAnalytics {
618
+ toggle: boolean;
619
+ }
620
+
621
+ interface ICardAnalytics {
622
+ last4Digits: string;
623
+ }
624
+
625
+ interface IChargeTermsAnalytics {
626
+ text: string;
627
+ }
628
+
629
+ interface IUserPreferencesAnalytics {
630
+ name: string;
631
+ text: string;
632
+ }
633
+ ```
634
+
635
+ ### Linkify
636
+ Text elements, which are described in the documentation as linkify, can be transformed into text with links. The link object starts with the '{' character and ends with the '}' character. The href field specifies the URL to navigate to when clicked, and the text field specifies the text that will be displayed to the user as the link.
637
+ Example: 'My text { href: "https://google.com", text: "Link1" } the ending of text. The continuation of the text { href: "https://google.com", text: "Link1" }.'
638
+
639
+ ### Webpack 5 Issues
640
+
641
641
  During the integration process, you might face multiple issues with webpack 5. This issue is caused due to the fact that some packages have certain dependencies, which are not present within the browser environment by webpack 5. Hence, you require certain [node polyfills](https://webpack.js.org/configuration/resolve/#resolvefallback) to be added to your project, while overriding the configurations to enable their usage. When that is done, your project should run without any issues.