Skip to content

Commit 79ddf19

Browse files
committed
Merge branch 'release/4.43.0'
2 parents 383e493 + 5aac4e5 commit 79ddf19

File tree

15 files changed

+530
-127
lines changed

15 files changed

+530
-127
lines changed

DEVELOPER.md

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,9 @@ btoa(`conteudo do blueprint.json`);
1717

1818
https://playground.wordpress.net/#ewogICIkc2NoZW1hIjogImh0dHBzOi8vcGxheWdyb3VuZC53b3JkcHJlc3MubmV0L2JsdWVwcmludC1zY2hlbWEuanNvbiIsCiAgInN0ZXBzIjogWwogICAgewogICAgICAic3RlcCI6ICJpbXBvcnRXb3JkUHJlc3NGaWxlcyIsCiAgICAgICJ3b3JkUHJlc3NGaWxlc1ppcCI6IHsKICAgICAgICAicmVzb3VyY2UiOiAidXJsIiwKICAgICAgICAidXJsIjogImh0dHBzOi8vd3d3LmRyb3Bib3guY29tL3NjbC9maS9zdGx2dWsxODg1Znk0ODVhb2xyYWwvcGFnYmFuay1jb25uZWN0LXBsYXlncm91bmQuemlwP3Jsa2V5PXVkeXpha2IybTJ6aDd6YWludWNhdm04dmwmZGw9MSIKICAgICAgfQogICAgfSwKICAgIHsKICAgICAgInN0ZXAiOiAid3AtY2xpIiwKICAgICAgImNvbW1hbmQiOiAid3AgcGx1Z2luIHVwZGF0ZSAtLWFsbCIKICAgIH0KICBdCn0=
1919

