@gudhub/ssg-web-components-library 1.0.115 → 1.0.117

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.
@@ -4,53 +4,90 @@ info-table {
4
4
  }
5
5
 
6
6
  .top-wrapper {
7
- display: flex;
8
- align-items: center;
7
+ margin-bottom: 30px;
9
8
 
10
- h2 {
11
- width: 50%;
12
- font-size: 18px;
9
+ .title {
10
+ color: #05183A;
13
11
  font-weight: 700;
14
- color: black;
15
- line-height: 120%;
12
+ font-size: 30px;
13
+ line-height: 136%;
14
+ letter-spacing: 0%;
15
+ text-align: center;
16
+ text-transform: uppercase;
17
+ margin-bottom: 12px;
16
18
  }
17
19
 
18
- p {
19
- width: 50%;
20
+ .subtitle {
21
+ font-weight: 400;
20
22
  font-size: 18px;
21
- font-weight: 700 !important;
22
- color: black !important;
23
- line-height: 120%;
23
+ line-height: 136%;
24
+ letter-spacing: 0%;
25
+ text-align: justify;
26
+ color: #63636F;
24
27
  text-align: center;
25
28
  }
26
-
27
- .title {
28
- margin-bottom: 30px;
29
- }
30
29
  }
30
+
31
31
  .block {
32
+ width: 100%;
32
33
  margin-bottom: 25px;
33
34
  border: 1px solid #C8C8C8;
35
+ border-collapse: collapse;
36
+ table-layout: fixed;
37
+ }
38
+
39
+ .table-head {
40
+ th {
41
+ width: 50%;
42
+ height: 52px;
43
+ padding: 0 15px;
44
+ border-bottom: 1px solid #C8C8C8;
45
+ vertical-align: middle;
46
+ text-align: center;
47
+ font-size: 18px;
48
+ font-weight: 700;
49
+ color: black;
50
+ line-height: 120%;
51
+ }
52
+
53
+ th:not(:last-child) {
54
+ border-right: 1px solid #C8C8C8;
55
+ }
34
56
  }
35
- .item {
36
- display: flex;
37
57
 
58
+ .item {
38
59
  &:nth-child(even) {
39
60
  background-color: #F6F6F6;
40
61
  }
41
- &:not(:last-child) {
62
+
63
+ td {
64
+ width: 50%;
65
+ height: 48px;
66
+ padding: 0 15px;
42
67
  border-bottom: 1px solid #C8C8C8;
68
+ vertical-align: middle;
69
+ text-align: center;
70
+ }
71
+
72
+ td:not(:last-child) {
73
+ border-right: 1px solid #C8C8C8;
74
+ }
75
+
76
+ &:last-child {
77
+ td {
78
+ border-bottom: none;
79
+ }
43
80
  }
44
81
 
45
82
  &-title,
46
83
  &-price {
47
- line-height: 48px;
84
+ width: 100%;
85
+ margin: 0;
86
+ font-size: 16px;
87
+ font-weight: 400;
88
+ color: black;
89
+ line-height: 140%;
48
90
  text-align: center;
49
- width: 50%;
50
- height: 48px;
51
- }
52
- &-price {
53
- border-left: 1px solid #C8C8C8;
54
91
  }
55
92
  }
56
93
 
@@ -70,6 +107,38 @@ info-table {
70
107
  @media (max-width: 700px) {
71
108
  section {
72
109
  padding-bottom: 40px;
73
- }
110
+ }
111
+
112
+ .top-wrapper {
113
+ margin-bottom: 24px;
114
+
115
+ .title {
116
+ font-size: 26px;
117
+ }
118
+
119
+ .subtitle {
120
+ font-size: 16px;
121
+ }
122
+ }
123
+
124
+ .table-head {
125
+ th {
126
+ height: 48px;
127
+ padding: 0 10px;
128
+ font-size: 16px;
129
+ }
130
+ }
131
+
132
+ .item {
133
+ td {
134
+ height: 46px;
135
+ padding: 0 10px;
136
+ }
137
+
138
+ &-title,
139
+ &-price {
140
+ font-size: 15px;
141
+ }
142
+ }
74
143
  }
75
- }
144
+ }
@@ -0,0 +1,6 @@
1
+ export const liqpayComponent = {
2
+ tag: 'liqpay-component',
3
+ category: 'Payment',
4
+ src: '@gudhub/ssg-web-components-library/src/components/liqpay-component/liqpay-component.js',
5
+ serverOnly: false
6
+ };
@@ -0,0 +1,91 @@
1
+ <section class="liqpay-component">
2
+ <!-- <div class="liqpay-component__logo">
3
+ <div class="liqpay-component__logo-badge">
4
+ <div class="liqpay-component__logo-badge-text">
5
+ <span class="liqpay-component__logo-gud">GUD</span>
6
+ <span class="liqpay-component__logo-hub">HUB</span>
7
+ </div>
8
+ </div>
9
+ <span class="liqpay-component__logo-crm">CRM</span>
10
+ </div> -->
11
+
12
+ <h1 class="liqpay-component__title" data-liqpay-title></h1>
13
+
14
+ <p class="liqpay-component__subtitle" data-liqpay-subtitle></p>
15
+
16
+ <div class="liqpay-component__card">
17
+ <div class="liqpay-component__amount-row">
18
+ <div>
19
+ <p class="liqpay-component__amount-label">Amount</p>
20
+ <p class="liqpay-component__amount" data-liqpay-amount></p>
21
+ </div>
22
+ <div class="liqpay-component__secured-badge">
23
+ <div class="liqpay-component__secured-icon" aria-hidden="true">
24
+ <svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
25
+ <polyline points="2,5 4,7.5 8,3" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
26
+ </svg>
27
+ </div>
28
+ <span class="liqpay-component__secured-text">Secured</span>
29
+ </div>
30
+ </div>
31
+
32
+ <div class="liqpay-component__divider"></div>
33
+
34
+ <div class="liqpay-component__summary">
35
+ <div class="liqpay-component__summary-row">
36
+ <span class="liqpay-component__summary-label">Description</span>
37
+ <strong class="liqpay-component__summary-value" data-liqpay-description></strong>
38
+ </div>
39
+
40
+ <div class="liqpay-component__summary-row" data-liqpay-order-row>
41
+ <span class="liqpay-component__summary-label">Order ID</span>
42
+ <strong class="liqpay-component__summary-value" data-liqpay-order-id></strong>
43
+ </div>
44
+ </div>
45
+
46
+ <p class="liqpay-component__text" data-liqpay-text></p>
47
+
48
+ <form
49
+ class="liqpay-component__form"
50
+ method="POST"
51
+ accept-charset="utf-8"
52
+ data-liqpay-form
53
+ >
54
+ <input type="hidden" name="data" data-liqpay-data>
55
+ <input type="hidden" name="signature" data-liqpay-signature>
56
+
57
+ <button class="liqpay-component__button" type="button" data-liqpay-button>
58
+ <svg class="liqpay-component__button-icon" viewBox="0 0 18 18" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true">
59
+ <rect x="2" y="7" width="14" height="10" rx="2" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
60
+ <path d="M6 7V5a3 3 0 016 0v2" stroke="#ffffff" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
61
+ </svg>
62
+ <span data-liqpay-button-text></span>
63
+ </button>
64
+ </form>
65
+
66
+ <p class="liqpay-component__error" data-liqpay-error hidden></p>
67
+
68
+ <p class="liqpay-component__powered">
69
+ Powered by <span class="liqpay-component__powered-brand">LiqPay</span>
70
+ </p>
71
+ </div>
72
+
73
+ <div class="liqpay-component__security">
74
+ <div class="liqpay-component__security-item">
75
+ <div class="liqpay-component__security-icon" aria-hidden="true">
76
+ <svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
77
+ <polyline points="2,5 4,7.5 8,3" stroke="#16a34a" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
78
+ </svg>
79
+ </div>
80
+ <span>256-bit Encryption</span>
81
+ </div>
82
+ <div class="liqpay-component__security-item">
83
+ <div class="liqpay-component__security-icon" aria-hidden="true">
84
+ <svg viewBox="0 0 10 10" fill="none" xmlns="http://www.w3.org/2000/svg">
85
+ <polyline points="2,5 4,7.5 8,3" stroke="#16a34a" stroke-width="1.8" stroke-linecap="round" stroke-linejoin="round"/>
86
+ </svg>
87
+ </div>
88
+ <span>PCI DSS Compliant</span>
89
+ </div>
90
+ </div>
91
+ </section>
@@ -0,0 +1,197 @@
1
+ import html from './liqpay-component.html';
2
+ import './liqpay-component.scss';
3
+ import jsonTemplate from './liqpay-component.json';
4
+
5
+ class LiqpayComponent extends window.GHComponent {
6
+ constructor() {
7
+ super();
8
+ super.setDefaultData(jsonTemplate);
9
+
10
+ this.isLoading = false;
11
+ }
12
+
13
+ async onServerRender() {
14
+ super.render(html);
15
+ }
16
+
17
+ onClientRender() {
18
+ this.initComponent();
19
+ }
20
+
21
+ initComponent() {
22
+ this.titleElement = this.querySelector('[data-liqpay-title]');
23
+ this.subtitleElement = this.querySelector('[data-liqpay-subtitle]');
24
+ this.amountElement = this.querySelector('[data-liqpay-amount]');
25
+ this.descriptionElement = this.querySelector('[data-liqpay-description]');
26
+ this.textElement = this.querySelector('[data-liqpay-text]');
27
+ this.orderRowElement = this.querySelector('[data-liqpay-order-row]');
28
+ this.orderIdElement = this.querySelector('[data-liqpay-order-id]');
29
+ this.formElement = this.querySelector('[data-liqpay-form]');
30
+ this.dataInput = this.querySelector('[data-liqpay-data]');
31
+ this.signatureInput = this.querySelector('[data-liqpay-signature]');
32
+ this.buttonElement = this.querySelector('[data-liqpay-button]');
33
+ this.buttonTextElement = this.querySelector('[data-liqpay-button-text]');
34
+ this.errorElement = this.querySelector('[data-liqpay-error]');
35
+
36
+ this.renderPaymentInfo();
37
+ this.bindEvents();
38
+ }
39
+
40
+ getConfig() {
41
+ return {
42
+ ...jsonTemplate,
43
+ ...(this.json || {})
44
+ };
45
+ }
46
+
47
+ renderPaymentInfo() {
48
+ const config = this.getConfig();
49
+
50
+ console.log("CONFIG:", config);
51
+
52
+ const amount = Number(config.amount || 0);
53
+ const currency = config.currency || 'UAH';
54
+
55
+ this.titleElement.textContent = config.title || '';
56
+ this.subtitleElement.textContent = config.subtitle || '';
57
+ this.descriptionElement.textContent = config.payment_description || '';
58
+ this.textElement.textContent = config.description || '';
59
+ this.amountElement.textContent = this.formatAmount(amount, currency);
60
+ this.buttonTextElement.textContent = config.button_text || 'Сплатити';
61
+
62
+ if (config.order_id) {
63
+ this.orderIdElement.textContent = config.order_id;
64
+ this.orderRowElement.hidden = false;
65
+ } else {
66
+ this.orderIdElement.textContent = '';
67
+ this.orderRowElement.hidden = true;
68
+ }
69
+
70
+ this.formElement.action = config.liqpay_checkout_url;
71
+ }
72
+
73
+ bindEvents() {
74
+ this.buttonElement.addEventListener('click', () => this.handlePayment());
75
+ }
76
+
77
+ async handlePayment() {
78
+ if (this.isLoading) {
79
+ return;
80
+ }
81
+
82
+ const config = this.getConfig();
83
+
84
+ this.hideError();
85
+
86
+ if (!this.validatePaymentConfig(config)) {
87
+ this.showError('Некоректні дані для оплати.');
88
+ return;
89
+ }
90
+
91
+ try {
92
+ this.setLoading(true);
93
+
94
+ const payment = await this.createPayment(config);
95
+
96
+ this.dataInput.value = payment.data;
97
+ this.signatureInput.value = payment.signature;
98
+
99
+ this.formElement.submit();
100
+ } catch (error) {
101
+ console.error('Failed to create LiqPay payment:', error);
102
+ this.showError(
103
+ config.error_text || 'Не вдалося підготувати оплату. Спробуйте ще раз.'
104
+ );
105
+ } finally {
106
+ this.setLoading(false);
107
+ }
108
+ }
109
+
110
+ async createPayment(config) {
111
+ const response = await fetch(`https://gudhub-nodejs.ngrok.io:443${config.create_payment_url}`, {
112
+ method: 'POST',
113
+ headers: {
114
+ 'Content-Type': 'application/json'
115
+ },
116
+ body: JSON.stringify({
117
+ amount: config.amount,
118
+ currency: config.currency,
119
+ order_id: config.order_id,
120
+ description: config.payment_description
121
+ })
122
+ });
123
+
124
+ if (!response.ok) {
125
+ const errorText = await response.text();
126
+
127
+ throw new Error(`Payment request failed with status ${response.status}: ${errorText}`);
128
+ }
129
+
130
+ const payment = await response.json();
131
+
132
+ if (!payment?.data || !payment?.signature) {
133
+ throw new Error('Invalid payment response');
134
+ }
135
+
136
+ return payment;
137
+ }
138
+
139
+ validatePaymentConfig(config) {
140
+ const amount = Number(config.amount);
141
+
142
+ if (!Number.isFinite(amount) || amount <= 0) {
143
+ return false;
144
+ }
145
+
146
+ if (!config.currency) {
147
+ return false;
148
+ }
149
+
150
+ if (!config.order_id) {
151
+ return false;
152
+ }
153
+
154
+ if (!config.payment_description) {
155
+ return false;
156
+ }
157
+
158
+ if (!config.create_payment_url) {
159
+ return false;
160
+ }
161
+
162
+ if (!config.liqpay_checkout_url) {
163
+ return false;
164
+ }
165
+
166
+ return true;
167
+ }
168
+
169
+ setLoading(isLoading) {
170
+ const config = this.getConfig();
171
+
172
+ this.isLoading = isLoading;
173
+ this.buttonElement.disabled = isLoading;
174
+ this.buttonTextElement.textContent = isLoading
175
+ ? config.loading_text || 'Підготовка оплати...'
176
+ : config.button_text || 'Сплатити';
177
+ }
178
+
179
+ showError(message) {
180
+ this.errorElement.textContent = message;
181
+ this.errorElement.hidden = false;
182
+ }
183
+
184
+ hideError() {
185
+ this.errorElement.textContent = '';
186
+ this.errorElement.hidden = true;
187
+ }
188
+
189
+ formatAmount(amount, currency) {
190
+ return new Intl.NumberFormat('uk-UA', {
191
+ style: 'currency',
192
+ currency
193
+ }).format(amount);
194
+ }
195
+ }
196
+
197
+ window.customElements.define('liqpay-component', LiqpayComponent);
@@ -0,0 +1,14 @@
1
+ {
2
+ "title": "Test Payment",
3
+ "subtitle": "Complete your test payment securely with LiqPay.",
4
+ "description": "After clicking the button you will be redirected to the LiqPay secure payment page.",
5
+ "amount": 1,
6
+ "currency": "UAH",
7
+ "order_id": "test-order-001",
8
+ "payment_description": "Test LiqPay payment",
9
+ "button_text": "Сплатити",
10
+ "loading_text": "Підготовка оплати...",
11
+ "error_text": "Не вдалося підготувати оплату. Спробуйте ще раз.",
12
+ "create_payment_url": "/liqpay/create-payment",
13
+ "liqpay_checkout_url": "https://www.liqpay.ua/api/3/checkout"
14
+ }