PluginProbe
seQura / 4.0.0
seQura v4.0.0
4.3.4 4.3.3 4.3.2 4.3.1 trunk 2.0.0 2.0.10 2.0.11 2.0.12 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 3.0.0 3.0.2 3.0.5 3.0.6 3.0.7 3.1.0 3.1.1 3.2.0 3.2.1 3.2.2 4.0.0 All 30 releases
sequra / assets / js / src / block / payment-gateway.js

payment-gateway.js in seQura 4.0.0, at assets/js/src/block/payment-gateway.js

161 lines 6.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { decodeEntities } from '@wordpress/html-entities';
2 import { __ } from '@wordpress/i18n';
3 import { useEffect, useState } from '@wordpress/element';
4
5 const { registerPaymentMethod } = window.wc.wcBlocksRegistry
6 const { getSetting } = window.wc.wcSettings
7
8 const settings = getSetting('sequra_data', {})
9 const label = decodeEntities(settings.title)
10
11 const Content = (props) => {
12 const { eventRegistration, emitResponse } = props;
13 const { onPaymentSetup } = eventRegistration;
14
15 const [content, setContent] = useState(settings.description || '');
16
17 useEffect(() => {
18 const unsubscribe = onPaymentSetup(async () => {
19 const checkedInput = document.querySelector('[name="sequra_payment_method_data"]:checked')
20 const data = checkedInput ? checkedInput.value : null;
21
22 if (!data) {
23 return {
24 type: emitResponse.responseTypes.ERROR,
25 message: __('Please select a payment method.', 'sequra'),
26 };
27 }
28 return {
29 type: emitResponse.responseTypes.SUCCESS,
30 meta: {
31 paymentMethodData: { "sequra_payment_method_data": data },
32 },
33 };
34 });
35 return () => unsubscribe();
36 }, [
37 emitResponse.responseTypes.ERROR,
38 emitResponse.responseTypes.SUCCESS,
39 onPaymentSetup,
40 ]);
41
42 useEffect(() => {
43 document.addEventListener('canMakePaymentLoading', (event) => {
44 setContent('<div class="sq-loader" style="margin-top:1rem;margin-bottom:1rem;"><span class="sqp-spinner"></span></div>');
45 });
46 document.addEventListener('canMakePaymentReady', (event) => {
47 setContent(event.detail.content);
48 setTimeout(() => {
49 if ('undefined' !== typeof Sequra && 'function' === typeof Sequra.refreshComponents) {
50 Sequra.refreshComponents();
51 }
52 }, 0);
53 });
54 if ('undefined' !== typeof Sequra && 'function' === typeof Sequra.refreshComponents && 'function' === typeof Sequra.onLoad) {
55 Sequra.onLoad(Sequra.refreshComponents());
56 }
57 }, []);
58
59 return <div dangerouslySetInnerHTML={{ __html: decodeEntities(content) }} />
60 }
61
62 const Label = () => {
63 return (
64 <span style={{ width: '100%' }}>
65 {label}
66 </span>
67 )
68 }
69
70 registerPaymentMethod({
71 // A unique string to identify the payment method client side.
72 name: "sequra",
73 // A react node that will be used as a label for the payment method in the checkout.
74 label: <Label />,
75 // A react node for your payment method UI.
76 content: <Content />,
77 // A react node to display a preview of your payment method in the editor.
78 edit: <Content />,
79 // A callback to determine whether the payment method should be shown in the checkout.
80 canMakePayment: ({ shippingAddress, billingAddress, cart }) => {
81 const isSolicitationAllowed = () => 'undefined' !== typeof SeQuraBlockIntegration && SeQuraBlockIntegration.isSolicitationAllowed;
82
83 const initCache = () => {
84 if ('undefined' === typeof SeQuraBlockIntegration.cache) {
85 SeQuraBlockIntegration.cache = {};
86 }
87 };
88
89 const readFromCache = (key) => {
90 initCache();
91 return SeQuraBlockIntegration.cache[key];
92 };
93
94 const writeToCache = (key, value) => {
95 initCache();
96 SeQuraBlockIntegration.cache[key] = value;
97 };
98
99 return new Promise((resolve) => {
100 const onResolved = (canMakePayment, detail) => {
101 settings.description = detail.content;
102 document.dispatchEvent(new CustomEvent('canMakePaymentReady', { detail }));
103 resolve(canMakePayment);
104 }
105
106 if (!isSolicitationAllowed()) {
107 // Prevent unnecessary requests.
108 onResolved(false, { content: '' });
109 return;
110 }
111
112 // Hash the data to prevent unnecessary requests.
113 const requestId = btoa(encodeURIComponent(JSON.stringify({ shippingAddress, billingAddress, cart })));
114
115 document.dispatchEvent(new CustomEvent('canMakePaymentLoading', { detail: { requestId } }));
116
117 // TODO: Implement check if requestId is pending. When page loads, this code is executed three times for the same requestId what can be avoided.
118 const cachedContent = readFromCache(requestId);
119 if (cachedContent) {
120 onResolved('' !== cachedContent, { content: cachedContent });
121 return;
122 }
123
124 settings.description = '';
125 const data = new FormData();
126 data.append('action', settings.blockContentAjaxAction);
127 data.append('shippingAddress', JSON.stringify(shippingAddress));
128 data.append('billingAddress', JSON.stringify(billingAddress));
129 data.append('requestId', requestId);
130
131 fetch(settings.blockContentUrl, {
132 method: 'POST',
133 credentials: 'same-origin', // Allow including cookies in the request.
134 body: data
135 }).then(response => {
136 if (!response.ok) {
137 throw new Error('Network response was not ok');
138 }
139
140 response.json().then(json => {
141 if (!json.requestId) {
142 // invalidate the request.
143 throw new Error('Request ID is missing');
144 }
145
146 writeToCache(json.requestId, json.content);
147 onResolved('' !== json.content, { content: json.content });
148 }).catch(() => {
149 onResolved(false, { content: '' });
150 });
151 }).catch(() => {
152 onResolved(false, { content: '' });
153 });
154 });
155 },
156 ariaLabel: label,
157 // SupportsConfiguration Object that describes various features provided by the payment method.
158 supports: {
159 features: settings.supports,
160 }
161 })