20-
O console do navegador poderá indicar se há algum erro no blueprint.
20+
O console do navegador poderá indicar se há algum erro no blueprint.
21+
22+
## Testando com Docker
23+
Pra enviar requests pro docker, 2 modificações precisam ser feitas em Helpers/Api.php.
24+
1. Trocar URL base para `https://web/connect/`
25+
2. Adicionar options sslverify = false nos options do método get e post.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"name": "ricardomartins/pagbank-woocommerce",
33
"description": "Integração PagBank (PagSeguro) WooCommerce com desconto nas taxas oficiais",
44
"type": "wordpress-plugin",
5-
"version": "4.42.2",
5+
"version": "4.43.0",
66
"license": "GPL-3.0",
77
"autoload": {
88
"psr-4": {

public/js/blocks/checkout-blocks-cc.js

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import {registerPaymentMethod} from '@woocommerce/blocks-registry';
22
import {getSetting} from '@woocommerce/settings';
3-
import {useEffect} from '@wordpress/element';
3+
import {useEffect, useRef} from '@wordpress/element';
44
import {decodeEntities} from '@wordpress/html-entities';
55
import {__} from '@wordpress/i18n';
66

@@ -9,7 +9,8 @@ import CreditCardForm from "./components/CreditCardForm";
99
import CustomerDocumentField from './components/CustomerDocumentField';
1010
import RecurringInfo from './components/RecurringInfo';
1111
import RetryInput from './components/RetryInput';
12-
12+
const { useSelect } = window.wp.data;
13+
const { checkoutStore } = window.wc.wcBlocksData;
1314
const settings = getSetting('rm-pagbank-cc_data', {});
1415
const label = decodeEntities( settings.title ) || window.wp.i18n.__( 'PagBank Connect Cartão de Crédito', 'rm-pagbank-pix' );
1516
let showRetryInput = false;
@@ -46,7 +47,8 @@ const Label = ( props ) => {
4647
const Content = ( props ) => {
4748
const { eventRegistration, emitResponse, billing } = props;
4849
const { onPaymentSetup, onCheckoutValidation: onCheckoutValidation, onCheckoutSuccess, onCheckoutFail } = eventRegistration;
49-
50+
const isCalculating = useSelect((select) => select(checkoutStore).isCalculating());
51+
const cartTotalRef = useRef(billing.cartTotal.value ?? 0);
5052
if (settings.paymentUnavailable) {
5153
useEffect( () => {
5254
const unsubscribe = onPaymentSetup(() => {
@@ -284,17 +286,15 @@ const Content = ( props ) => {
284286
selectedInstallments = 1;
285287
}
286288

287-
let cartTotal = billing.cartTotal.value;
288-
289289
//if cart total is less than 100, don't continue with 3ds
290-
if (cartTotal < 100) {
290+
if (cartTotalRef.current < 100) {
291291
canContinue = true;
292292
card3d = false;
293293
return true;
294294
}
295295

296296
if (selectedInstallments > 1) {
297-
cartTotal = window.ps_cc_installments.find((installment, idx, installments)=> installments[idx].installments == selectedInstallments).total_amount_raw;
297+
cartTotalRef.current = window.ps_cc_installments.find((installment, idx, installments)=> installments[idx].installments == selectedInstallments).total_amount_raw;
298298
}
299299

300300
let request = {
@@ -359,7 +359,7 @@ const Content = ( props ) => {
359359
}]
360360
},
361361
amount: {
362-
value: cartTotal,
362+
value: cartTotalRef.current,
363363
currency: 'BRL'
364364
},
365365
billingAddress: {
@@ -447,6 +447,13 @@ const Content = ( props ) => {
447447
};
448448
}, [onPaymentSetup] );
449449

450+
// When the bin changes or total recalculates
451+
useEffect(() => {
452+
if (!isCalculating) {
453+
cartTotalRef.current = billing.cartTotal.value;
454+
}
455+
}, [isCalculating]);
456+
450457
return (
451458
<div className="rm-pagbank-cc">
452459
{showRetryInput ? <RetryInput /> : null}

public/js/blocks/components/CreditCardForm.js

Lines changed: 77 additions & 82 deletions
Original file line numberDiff line numberDiff line change
@@ -4,97 +4,92 @@ import { __ } from '@wordpress/i18n';
44
import { getSetting } from '@woocommerce/settings';
55
import MaskedInput from './MaskedInput';
66
import InstallmentsOptions from './InstallmentsOptions';
7+
const { useSelect } = window.wp.data;
8+
const { checkoutStore } = window.wc.wcBlocksData;
79
const PaymentInstructions = () => {
810
const settings = getSetting('rm-pagbank-cc_data', {});
911
const defaultInstallments = settings.defaultInstallments || [];
10-
const [creditCardNumber, setCreditCardNumber] = useState('');
12+
const [creditCardNumber, setCreditCardNumber] = useState('555566');
1113
const [ccBin, setCcBin] = useState('');
1214
const [cardBrand, setCardBrand] = useState('');
1315
const prevCcBinRef = useRef();
1416
const [installments, setInstallments] = useState(defaultInstallments);
1517
window.ps_cc_installments = installments;
1618

17-
useEffect(() => {
18-
prevCcBinRef.current = ccBin;
19-
}, [ccBin]);
20-
21-
const prevCcBin = prevCcBinRef.current;
22-
23-
useEffect( () => {
24-
// Detect card brand
25-
const detectCardBrand = (number) => {
26-
const visaRegex = /^4[0-9]{0,}$/;
27-
const mastercardRegex = /^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/;
28-
const amexRegex = /^3([47]\d*)?$/;
29-
const dinersRegex = /^(3(0[0-5]|095|6|[8-9]))\d*$/;
30-
const jcbRegex = /^(?:2131|1800|35\d{3})\d{0,}$/;
31-
const auraRegex = /^5078\d*$/;
32-
const hiperRegex = /^((606282)|(637095)|(637568)|(637599)|(637609)|(637612))\d*$/;
33-
const eloRegex = new RegExp(
34-
'^((451416)|(509091)|(636368)|(636297)|(504175)|(438935)|(40117[8-9])|(45763[1-2])|' +
35-
'(457393)|(431274)|(50990[0-2])|(5099[7-9][0-9])|(50996[4-9])|(509[1-8][0-9][0-9])|' +
36-
'(5090(0[0-2]|0[4-9]|1[2-9]|[24589][0-9]|3[1-9]|6[0-46-9]|7[0-24-9]))|' +
37-
'(5067(0[0-24-8]|1[0-24-9]|2[014-9]|3[0-379]|4[0-9]|5[0-3]|6[0-5]|7[0-8]))|' +
38-
'(6504(0[5-9]|1[0-9]|2[0-9]|3[0-9]))|' +
39-
'(6504(8[5-9]|9[0-9])|6505(0[0-9]|1[0-9]|2[0-9]|3[0-8]))|' +
40-
'(6505(4[1-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-8]))|' +
41-
'(6507(0[0-9]|1[0-8]))|(65072[0-7])|(6509(0[1-9]|1[0-9]|20))|' +
42-
'(6516(5[2-9]|6[0-9]|7[0-9]))|(6550(0[0-9]|1[0-9]))|' +
43-
'(6550(2[1-9]|3[0-9]|4[0-9]|5[0-8])))\\d*$'
44-
);
45-
46-
if (mastercardRegex.test(number)) return 'mastercard';
47-
if (amexRegex.test(number)) return 'amex';
48-
if (dinersRegex.test(number)) return 'diners';
49-
if (jcbRegex.test(number)) return 'jcb';
50-
if (auraRegex.test(number)) return 'aura';
51-
if (hiperRegex.test(number)) return 'hipercard';
52-
if (eloRegex.test(number)) return 'elo';
53-
if (visaRegex.test(number)) return 'visa';
54-
55-
return '';
56-
};
57-
58-
setCardBrand(detectCardBrand(creditCardNumber.replace(/\D/g, '')));
59-
60-
if (settings.isCartRecurring === true) {
61-
return;
62-
}
63-
64-
if (creditCardNumber.replace(/\D/g, '').length < 6) {
65-
return;
66-
}
67-
68-
let ccBinNew = creditCardNumber.replace(/\D/g, '').substring(0, 6);
69-
if (ccBinNew === prevCcBin) {
70-
return;
71-
}
72-
73-
setCcBin(ccBinNew);
74-
75-
let url = settings.ajax_url;
76-
77-
jQuery.ajax({
78-
url: url,
79-
method: 'POST',
80-
data: {
81-
cc_bin: ccBinNew,
82-
nonce: settings.rm_pagbank_nonce,
83-
action: 'ps_get_installments',
84-
},
85-
success: (response)=>{
86-
window.ps_cc_installments = response;
87-
setInstallments(response);
88-
},
89-
error: (response)=>{
90-
alert('Erro ao calcular parcelas. Verifique os dados do cartão e tente novamente.');
91-
console.info('Lojista: Verifique os logs em WooCommerce > Status > Logs ' +
92-
'para ver os possíveis problemas na obtenção das parcelas. Note que cartões de teste falharão ' +
93-
'na maioria dos casos.');
94-
}
95-
});
96-
97-
}, [creditCardNumber] );
19+
const isCalculating = useSelect((select) => select(checkoutStore).isCalculating());
20+
const detectCardBrand = (number) => {
21+
const visaRegex = /^4[0-9]{0,}$/;
22+
const mastercardRegex = /^(?:5[1-5][0-9]{2}|222[1-9]|22[3-9][0-9]|2[3-6][0-9]{2}|27[01][0-9]|2720)[0-9]{12}$/;
23+
const amexRegex = /^3([47]\d*)?$/;
24+
const dinersRegex = /^(3(0[0-5]|095|6|[8-9]))\d*$/;
25+
const jcbRegex = /^(?:2131|1800|35\d{3})\d{0,}$/;
26+
const auraRegex = /^5078\d*$/;
27+
const hiperRegex = /^((606282)|(637095)|(637568)|(637599)|(637609)|(637612))\d*$/;
28+
const eloRegex = new RegExp(
29+
'^((451416)|(509091)|(636368)|(636297)|(504175)|(438935)|(40117[8-9])|(45763[1-2])|' +
30+
'(457393)|(431274)|(50990[0-2])|(5099[7-9][0-9])|(50996[4-9])|(509[1-8][0-9][0-9])|' +
31+
'(5090(0[0-2]|0[4-9]|1[2-9]|[24589][0-9]|3[1-9]|6[0-46-9]|7[0-24-9]))|' +
32+
'(5067(0[0-24-8]|1[0-24-9]|2[014-9]|3[0-379]|4[0-9]|5[0-3]|6[0-5]|7[0-8]))|' +
33+
'(6504(0[5-9]|1[0-9]|2[0-9]|3[0-9]))|' +
34+
'(6504(8[5-9]|9[0-9])|6505(0[0-9]|1[0-9]|2[0-9]|3[0-8]))|' +
35+
'(6505(4[1-9]|5[0-9]|6[0-9]|7[0-9]|8[0-9]|9[0-8]))|' +
36+
'(6507(0[0-9]|1[0-8]))|(65072[0-7])|(6509(0[1-9]|1[0-9]|20))|' +
37+
'(6516(5[2-9]|6[0-9]|7[0-9]))|(6550(0[0-9]|1[0-9]))|' +
38+
'(6550(2[1-9]|3[0-9]|4[0-9]|5[0-8])))\\d*$'
39+
);
40+
41+
if (mastercardRegex.test(number)) return 'mastercard';
42+
if (amexRegex.test(number)) return 'amex';
43+
if (dinersRegex.test(number)) return 'diners';
44+
if (jcbRegex.test(number)) return 'jcb';
45+
if (auraRegex.test(number)) return 'aura';
46+
if (hiperRegex.test(number)) return 'hipercard';
47+
if (eloRegex.test(number)) return 'elo';
48+
if (visaRegex.test(number)) return 'visa';
49+
return '';
50+
};
51+
52+
const fetchInstallments = (bin, force = false) => {
53+
if (bin.length < 6 || (prevCcBinRef.current === bin && !force)) return;
54+
55+
if (settings.isCartRecurring === true) return;
56+
57+
prevCcBinRef.current = bin;
58+
59+
jQuery.ajax({
60+
url: settings.ajax_url,
61+
method: 'POST',
62+
data: {
63+
cc_bin: bin,
64+
nonce: settings.rm_pagbank_nonce,
65+
action: 'ps_get_installments',
66+
},
67+
success: (response) => {
68+
window.ps_cc_installments = response;
69+
setInstallments(response);
70+
},
71+
error: () => {
72+
alert('Erro ao calcular parcelas. Verifique os dados do cartão e tente novamente.');
73+
console.info('WooCommerce > Status > Logs para mais detalhes.');
74+
}
75+
});
76+
};
77+
78+
// When the credit card number changes
79+
useEffect(() => {
80+
const digits = creditCardNumber.replace(/\D/g, '');
81+
if (digits.length >= 6) {
82+
setCardBrand(detectCardBrand(digits));
83+
setCcBin(digits.substring(0, 6));
84+
}
85+
}, [creditCardNumber]);
86+
87+
// When the bin changes or total recalculates
88+
useEffect(() => {
89+
if (!isCalculating && ccBin) {
90+
fetchInstallments(ccBin, true);
91+
}
92+
}, [ccBin, isCalculating]);
9893

9994
return (
10095
<div>

public/js/creditcard.js

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -209,15 +209,15 @@ jQuery(document).ready(function ($) {
209209

210210
//region 3ds authentication
211211
let isSubmitting = false;
212-
let checkoutFormIdentifiers = 'form.woocommerce-checkout, form#order_review, .wc-block-components-form, .wc-block-checkout__form, form#order_update';
212+
let checkoutFormIdentifiers = 'form.woocommerce-checkout, form#order_review, .wc-block-components-form, .wc-block-checkout__form, form#order_update, form#add_payment_method';
213213
if (!jQuery(checkoutFormIdentifiers).length) {
214214
console.debug('PagBank: checkout form not found');
215215
return true;
216216
}
217217
let originalSubmitHandler = () => {};
218218
// get the original submit handler for checkout or order-pay page
219219
if (jQuery._data(jQuery(checkoutFormIdentifiers)[0], "events") !== undefined) {
220-
let formCheckout = jQuery('form.woocommerce-checkout, form#order_review, form#order_update')[0];
220+
let formCheckout = jQuery('form.woocommerce-checkout, form#order_review, form#order_update, form#add_payment_method')[0];
221221
let formEvents = jQuery._data(formCheckout, "events");
222222

223223
if (formEvents && formEvents.submit) {
@@ -244,6 +244,15 @@ jQuery(document).ready(function ($) {
244244
return true;
245245
}
246246

247+
const cc_payment_token = jQuery('input[name="wc-rm-pagbank-cc-payment-token"]:checked').val();
248+
if (cc_payment_token && cc_payment_token !== 'new') {
249+
console.debug('PagBank: cartão salvo selecionado, não criptografar.');
250+
isSubmitting = true;
251+
jQuery(checkoutFormIdentifiers).on('submit', originalSubmitHandler);
252+
jQuery(checkoutFormIdentifiers).trigger('submit');
253+
return true;
254+
}
255+
247256
if (window.ps_cc_has_changed !== false) {
248257
console.debug('Pagbank: cartao mudou NOVO');
249258
let card_number = jQuery('#rm-pagbank-card-number').val();
@@ -474,10 +483,12 @@ jQuery(document).ready(function ($) {
474483
jQuery(checkoutFormIdentifiers).off('checkout_place_order').on('checkout_place_order', async function (e) {
475484
console.debug('PagBank: checkout_place_order');
476485

486+
const cc_payment_token = jQuery('input[name="wc-rm-pagbank-cc-payment-token"]:checked').val();
477487
//if not pagseguro connect or not credit card, return
478488
if ((jQuery('#ps-connect-payment-cc').attr('disabled') !== undefined ||
479489
jQuery('#payment_method_rm-pagbank').is(':checked') === false) &&
480-
jQuery('input[name="payment_method"]:checked').val() !== 'rm-pagbank-cc') //when using standalone methods
490+
jQuery('input[name="payment_method"]:checked').val() !== 'rm-pagbank-cc' ||
491+
(cc_payment_token && cc_payment_token !== 'new')) //when using standalone methods
481492
{
482493
return true;
483494
}
@@ -535,9 +546,25 @@ jQuery(document).ready(function ($) {
535546
jQuery(document).on('input change paste', '#rm-pagbank-card-holder-name', (e)=>{
536547
jQuery(e.target).val(jQuery(e.target).val().toUpperCase());
537548
});
549+
550+
// CPF/CNPJ formatting
551+
jQuery(document).on('input change paste', '#rm-pagbank-card-cpf-cnpj', (e)=>{
552+
let value = jQuery(e.target).val().replace(/[^0-9]/g, '');
553+
let formattedValue = '';
554+
555+
if (value.length <= 11) {
556+
// CPF format: 000.000.000-00
557+
formattedValue = value.replace(/(\d{3})(\d{3})(\d{3})(\d{2})/, '$1.$2.$3-$4');
558+
} else {
559+
// CNPJ format: 00.000.000/0000-00
560+
formattedValue = value.replace(/(\d{2})(\d{3})(\d{3})(\d{4})(\d{2})/, '$1.$2.$3/$4-$5');
561+
}
562+
563+
jQuery(e.target).val(formattedValue);
564+
});
538565
// });
539566

540-
jQuery(document.body).on('update_installments', ()=> {
567+
jQuery(document.body).on('update_installments', (event, selector_installments = '#rm-pagbank-card-installments')=> {
541568
//if success, update the installments select with the response
542569
//if error, show error message
543570
let ccBin = typeof window.ps_cc_bin === 'undefined' || window.ps_cc_bin.replace(/[^0-9]/g, '').length < 6 ? '555566' : window.ps_cc_bin;
@@ -555,7 +582,7 @@ jQuery(document).ready(function ($) {
555582
//convert to cents
556583
let orderTotal = parseFloat(total).toFixed(2) * 100;
557584
if (orderTotal < 100) {
558-
let select = jQuery('#rm-pagbank-card-installments');
585+
let select = jQuery(selector_installments);
559586
select.parent().hide();
560587
return;
561588
}
@@ -573,10 +600,10 @@ jQuery(document).ready(function ($) {
573600
order_id: encryptedOrderId,
574601
},
575602
success: (response)=>{
576-
let select = jQuery('#rm-pagbank-card-installments');
603+
let select = jQuery(selector_installments);
577604
select.empty();
578605
let found = false;
579-
let previouslySelected = window.ps_cc_selected_installment || jQuery('#rm-pagbank-card-installments').val();
606+
let previouslySelected = window.ps_cc_selected_installment || jQuery(selector_installments).val();
580607
for (let i = 0; i < response.length; i++) {
581608
let option = jQuery('<option></option>');
582609
option.attr('value', response[i].installments);
@@ -628,6 +655,22 @@ jQuery(document.body).on('checkout_error', function(event, error_data) {
628655
}
629656
});
630657

631-
jQuery(document).on("change", "#rm-pagbank-card-installments", function () {
658+
jQuery(document).on("change", "#rm-pagbank-card-installments, #rm-pagbank-card-installments-token", function () {
632659
window.ps_cc_selected_installment = jQuery(this).val();
633660
});
661+
662+
jQuery(function($){
663+
function togglePagBankFields() {
664+
var selected = $('input[name="wc-rm-pagbank-cc-payment-token"]:checked').val();
665+
if (selected !== 'new') {
666+
var bin = jQuery(this).data('cc-bin');
667+
if (bin) {
668+
window.ps_cc_bin = bin.toString();
669+
jQuery(document.body).trigger('update_installments', '#rm-pagbank-card-installments-token');
670+
}
671+
}
672+
return selected && selected !== 'new' ? $('#rm-pagbank-installments-token').show() : $('#rm-pagbank-installments-token').hide();
673+
}
674+
$(document).on('change', 'input[name="wc-rm-pagbank-cc-payment-token"]', togglePagBankFields);
675+
togglePagBankFields();
676+
});

0 commit comments

Comments
 (0)