PluginProbe
PayPlug for WooCommerce (Official) / 3.1.0
PayPlug for WooCommerce (Official) v3.1.0
3.1.0 3.0.0 2.18.0 1.0.17 1.0.18 1.0.19 1.0.20 1.0.21 1.0.22 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.1.0 1.10.0 1.10.1 1.2.1 1.2.10 1.2.11 1.2.2 1.2.3 1.2.4 1.2.5 All 102 releases
payplug / resources / js / frontend / wc-payplug-integratedPayment-blocks.js

wc-payplug-integratedPayment-blocks.js in PayPlug for WooCommerce (Official) 3.1.0, at resources/js/frontend/wc-payplug-integratedPayment-blocks.js

290 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { getSetting } from '@woocommerce/settings';
2 import React, { useEffect, useRef } from 'react';
3 const settings = getSetting( 'payplug_data', {} );
4 import {getPayment, check_payment } from "./helper/wc-payplug-requests";
5 let saved_card = false;
6
7 const IntegratedPayment = ({props: props,}) => {
8 const { eventRegistration, emitResponse } = props;
9 saved_card = props.shouldSavePayment;
10
11 const { onCheckoutValidation, onPaymentSetup, onCheckoutSuccess } = eventRegistration;
12
13 // A plain object would be reset on every re-render, but it's read from async
14 // callbacks/DOM handlers registered in effects below that can fire well after a
15 // re-render has happened (same reason the Apple Pay blocks component uses useRef).
16 const ObjIntegratedPayment = useRef({
17 cartId: null,
18 paymentId: null,
19 paymentOptionId: null,
20 form: {},
21 checkoutForm: null,
22 api: null,
23 integratedPayment: null,
24 token: null,
25 notValid: true,
26 fieldsValid: {
27 cardHolder: false,
28 pan: false,
29 cvv: false,
30 exp: false,
31 },
32 fieldsEmpty: {
33 cardHolder: true,
34 pan: true,
35 cvv: true,
36 exp: true,
37 },
38 inputStyle: {
39 default: {
40 color: '#2B343D',
41 fontFamily: 'Poppins, sans-serif',
42 fontSize: '14px',
43 textAlign: 'left',
44 '::placeholder': {
45 color: '#969a9f',
46 },
47 ':focus': {
48 color: '#2B343D',
49 }
50 },
51 invalid: {
52 color: '#E91932'
53 }
54 },
55 save_card: false,
56 scheme: null,
57 query: null,
58 submit: null,
59 order_review: false,
60 return_url: null
61 });
62
63 useEffect(() => {
64 document.body.setAttribute('payplug-domain', settings?.secureDomain);
65 ObjIntegratedPayment.current.api = new Payplug.IntegratedPayment( settings?.mode == 1 ? false : true );
66 ObjIntegratedPayment.current.api.setDisplayMode3ds(Payplug.DisplayMode3ds.LIGHTBOX)
67 ObjIntegratedPayment.current.form.cardHolder = ObjIntegratedPayment.current.api.cardHolder(document.querySelector('.cardHolder-input-container'), {default: ObjIntegratedPayment.current.inputStyle.default, placeholder: settings?.payplug_integrated_payment_cardholder } );
68 ObjIntegratedPayment.current.form.pan = ObjIntegratedPayment.current.api.cardNumber(document.querySelector('.pan-input-container'), {default: ObjIntegratedPayment.current.inputStyle.default, placeholder: settings?.payplug_integrated_payment_card_number } );
69 ObjIntegratedPayment.current.form.cvv = ObjIntegratedPayment.current.api.cvv(document.querySelector('.cvv-input-container'), {default: ObjIntegratedPayment.current.inputStyle.default, placeholder: settings?.payplug_integrated_payment_cvv } );
70 ObjIntegratedPayment.current.form.exp = ObjIntegratedPayment.current.api.expiration(document.querySelector('.exp-input-container'), {default: ObjIntegratedPayment.current.inputStyle.default, placeholder: settings?.payplug_integrated_payment_expiration_date } );
71 ObjIntegratedPayment.current.scheme = ObjIntegratedPayment.current.api.getSupportedSchemes();
72 fieldValidation();
73
74 }, []);
75
76 useEffect(() => {
77 const onValidation = async () => {
78 ObjIntegratedPayment.current.api.validateForm();
79
80 let isValid = false;
81 await validateForm().then( (response) => {
82 isValid = response;
83 });
84
85 if(!isValid){
86 return {
87 errorMessage: settings?.payplug_invalid_form
88 }
89 }else{
90 return isValid;
91 }
92
93 function validateForm(){
94 return new Promise(async (resolve, reject) => {
95 await ObjIntegratedPayment.current.api.onValidateForm(({isFormValid}) => {
96 resolve(isFormValid);
97 });
98 })
99 }
100 }
101 const unsubscribeAfterProcessing = onCheckoutValidation(onValidation);
102 return () => { unsubscribeAfterProcessing(); };
103 }, [onCheckoutValidation]);
104
105 // Waits for the SDK to report the card capture as completed, then verifies it server-side
106 // and resolves the final response WooCommerce Blocks expects (onPaymentSetup/onCheckoutSuccess
107 // share this shape). Used once the payment_id/return_url to pay against are already known,
108 // regardless of whether that happened on order-pay (in onPaymentSetup) or regular checkout
109 // (in onCheckoutSuccess, see below).
110 function onCompleteEvent(){
111 return new Promise((resolve, reject) => {
112 ObjIntegratedPayment.current.api.onCompleted(function (event) {
113 check_payment({'payment_id' : event.token}).then((res) => {
114 if (res && res.success === false) {
115 resolve({
116 type: 'error',
117 message: settings?.payplug_integrated_payment_error
118 });
119 return;
120 }
121 resolve({
122 type: 'success',
123 });
124 }).catch(() => {
125 resolve({
126 type: 'error',
127 message: settings?.payplug_integrated_payment_error
128 });
129 });
130 });
131 });
132 }
133
134 useEffect(() => {
135 const handlePaymentProcessing = async () => {
136 // Order-pay always has a real, existing order from the start (the one being
137 // repaid), so the payment intent can be created and paid right away.
138 if (settings.is_order_pay) {
139 try {
140 const response = await getPayment(props, settings, settings.order_pay_id);
141 ObjIntegratedPayment.current.paymentId = response.data.payment_id;
142 ObjIntegratedPayment.current.return_url = response.data.redirect;
143
144 const onCompleted = onCompleteEvent();
145 await ObjIntegratedPayment.current.api.pay(ObjIntegratedPayment.current.paymentId, Payplug.Scheme.AUTO, {save_card: saved_card} );
146
147 return await onCompleted;
148 } catch (error) {
149 return {
150 type: 'error',
151 message: error.message
152 }
153 }
154 }
155
156 // Regular checkout: WooCommerce doesn't create the real order until the place-order
157 // submission that follows this step (order creation is deferred until then since
158 // WooCommerce 10.8). The payment intent can only be created once that real order
159 // exists, so that happens server-side in process_payment() and comes back here via
160 // payment_details on the onCheckoutSuccess event below - nothing more to do yet.
161 return {
162 type: 'success'
163 };
164 }
165 const unsubscribeAfterProcessing = onPaymentSetup(handlePaymentProcessing);
166 return () => { unsubscribeAfterProcessing(); };
167
168 }, [
169 onPaymentSetup
170 ]);
171
172 useEffect(() => {
173 const handleCheckoutSuccess = async ({ processingResponse }) => {
174 // Order-pay's payment was already created and paid synchronously in onPaymentSetup
175 // above, since a real order already existed there - nothing left to do here.
176 if (settings.is_order_pay) {
177 return {
178 type: "success",
179 redirectUrl: ObjIntegratedPayment.current.return_url
180 }
181 }
182
183 const paymentDetails = processingResponse?.paymentDetails || {};
184 ObjIntegratedPayment.current.paymentId = paymentDetails.payment_id;
185 ObjIntegratedPayment.current.return_url = paymentDetails.redirect;
186
187 try {
188 const onCompleted = onCompleteEvent();
189 await ObjIntegratedPayment.current.api.pay(ObjIntegratedPayment.current.paymentId, Payplug.Scheme.AUTO, {save_card: saved_card} );
190
191 const result = await onCompleted;
192 return result.type === 'success'
193 ? { ...result, redirectUrl: ObjIntegratedPayment.current.return_url }
194 : result;
195 } catch (error) {
196 return {
197 type: 'error',
198 message: error.message
199 }
200 }
201 }
202 const unsubscribeAfterProcessing = onCheckoutSuccess(handleCheckoutSuccess);
203 return () => { unsubscribeAfterProcessing(); };
204
205 }, [
206 onCheckoutSuccess
207 ]);
208
209
210 const fieldValidation = () => {
211 jQuery.each(ObjIntegratedPayment.current.form, function (key, field) {
212 field.onChange(function(err) {
213 if (err.error) {
214 document.querySelector(".payplug.IntegratedPayment_error.-"+key).classList.remove("-hide");
215 document.querySelector('.'+key+'-input-container').classList.add("-invalid");
216
217 if (err.error.name === "FIELD_EMPTY") {
218 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".emptyField").classList.remove("-hide");
219 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".invalidField").classList.add("-hide");
220 } else {
221 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".invalidField").classList.remove("-hide");
222 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".emptyField").classList.add("-hide");
223 }
224 } else {
225 document.querySelector(".payplug.IntegratedPayment_error.-"+key).classList.add("-hide");
226 document.querySelector('.'+key+'-input-container').classList.remove("-invalid");
227 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".invalidField").classList.add("-hide");
228 document.querySelector(".payplug.IntegratedPayment_error.-"+key).querySelector(".emptyField").classList.add("-hide");
229 ObjIntegratedPayment.current.fieldsValid[key] = true;
230 ObjIntegratedPayment.current.fieldsEmpty[key] = false;
231 }
232 });
233 });
234 }
235
236 return (
237 <>
238 <div id="payplug-integrated-payment" className="payplug IntegratedPayment -loaded">
239 <div className="payplug IntegratedPayment_container -cardHolder cardHolder-input-container" data-e2e-name="cardHolder"></div>
240 <div className="payplug IntegratedPayment_error -cardHolder -hide">
241 <span className="-hide invalidField" data-e2e-error="invalidField">{ settings?.payplug_integrated_payment_cardHolder_error }</span>
242 <span className="-hide emptyField" data-e2e-error="paymentError">{settings?.payplug_integrated_payment_empty}</span>
243 </div>
244 <div className="payplug IntegratedPayment_container -scheme">
245 <div>{settings?.payplug_integrated_payment_your_card}</div>
246 <div className="payplug IntegratedPayment_schemes">
247 <label className="payplug IntegratedPayment_scheme -cb">
248 <input type="radio" name="schemeOptions" value="cb"/><span></span></label>
249 <label className="payplug IntegratedPayment_scheme -visa">
250 <input type="radio" name="schemeOptions" value="visa" /><span></span></label>
251 <label className="payplug IntegratedPayment_scheme -mastercard">
252 <input type="radio" name="schemeOptions" value="mastercard"/><span></span></label>
253 </div>
254 </div>
255 <div className="payplug IntegratedPayment_container -pan pan-input-container" data-e2e-name="pan"></div>
256 <div className="payplug IntegratedPayment_error -pan -hide">
257 <span className="-hide invalidField" data-e2e-error="invalidField">{settings?.payplug_integrated_payment_pan_error}</span>
258 <span className="-hide emptyField" data-e2e-error="paymentError">{settings?.payplug_integrated_payment_empty}</span>
259 </div>
260 <div className="payplug IntegratedPayment_container -exp exp-input-container" data-e2e-name="expiration"></div>
261 <div className="payplug IntegratedPayment_container -cvv cvv-input-container" data-e2e-name="cvv"></div>
262 <div className="payplug IntegratedPayment_error -exp -hide">
263 <span className="-hide invalidField" data-e2e-error="invalidField">{settings?.payplug_integrated_payment_exp_error}</span>
264 <span className="-hide emptyField" data-e2e-error="paymentError">{settings?.payplug_integrated_payment_empty}</span>
265 </div>
266 <div className="payplug IntegratedPayment_error -cvv -hide">
267 <span className="-hide invalidField" data-e2e-error="invalidField">{settings?.payplug_integrated_payment_cvv_error}</span>
268 <span className="-hide emptyField" data-e2e-error="paymentError">{settings?.payplug_integrated_payment_empty}</span>
269 </div>
270
271 <div className="payplug IntegratedPayment_error -payment">
272 <span>{settings?.payplug_integrated_payment_error}</span>
273 </div>
274
275 <div className="payplug IntegratedPayment_container -transaction">
276 <img className="lock-icon" src={settings?.lock}/>
277 <label
278 className="transaction-label">{settings?.payplug_integrated_payment_transaction_secure}</label>
279 <img className="payplug-logo" src={settings?.logo}/>
280 </div>
281 <div className="payplug IntegratedPayment_container -privacy-policy">
282 <a href={settings?.payplug_integrated_payment_privacy_policy_url} target="_blank">{settings?.payplug_integrated_payment_privacy_policy}</a>
283 </div>
284 </div>
285 </>
286 )
287 }
288
289 export default IntegratedPayment;
290