PluginProbe ʕ •ᴥ•ʔ
Payment Gateway for Authorize.net for WooCommerce / 1.0.13
Payment Gateway for Authorize.net for WooCommerce v1.0.13
1.0.18 1.0.17 1.0.16 1.0.15 1.0.14 1.0.13 trunk 1.0.0 1.0.1 1.0.10 1.0.11 1.0.12 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9
payment-gateway-for-authorize-net-for-woocommerce / assets / js / acceptjs-handler.js
payment-gateway-for-authorize-net-for-woocommerce / assets / js Last commit date
blocks 1 month ago acceptjs-echeck-handler.js 1 month ago acceptjs-handler.js 1 month ago blocks-authorizenet.js 1 month ago easyauthnet-authorizenet-admin.js 1 month ago easyauthnet-review-ajax.js 1 month ago googlepay-express.js 1 month ago googlepay-handler.js 1 month ago
acceptjs-handler.js
330 lines
1 (function ($) {
2 const {__} = wp.i18n;
3 class EPAcceptJsHandler {
4 constructor(gatewayId, params) {
5 this.gatewayId = gatewayId;
6 this.params = params;
7 this.debug = params.debug;
8 this.tokenGenerated = false;
9 this.pendingResolve = null;
10 this.pendingReject = null;
11
12 this.cardTypes = {
13 visa: /^4/,
14 mastercard: /^5[1-5]/,
15 amex: /^3[47]/,
16 discover: /^6(?:011|5)/,
17 diners: /^3(?:0[0-5]|68|69)/,
18 jcb: /^(?:2131|1800|35\d{3})/
19 };
20
21 this.log('Handler initialized');
22 this.attachEventListeners();
23 }
24
25 log(message, data = null) {
26 if (this.debug) {
27 console.log(`[AuthorizeNet] ${message}`, data || '');
28 }
29 }
30
31 error(message, data = null) {
32 if (this.debug) {
33 console.error(`[AuthorizeNet] ${message}`, data || '');
34 }
35 }
36
37 isSelected() {
38 return $(`#payment_method_${this.gatewayId}`).is(':checked');
39 }
40
41 isUsingSavedToken() {
42 const selected = $(`input[name="wc-${this.gatewayId}-payment-token"]:checked`);
43 return selected.length && selected.val() !== 'new';
44 }
45
46 collectCardData() {
47 const expiry = $('.wc-credit-card-form-card-expiry').val().split('/');
48 const cardNumber = $('.wc-credit-card-form-card-number').val().replace(/\s+/g, '');
49
50 return {
51 cardNumber: cardNumber,
52 month: expiry[0]?.trim() || '',
53 year: expiry[1]?.trim() || '',
54 cardCode: $('.wc-credit-card-form-card-cvc').val(),
55 cardType: this.detectCardType(cardNumber),
56 last4: cardNumber.slice(-4)
57 };
58 }
59
60 detectCardType(cardNumber) {
61 for (const [type, pattern] of Object.entries(this.cardTypes)) {
62 if (pattern.test(cardNumber)) {
63 return type;
64 }
65 }
66 return 'unknown';
67 }
68
69 sendToAcceptJs(cardData, form, resolve, reject) {
70 this.pendingResolve = resolve;
71 this.pendingReject = reject;
72
73 try {
74 if (typeof Accept === 'undefined') {
75 throw new Error('Accept.js library not loaded');
76 }
77
78 this.log('Dispatching card data to Authorize.Net');
79 form.addClass('easyauthnet-authorizenet-submitting');
80
81 Accept.dispatchData(
82 {
83 authData: {
84 clientKey: this.params.client_key,
85 apiLoginID: this.params.login_id
86 },
87 cardData: {
88 cardNumber: cardData.cardNumber,
89 month: cardData.month,
90 year: cardData.year,
91 cardCode: cardData.cardCode
92 }
93 },
94 (response) => {
95 this.handleResponse(response, form, cardData);
96 }
97 );
98 } catch (error) {
99 form.removeClass('easyauthnet-authorizenet-submitting');
100 this.error('Accept.js error:', error);
101 if (reject) {
102 reject(error);
103 }
104 }
105 }
106
107 handleResponse(response, form, cardData) {
108 this.log('Received response from Authorize.Net:', response);
109
110 if (response.messages.resultCode === 'Error') {
111 const message = response.messages.message[0].text;
112 this.showError(message);
113 form.removeClass('easyauthnet-authorizenet-submitting');
114 if (this.pendingReject) {
115 this.pendingReject(new Error(message));
116 }
117 return;
118 }
119
120 const token = response.opaqueData.dataValue;
121 const last4 = cardData.last4;
122 const expiry = `${cardData.month}/${cardData.year.slice(-2)}`;
123 const cardType = cardData.cardType;
124
125 this.log('Tokenization successful', {
126 token: token.substring(0, 10) + '...',
127 last4,
128 expiry,
129 cardType
130 });
131
132 this.addHiddenField(form, 'easyauthnet_authorizenet_token', token);
133 this.addHiddenField(form, 'easyauthnet_authorizenet_card_last4', last4);
134 this.addHiddenField(form, 'easyauthnet_authorizenet_card_expiry', expiry);
135 this.addHiddenField(form, 'easyauthnet_authorizenet_card_type', cardType);
136
137 form.removeClass('easyauthnet-authorizenet-submitting');
138
139 if (this.pendingResolve) {
140 this.pendingResolve({
141 token,
142 last4,
143 expiry,
144 cardType: cardType || 'unknown'
145 });
146 }
147 }
148
149 addHiddenField(form, name, value) {
150 form.find(`input[name="${name}"]`).remove();
151
152 $('<input>')
153 .attr({
154 type: 'hidden',
155 name,
156 id: name,
157 value
158 })
159 .appendTo(form);
160
161 this.log(`Added hidden field ${name}`);
162 }
163
164 showError(msg) {
165 const $form = $('form.checkout, .woocommerce-notices-wrapper, .woocommerce, .wc-block-components-notices').first();
166 if (!$form.length)
167 return;
168
169 $form.find('.woocommerce-error').remove();
170 $form.prepend(`<ul class="woocommerce-error"><li>${msg}</li></ul>`);
171
172 $('html, body').animate({scrollTop: $form.offset().top - 100}, 500);
173 }
174
175 validateCardFields() {
176 const num = $('.wc-credit-card-form-card-number').val().trim();
177 const exp = $('.wc-credit-card-form-card-expiry').val().trim();
178 const cvc = $('.wc-credit-card-form-card-cvc').val().trim();
179
180 if (!num || !exp || !cvc) {
181 this.showError(__('Please fill in all card details.', 'payment-gateway-for-authorize-net-for-woocommerce'));
182 return false;
183 }
184
185 const parts = exp.split('/');
186 if (parts.length !== 2 || parts[0].length < 2 || parts[1].length < 2) {
187 this.showError(__('Enter a valid expiration date (MM/YY).', 'payment-gateway-for-authorize-net-for-woocommerce'));
188 return false;
189 }
190
191 const cardType = this.detectCardType(num);
192 const requiredCvc = cardType === 'amex' ? 4 : 3;
193 if (cvc.length !== requiredCvc) {
194 this.showError(__('Enter a valid security code.', 'payment-gateway-for-authorize-net-for-woocommerce'));
195 return false;
196 }
197
198 return true;
199 }
200
201 attachEventListeners() {
202 this.ensureSavePaymentMethodEnabled();
203
204 $(document.body).on('updated_checkout payment_method_selected', () => {
205 this.ensureSavePaymentMethodEnabled();
206 });
207
208 // Classic Checkout
209 $('form.checkout, form#order_review').on(`checkout_place_order_${this.gatewayId}`, (e) => {
210 const form = $(e.currentTarget);
211
212 if (!this.isSelected() || this.tokenGenerated || this.isUsingSavedToken()) {
213 return true;
214 }
215
216 e.preventDefault();
217 form.addClass('easyauthnet-authorizenet-submitting');
218 $('.woocommerce-error').remove();
219
220 if (!this.validateCardFields()) {
221 form.removeClass('easyauthnet-authorizenet-submitting');
222 return false;
223 }
224
225 const cardData = this.collectCardData();
226
227 this.sendToAcceptJs(cardData, form, () => {
228 this.tokenGenerated = true;
229 form.removeClass('easyauthnet-authorizenet-submitting');
230 form.trigger('submit');
231 }, (error) => {
232 form.removeClass('easyauthnet-authorizenet-submitting');
233 this.error('Accept.js error (classic):', error);
234 });
235
236 return false;
237 });
238
239 // Checkout Blocks
240 $(document.body).on('submit_easyauthnet_authorizenet_form', (e, { resolve, reject }) => {
241 const form = $('form.wc-block-checkout__form');
242 if (!form.length) {
243 this.error('Checkout form not found');
244 if (reject)
245 reject(new Error('Checkout form not found'));
246 return;
247 }
248
249 if (this.tokenGenerated || this.isUsingSavedToken()) {
250 if (resolve)
251 resolve();
252 return;
253 }
254
255 form.addClass('easyauthnet-authorizenet-submitting');
256 $('.woocommerce-error').remove();
257
258 if (!this.validateCardFields()) {
259 form.removeClass('easyauthnet-authorizenet-submitting');
260 if (reject)
261 reject(new Error('Invalid card details'));
262 return;
263 }
264
265 this.sendToAcceptJs(this.collectCardData(), form, resolve, reject);
266 });
267
268 // Add Payment Method (My Account)
269 const addPaymentForm = $('form#add_payment_method');
270 if (addPaymentForm.length) {
271 this.log('Detected Add Payment Method page. Binding submit listener.');
272
273 addPaymentForm.on('submit', (e) => {
274 if (!this.isSelected()) {
275 this.log('Payment method not selected. Skipping Accept.js.');
276 return true;
277 }
278
279 if (this.tokenGenerated) {
280 this.log('Token already generated. Allowing submit.');
281 return true;
282 }
283
284 e.preventDefault();
285 $('.woocommerce-error').remove();
286
287 if (!this.validateCardFields()) {
288 return false;
289 }
290
291 const cardData = this.collectCardData();
292
293 this.sendToAcceptJs(cardData, addPaymentForm, () => {
294 this.tokenGenerated = true;
295 addPaymentForm.trigger('submit');
296 }, (error) => {
297 this.error('Accept.js error (add payment method):', error);
298 addPaymentForm.removeClass('easyauthnet-authorizenet-submitting');
299 });
300
301 return false;
302 });
303 }
304 }
305
306 ensureSavePaymentMethodEnabled() {
307 if (!this.params?.force_save_payment_method) {
308 return;
309 }
310
311 const checkbox = $(`#wc-${this.gatewayId}-new-payment-method`);
312 if (!checkbox.length) {
313 return;
314 }
315
316 checkbox.prop('checked', true);
317 checkbox.prop('disabled', false);
318 checkbox.trigger('change');
319 }
320 }
321
322 // Initialize on DOM ready
323 $(function () {
324 if (typeof easyauthnet_authorizenet_params !== 'undefined') {
325 window.EPAcceptJsHandler = EPAcceptJsHandler;
326 new EPAcceptJsHandler('easyauthnet_authorizenet', easyauthnet_authorizenet_params);
327 }
328 });
329 })(jQuery);
330