diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index f868de2a..2b94ae0f 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -14,7 +14,7 @@ jobs: name: Lint runs-on: ubuntu-latest container: - image: php:7.2-apache + image: php:7.1-apache steps: - name: Checkout @@ -39,7 +39,11 @@ jobs: php composer.phar --version - name: Check PHP sintax - run: find . -name \*.php -exec php -l "{}" \; + run: | + find . -name \*.php -exec php -l "{}" \; | tee errors.log + if grep -q "Sintax errors:" errors.log; then + exit 1 + fi - name: Install project dependences run: diff --git a/assets/javascripts/front/checkout/checkoutFields.js b/assets/javascripts/front/checkout/checkoutFields.js new file mode 100644 index 00000000..5db98f11 --- /dev/null +++ b/assets/javascripts/front/checkout/checkoutFields.js @@ -0,0 +1,58 @@ +/* globals wc_pagarme_checkout */ +/* jshint esversion: 6 */ +const pagarmeCustomerFields = { + billingDocumentId: 'billing_document', + shippingDocumentId: 'shipping_document', + blocksBillingDocumentId: 'billing-address-document', + blocksShippingDocumentId: 'shipping-address-document', + + documentMasks: [ + '000.000.000-009999', + '00.000.000/0000-00' + ], + documentMaskOptions: { + onKeyPress: function (document, e, field, options) { + const masks = pagarmeCustomerFields.documentMasks, + mask = document.length > 14 ? masks[1] : masks[0]; + field.mask(mask, options); + } + }, + + applyDocumentMask() { + jQuery('#' + this.billingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.shippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.blocksBillingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + jQuery('#' + this.blocksShippingDocumentId).mask(this.documentMasks[0], this.documentMaskOptions); + }, + + addEventListener() { + jQuery(document.body).on('checkout_error', function () { + const documentFieldIds = [ + pagarmeCustomerFields.billingDocumentId, + pagarmeCustomerFields.shippingDocumentId, + pagarmeCustomerFields.blocksBillingDocumentId, + pagarmeCustomerFields.blocksShippingDocumentId + ]; + jQuery.each(documentFieldIds, function () { + const documentField = '#' + this + '_field', + isDocumentEmpty = jQuery('.woocommerce-error li[data-id="' + this + '"]').length, + isDocumentInvalid = jQuery('.woocommerce-error li[data-pagarme-error="' + this + '"]').length; + if (isDocumentEmpty || isDocumentInvalid) { + jQuery(documentField).addClass('woocommerce-invalid'); + } else { + jQuery(documentField).removeClass('woocommerce-invalid'); + } + }); + }); + }, + + start: function () { + this.addEventListener(); + + setTimeout(function() { + pagarmeCustomerFields.applyDocumentMask(); + }, 5000); + } +}; + +pagarmeCustomerFields.start(); diff --git a/assets/javascripts/front/reactCheckout/payments/CreditCard/index.js b/assets/javascripts/front/reactCheckout/payments/CreditCard/index.js index 1d46321f..f52e0b3a 100644 --- a/assets/javascripts/front/reactCheckout/payments/CreditCard/index.js +++ b/assets/javascripts/front/reactCheckout/payments/CreditCard/index.js @@ -2,24 +2,46 @@ const { registerPaymentMethod } = window.wc.wcBlocksRegistry; import PropTypes from "prop-types"; import Card from "../Card"; +import PagarmeGooglePayComponent from "../GooglePay"; import useCreditCard from "./useCreditCard"; +import pagarmeTokenStore from "../store/googlepay"; +import { useSelect } from "@wordpress/data"; const backendConfig = wc.wcSettings.getSetting( "woo-pagarme-payments-credit_card_data", ); +const googlePayBackendConfig = wc.wcSettings.getSetting( + "woo-pagarme-payments-googlepay_data", +); const PagarmeCreditCardComponent = (props) => { + const googleCards = useSelect((select) => { + return select(pagarmeTokenStore).getToken(); + }); const { emitResponse, eventRegistration } = props; - useCreditCard(backendConfig, emitResponse, eventRegistration); + const googleActive = googlePayBackendConfig.enabled; + const hasSubscriptionInCart = googlePayBackendConfig.hasSubscriptionInCart; + useCreditCard(backendConfig, emitResponse, eventRegistration, googleCards); return ( - +
+ {googleActive && !hasSubscriptionInCart && ( +
+ +
+

Ou pague com cartão

+
+
+ )} + {!googleCards && ( + + )} +
); }; const PagarmeCreditCardLabel = ({ components }) => { const { PaymentMethodLabel } = components; - return ; }; diff --git a/assets/javascripts/front/reactCheckout/payments/CreditCard/useCreditCard.js b/assets/javascripts/front/reactCheckout/payments/CreditCard/useCreditCard.js index 8bec6b00..2a039831 100644 --- a/assets/javascripts/front/reactCheckout/payments/CreditCard/useCreditCard.js +++ b/assets/javascripts/front/reactCheckout/payments/CreditCard/useCreditCard.js @@ -4,10 +4,11 @@ import TokenizeException from "../Card/token/tokenizeException"; import tokenizeMultiCards from "../Card/token/tokenizeMultiCards"; import { useDispatch, useSelect } from "@wordpress/data"; import { useEffect } from "@wordpress/element"; +import pagarmeTokenStore from "../store/googlepay"; -const useCreditCard = (backendConfig, emitResponse, eventRegistration) => { +const useCreditCard = (backendConfig, emitResponse, eventRegistration, googleCards) => { const { reset } = useDispatch(pagarmeCardsStore); - + const { reset: resetGoogleToken } = useDispatch(pagarmeTokenStore); const { onPaymentSetup } = eventRegistration; const cards = useSelect((select) => { @@ -21,6 +22,20 @@ const useCreditCard = (backendConfig, emitResponse, eventRegistration) => { useEffect(() => { return onPaymentSetup(async () => { try { + if (googleCards) { + resetGoogleToken(); + return { + type: emitResponse.responseTypes.SUCCESS, + meta: { + paymentMethodData: { + pagarme: JSON.stringify({ + ['googlepay']: {'googlepay': {['payload']: googleCards}} + }), + payment_method: 'googlepay', + }, + }, + }; + } let hasErrors = false; if (typeof cards === 'object') { hasErrors = Object.values(cards).some((card) => { @@ -60,14 +75,13 @@ const useCreditCard = (backendConfig, emitResponse, eventRegistration) => { if (e instanceof TokenizeException) { errorMesage = e.message; } - return { type: emitResponse.responseTypes.ERROR, message: errorMesage, }; } }); - }, [onPaymentSetup, cards, backendConfig]); + }, [onPaymentSetup, cards, backendConfig, googleCards]); }; export default useCreditCard; diff --git a/assets/javascripts/front/reactCheckout/payments/GooglePay/index.js b/assets/javascripts/front/reactCheckout/payments/GooglePay/index.js index c4c7f577..3ccc9756 100644 --- a/assets/javascripts/front/reactCheckout/payments/GooglePay/index.js +++ b/assets/javascripts/front/reactCheckout/payments/GooglePay/index.js @@ -1,26 +1,19 @@ -import PropTypes from "prop-types"; import GooglePayButton from "@google-pay/button-react"; -import useGooglepay from "./useGooglepay"; -import { useDispatch, useSelect } from "@wordpress/data"; +import { useDispatch } from "@wordpress/data"; import pagarmeTokenStore from "../store/googlepay" - -const { registerPaymentMethod } = window.wc.wcBlocksRegistry; - -const backendConfig = wc.wcSettings.getSetting( - "woo-pagarme-payments-googlepay_data", -); - -const environment = backendConfig.isSandboxMode ? "TEST" : "PRODUCTION"; +import validateBilling from "./validateBilling"; const PagarmeGooglePayComponent = (props) => { - const { emitResponse, eventRegistration } = props; - - useGooglepay(emitResponse, eventRegistration, backendConfig); + const backendConfig = wc.wcSettings.getSetting( + "woo-pagarme-payments-googlepay_data", + ); + const environment = backendConfig.isSandboxMode ? "TEST" : "PRODUCTION"; + const billingAddress = props?.billing?.billingAddress; const { setToken } = useDispatch(pagarmeTokenStore); - + return ( { type: "CARD", parameters: { allowedAuthMethods: ["PAN_ONLY"], - allowedCardNetworks: ["MASTERCARD", "VISA", "ELO"], + allowedCardNetworks: backendConfig.allowedGoogleBrands, }, tokenizationSpecification: { type: "PAYMENT_GATEWAY", @@ -59,37 +52,14 @@ const PagarmeGooglePayComponent = (props) => { }, }} onLoadPaymentData={(paymentRequest) => { - let googleToken = paymentRequest.paymentMethodData.tokenizationData.token; - setToken(googleToken); + if(validateBilling(billingAddress)) { + let googleToken = paymentRequest.paymentMethodData.tokenizationData.token; + setToken(googleToken); + } jQuery(".wc-block-components-checkout-place-order-button").click(); }} /> ); }; - -const PagarmeGooglePayLabel = ({ components }) => { - const { PaymentMethodLabel } = components; - return ; -}; - -PagarmeGooglePayComponent.propTypes = { - emitResponse: PropTypes.object, - eventRegistration: PropTypes.object, -}; - -PagarmeGooglePayLabel.propTypes = { - components: PropTypes.object, -}; - - -const pagarmeGooglePayPaymentMethod = { - name: backendConfig.name, - label: , - content: , - edit: , - canMakePayment: () => true, - ariaLabel: backendConfig.ariaLabel, -}; - -registerPaymentMethod(pagarmeGooglePayPaymentMethod); +export default PagarmeGooglePayComponent; \ No newline at end of file diff --git a/assets/javascripts/front/reactCheckout/payments/GooglePay/useGooglepay.js b/assets/javascripts/front/reactCheckout/payments/GooglePay/useGooglepay.js deleted file mode 100644 index 95b9a615..00000000 --- a/assets/javascripts/front/reactCheckout/payments/GooglePay/useGooglepay.js +++ /dev/null @@ -1,39 +0,0 @@ -/* jshint esversion: 9 */ -import pagarmeTokenStore from "../store/googlepay"; -import { useEffect } from "@wordpress/element"; -import { useDispatch, useSelect } from "@wordpress/data"; - -const useGooglepay = ( - emitResponse, - eventRegistration, - backendConfig -) => { - const { reset } = useDispatch(pagarmeTokenStore); - - const { onPaymentSetup } = eventRegistration; - - const cards = useSelect((select) => { - return select(pagarmeTokenStore).getToken(); - }); - - useEffect(() => { - return onPaymentSetup(() => { - const paymentMethodData = { - payment_method: backendConfig.key, - }; - - return { - type: emitResponse.responseTypes.SUCCESS, - meta: { - paymentMethodData: { - pagarme: JSON.stringify({ - [backendConfig.key]: {[backendConfig.key]: {['payload']: cards}} - }), - payment_method: backendConfig.key, - }, - }, - }; - }); - }, [onPaymentSetup, cards, backendConfig]); -}; -export default useGooglepay; diff --git a/assets/javascripts/front/reactCheckout/payments/GooglePay/validateBilling.js b/assets/javascripts/front/reactCheckout/payments/GooglePay/validateBilling.js new file mode 100644 index 00000000..873ba2e5 --- /dev/null +++ b/assets/javascripts/front/reactCheckout/payments/GooglePay/validateBilling.js @@ -0,0 +1,23 @@ + +function validateBilling(billing) { + + const requiredFields = [ + 'first_name', + 'last_name', + 'email', + 'phone', + 'address_1', + 'city', + 'postcode', + 'state', + 'country' + ]; + for (const field of requiredFields) { + if (!billing[field]) { + return false; + } + } + return true; +} + +export default validateBilling; \ No newline at end of file diff --git a/assets/javascripts/front/reactCheckout/payments/store/googlepay.js b/assets/javascripts/front/reactCheckout/payments/store/googlepay.js index 15b9996c..7d35d4a4 100644 --- a/assets/javascripts/front/reactCheckout/payments/store/googlepay.js +++ b/assets/javascripts/front/reactCheckout/payments/store/googlepay.js @@ -38,13 +38,12 @@ const pagarmeTokenStore = createReduxStore("pagarme-googlepay", { reducer(state = DEFAULT_STATE, action) { switch (action.type) { case "SET_PROPERTY_VALUE": - // console.log(action); if (!action.propertyName) { return state; } return { ...state, - [action.propertyName]: action.value, + [action.propertyName]: action.value }; case "RESET": return DEFAULT_STATE; diff --git a/assets/stylesheets/front/style.css b/assets/stylesheets/front/style.css index f6bbd4c3..900e1b24 100644 --- a/assets/stylesheets/front/style.css +++ b/assets/stylesheets/front/style.css @@ -94,26 +94,27 @@ font-style: italic; } -#payment .pagarme_creditcard_divider { +.pagarme_creditcard_divider{ margin: 1em 0 0; } -#payment .pagarme_creditcard_divider p { +.pagarme_creditcard_divider p { display: flex; flex-direction: row; } -#payment .pagarme_creditcard_divider p:after , -#payment .pagarme_creditcard_divider p:before { +.pagarme_creditcard_divider p:after, +.pagarme_creditcard_divider p:before { content: ""; flex: 1 1; border-bottom: 1px solid; margin: auto; } -#payment .pagarme_creditcard_divider p:after { +.pagarme_creditcard_divider p:after { margin-left: 0.5em; } -#payment .pagarme_creditcard_divider p:before { + +.pagarme_creditcard_divider p:before { margin-right: 0.5em; } diff --git a/build/credit_card.asset.php b/build/credit_card.asset.php index 1b7a08af..4390e935 100644 --- a/build/credit_card.asset.php +++ b/build/credit_card.asset.php @@ -1 +1 @@ - array('react', 'react-dom', 'wp-data', 'wp-element'), 'version' => '568464aca724c57656dd'); + array('react', 'react-dom', 'wp-data', 'wp-element'), 'version' => '4df6da733d92f5ffc390'); diff --git a/build/credit_card.js b/build/credit_card.js index 7adc2ef7..0b132abb 100644 --- a/build/credit_card.js +++ b/build/credit_card.js @@ -1 +1 @@ -(()=>{var e={694:(e,t,n)=>{"use strict";var r=n(925);function a(){}function s(){}s.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,s,o){if(o!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:s,resetWarningCache:a};return n.PropTypes=n,n}},556:(e,t,n)=>{e.exports=n(694)()},925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},844:(e,t,n)=>{e.exports=n(200)},200:(e,t,n)=>{"use strict";var r,a=(r=n(609))&&"object"==typeof r&&"default"in r?r.default:r,s=n(795);function o(){return(o=Object.assign||function(e){for(var t=1;tr.length&&p(e,t.length-1);)t=t.slice(0,t.length-1);return t.length}for(var a=r.length,s=t.length;s>=r.length;s--){var o=t[s];if(!p(e,s)&&m(e,s,o)){a=s+1;break}}return a}function h(e,t){return f(e,t)===e.mask.length}function g(e,t){var n=e.maskChar,r=e.mask,a=e.prefix;if(!n){for((t=b(e,"",t,0)).lengtht.length&&(t+=a.slice(t.length,r)),l.every((function(n){for(;c=n,p(e,u=r)&&c!==a[u];){if(r>=t.length&&(t+=a[r]),l=n,s&&p(e,r)&&l===s)return!0;if(++r>=a.length)return!1}var l,u,c;return!m(e,r,n)&&n!==s||(ra.start?d=(c=function(e,t,n,r){var a=e.mask,s=e.maskChar,o=n.split(""),l=r;return o.every((function(t){for(;o=t,p(e,n=r)&&o!==a[n];)if(++r>=a.length)return!1;var n,o;return(m(e,r,t)||t===s)&&r++,r=s.length?v=s.length:v=o.length&&v{"use strict";e.exports=window.React},795:e=>{"use strict";e.exports=window.ReactDOM}},t={};function n(r){var a=t[r];if(void 0!==a)return a.exports;var s=t[r]={exports:{}};return e[r](s,s.exports,n),s.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";function e(){return e=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const o=s(a),l=s(t);return 1===n?`${e} (${o})`:`${n}x ${e} ${o} (${l}) ${r}`.trim()},l=e=>e.map((e=>({label:o(e),value:e.value}))),i=(e,n,r,a,s,o,i)=>{const[u,c]=(0,t.useState)(l(e)),d=(e=>{const n=(0,t.useRef)();return(0,t.useEffect)((()=>{n.current=e})),n.current})(a);return(0,t.useEffect)((()=>{(async()=>{if(2===n&&!r||1===n&&(!d||d===a))return;o(!0);const e=parseFloat(a/100).toFixed(2).replace(".",",");try{const t=await fetch("/wp-admin/admin-ajax.php?"+new URLSearchParams({action:"xqRhBHJ5sW",flag:r,total:e}),{headers:{"X-Request-Type":"Ajax"}});if(!t.ok)return void o(!1);const n=await t.json();if(!n?.installments?.length)return void o(!1);c(l(n.installments)),s(i,1),o(!1)}catch(e){return void o(!1)}})()}),[r,a,n,c,l,s,i]),(0,t.useEffect)((()=>{2===n&&c([{label:"...",value:""}])}),[n,c]),{installmentsOptions:u,filterHandler:e=>{u.filter((t=>t.label.toLowerCase().startsWith(e.toLowerCase())))},installmentsChangeHandler:e=>{s(i,e)}}},{ComboboxControl:u}=wp.components,c=({label:e,installments:n,installmentsType:r,selectedInstallment:a,setSelectedInstallment:s,brand:o,cartTotal:l,setIsLoading:c,cardIndex:d})=>{const{installmentsOptions:p,filterHandler:m,installmentsChangeHandler:v}=i(n,r,o,l,s,c,d);return(0,t.createElement)("div",{className:"wc-block-components-select-input pagarme-installments-combobox"},(0,t.createElement)("div",{className:"wc-block-components-combobox is-active"},(0,t.createElement)(u,{className:"wc-block-components-combobox-control",label:e,onChange:v,value:a,options:p,onFilterValueChange:m,allowReset:!1,autoComplete:"off"})))};c.propTypes={label:a().string.isRequired,installments:a().array.isRequired,installmentsType:a().number.isRequired,selectedInstallment:a().oneOfType([a().string,a().number]).isRequired,setSelectedInstallment:a().func.isRequired,brand:a().string.isRequired,cartTotal:a().number.isRequired,setIsLoading:a().func.isRequired,cardIndex:a().number.isRequired};const d=c;function p(e){return e.replace(/\s/g,"").split("/")}const m=(e,t,n,r)=>{const a=(e,t)=>(delete t.inputHolderName,e.length>0||(t.inputHolderName=r.holderName),t),s=(e,t)=>(delete t.inputNumber,16===(e=e.replace(/(\D)/g,"")).length||(t.inputNumber=r.cardNumber),t),o=(e,t)=>{if(delete t.inputExpiry,0===e.length)return t.inputExpiry=r.emptyExpiry,t;const[n,a]=p(e),s=new Date(`20${a}`,n-1);let o=new Date;return o=new Date(o.getFullYear(),o.getMonth()),n>=1&&n<=12||(t.inputExpiry=r.invalidExpiryMonth),!a.includes("_")||(t.inputExpiry=r.invalidExpiryYear),s(delete t.inputCvv,0===(e=e.replace(/(\D)/g,"")).length?(t.inputCvv=r.emptyCvv,t):(3===e.length||4===e.length||(t.inputCvv=r.invalidCvv),t));return{validateInputHolderName:r=>{const s=a(r,t);return n(e,{...s}),!!s.inputHolderName},validateInputNumber:r=>{const a=s(r,t);return n(e,{...a}),!!a.inputNumber},validateInputExpiry:r=>{const a=o(r,t);return n(e,{...a}),!!a.inputExpiry},validateInputCvv:r=>{const a=l(r,t);return n(e,{...a}),!!a.inputCvv},validateAllFields:(r,i,u,c)=>{let d={...t};return d=a(r,d),d=s(i,d),d=o(u,d),d=l(c,d),n(e,{...d}),0===Object.keys(d).length}}},v=({id:e,label:n,inputValue:r,setInputValue:a,cardIndex:s,errors:o,setErrors:l,fieldErrors:i})=>{const{setIsActive:u,cssClasses:c,inputChangeHandler:d,inputBlurHandler:p}=((e,n,r,a,s,o)=>{const{validateInputHolderName:l}=m(r,a,s,o);let i="wc-block-components-text-input";const[u,c]=(0,t.useState)(!1);return(u||e.length)&&(i+=" is-active"),a.hasOwnProperty("inputHolderName")&&(i+=" has-error"),{setIsActive:c,cssClasses:i,inputChangeHandler:e=>{const t=e.target.value.replace(/[^a-z ]/gi,"");n(r,t)},inputBlurHandler:e=>{l(e.target.value),c(!1)}}})(r,a,s,o,l,i);return(0,t.createElement)("div",{className:c},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)("input",{type:"text",id:e,value:r,onChange:d,onFocus:()=>u(!0),onBlur:p}),o.inputHolderName&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,o.inputHolderName)))};v.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,cardIndex:a().number.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const f=v;var h=n(844),g=n.n(h);function b(e){return e.replace(/\s|•/g,"")}const E=(e,n,r,a,s,o,l,i,u)=>{const{validateInputNumber:c}=m(o,l,i,u),[d,p]=(0,t.useState)("");let v="wc-block-components-text-input pagarme-credit-card-number-container";const[f,h]=(0,t.useState)(!1);(f||e.length)&&(v+=" is-active"),l.hasOwnProperty("inputNumber")&&(v+=" has-error");const g=()=>{a(o,""),p("")};return{setIsActive:h,cssClasses:v,brandImageSrc:d,inputChangeHandler:e=>{r(o,e.target.value)},inputBlurHandler:t=>{c(t.target.value),(async()=>{const t=b(e);if(16!==t.length)return void g();s(!0);const r=t.substring(0,6),l=`https://api.pagar.me/bin/v1/${r}`;try{const e=await fetch(l),t=await e.json();let i=t.brand;if(e.ok&&void 0!==t.brandName||(i=(e=>{let t="",r=null;for(const[a,s]of Object.entries(n))for(const n of s.prefixes){const s=n.toString();0===e.indexOf(s)&&t.length{const{setIsActive:m,cssClasses:v,brandImageSrc:f,inputChangeHandler:h,inputBlurHandler:b}=E(r,l,a,o,i,u,c,d,p);return(0,t.createElement)("div",{className:v},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)(g(),{className:"pagarme-card-form-card-number",type:"text",id:e,mask:"9999 9999 9999 9999",maskChar:"•",onFocus:()=>m(!0),onChange:h,value:r,onBlur:b}),f&&(0,t.createElement)("img",{src:f,alt:s}),c.inputNumber&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,c.inputNumber)))};C.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,brand:a().string.isRequired,setBrand:a().func.isRequired,brands:a().object.isRequired,setIsLoading:a().func.isRequired,cardIndex:a().number.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const I=C,k=({id:e,label:n,inputValue:r,setInputValue:a,cardIndex:s,validate:o,validateIndex:l,mask:i,maskChar:u=null,errors:c})=>{const{setIsActive:d,cssClasses:p,inputChangeHandler:m,inputBlurHandler:v}=((e,n,r,a,s,o)=>{let l="wc-block-components-text-input";const[i,u]=(0,t.useState)(!1);return(i||e.length)&&(l+=" is-active"),o.hasOwnProperty(s)&&(l+=" has-error"),{setIsActive:u,cssClasses:l,inputChangeHandler:e=>{n(r,e.target.value)},inputBlurHandler:e=>{a(e.target.value),u(!1)}}})(r,a,s,o,l,c);return(0,t.createElement)("div",{className:p},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)(g(),{type:"text",id:e,mask:i,maskChar:u,onChange:m,value:r,onFocus:()=>d(!0),onBlur:v}))};k.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,cardIndex:a().number.isRequired,mask:a().string.isRequired,maskChar:a().string,validate:a().func.isRequired,validateIndex:a().string.isRequired,errors:a().object.isRequired};const w=k,y=({id:e,label:n,cardIndex:r,inputValue:a,setInputValue:s,errors:o,setErrors:l,fieldErrors:i})=>{const{validateInputExpiry:u}=m(r,o,l,i);return(0,t.createElement)(t.Fragment,null,(0,t.createElement)(w,{id:e,label:n,mask:"99/99",maskChar:"_",inputValue:a,setInputValue:s,cardIndex:r,validate:u,validateIndex:"inputExpiry",errors:o}),o.inputExpiry&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,o.inputExpiry)))};y.propTypes={id:a().string.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const R=y,x=({id:e,label:n,cardIndex:r,inputValue:a,setInputValue:s,errors:o,setErrors:l,fieldErrors:i})=>{const{validateInputCvv:u}=m(r,o,l,i);return(0,t.createElement)(t.Fragment,null,(0,t.createElement)(w,{id:e,label:n,mask:"9999",inputValue:a,setInputValue:s,cardIndex:r,validate:u,validateIndex:"inputCvv",errors:o}),o.inputCvv&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,o.inputCvv)))};x.propTypes={id:a().string.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const S=x,{ComboboxControl:O}=wp.components,N=({cards:e,label:n,cardIndex:r,selectedCard:a,setSelectCard:s,setBrand:o})=>{const{filterHandler:l,cardChangeHandler:i}=((e,t,n,r)=>({filterHandler:t=>{e.filter((e=>e.label.toLowerCase().startsWith(t.toLowerCase())))},cardChangeHandler:a=>{if(n(t,a),!e)return;const s=e.find((e=>e.value===a));r(t,s?s.brand:"")}}))(e,r,s,o);return(0,t.createElement)("div",{className:"wc-block-components-select-input pagarme-installments-combobox"},(0,t.createElement)("div",{className:"wc-block-components-combobox is-active"},(0,t.createElement)(O,{className:"wc-block-components-combobox-control",label:n,onChange:i,value:a,options:e,onFilterValueChange:l,allowReset:!1,autoComplete:"off"})))};N.propTypes={cards:a().array.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,selectedCard:a().string.isRequired,setSelectCard:a().func.isRequired,setBrand:a().func.isRequired};const V=N,q=window.wp.data,T={holderName:"",number:"",expirationDate:"",installment:1,brand:"",cvv:"",saveCard:!1,walletId:"",errors:{}},P={cards:{1:{...T},2:{...T}}},D=(0,q.createReduxStore)("pagarme-cards",{reducer(e=P,t){switch(t.type){case"SET_PROPERTY_VALUE":return 0===t.propertyName?.length?e:{...e,cards:{...e.cards,[t.cardIndex]:{...e.cards[t.cardIndex],[t.propertyName]:t.value}}};case"RESET":return P}return e},actions:{setHolderName:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"holderName"}),setNumber:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"number"}),setExpirationDate:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"expirationDate"}),setInstallment:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"installment"}),setBrand:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"brand"}),setCvv:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"cvv"}),setSaveCard:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"saveCard"}),setWalletId:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"walletId"}),setErrors:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"errors"}),reset:()=>({type:"RESET"})},selectors:{getHolderName:(e,t)=>e.cards[t].holderName,getNumber:(e,t)=>e.cards[t].number,getExpirationDate:(e,t)=>e.cards[t].expirationDate,getInstallment:(e,t)=>e.cards[t].installment,getBrand:(e,t)=>e.cards[t].brand,getCvv:(e,t)=>e.cards[t].cvv,getSaveCard:(e,t)=>e.cards[t].saveCard,getWalletId:(e,t)=>e.cards[t].walletId,getCards:e=>e.cards,getErrors:(e,t)=>e.cards[t].errors}});(0,q.register)(D);const L=D,{CheckboxControl:M}=window.wc.blocksComponents,_=({billing:e,components:n,backendConfig:r,cardIndex:a,eventRegistration:s})=>{const{LoadingMask:o}=n,{holderNameLabel:l,numberLabel:i,expiryLabel:u,cvvLabel:c,installmentsLabel:p,saveCardLabel:v,walletLabel:h}=r.fieldsLabels,{isLoading:g,setIsLoading:b,setHolderName:E,setNumber:C,setExpirationDate:k,setInstallment:w,setBrand:y,setCvv:x,setWalletId:O,setErrors:N,saveCardChangeHandler:T,formatFieldId:P,holderName:D,number:_,expirationDate:j,selectedInstallment:H,brand:B,cvv:F,saveCard:A,walletId:U,errors:Y}=((e,n,r)=>{const[a,s]=(0,t.useState)(!1),{setHolderName:o,setNumber:l,setExpirationDate:i,setInstallment:u,setBrand:c,setCvv:d,setSaveCard:p,setWalletId:v,setErrors:f}=(0,q.useDispatch)(L),h=(0,q.useSelect)((t=>t(L).getHolderName(e)),[e]),g=(0,q.useSelect)((t=>t(L).getNumber(e)),[e]),b=(0,q.useSelect)((t=>t(L).getExpirationDate(e)),[e]),E=(0,q.useSelect)((t=>t(L).getInstallment(e)),[e]),C=(0,q.useSelect)((t=>t(L).getBrand(e)),[e]),I=(0,q.useSelect)((t=>t(L).getCvv(e)),[e]),k=(0,q.useSelect)((t=>t(L).getSaveCard(e)),[e]),w=(0,q.useSelect)((t=>t(L).getWalletId(e)),[e]),y=(0,q.useSelect)((t=>t(L).getErrors(e)),[e]),{validateAllFields:R}=m(e,y,f,r.fieldErrors),{onCheckoutValidation:x}=n;return(0,t.useEffect)((()=>x((()=>(0===w.length&&R(h,g,b,I),!0)))),[x,h,g,b,I,r,w]),{isLoading:a,setIsLoading:s,setHolderName:o,setNumber:l,setExpirationDate:i,setInstallment:u,setBrand:c,setCvv:d,setWalletId:v,setErrors:f,saveCardChangeHandler:t=>{p(e,t)},formatFieldId:t=>`pagarme_credit_card_${e}_${t}`,holderName:h,number:g,expirationDate:b,selectedInstallment:E,brand:C,cvv:I,saveCard:k,walletId:w,errors:y}})(a,s,r);return(0,t.createElement)(o,{isLoading:g},(0,t.createElement)("div",{className:"wc-block-components-form"},r?.walletEnabled&&r?.cards?.length>0&&(0,t.createElement)(V,{label:h,selectedCard:U,cards:r.cards,cardIndex:a,setSelectCard:O,setBrand:y}),0===U.length&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(f,{id:P("holder_name"),label:l,inputValue:D,setInputValue:E,cardIndex:a,errors:Y,setErrors:N,fieldErrors:r?.fieldErrors}),(0,t.createElement)(I,{id:P("number"),label:i,inputValue:_,setInputValue:C,brand:B,setBrand:y,brands:r?.brands,setIsLoading:b,cardIndex:a,errors:Y,setErrors:N,fieldErrors:r?.fieldErrors}),(0,t.createElement)(R,{id:P("expiry"),label:u,inputValue:j,setInputValue:k,cardIndex:a,errors:Y,setErrors:N,fieldErrors:r?.fieldErrors}),(0,t.createElement)(S,{id:P("cvv"),label:c,inputValue:F,setInputValue:x,cardIndex:a,errors:Y,setErrors:N,fieldErrors:r?.fieldErrors})),(0,t.createElement)(d,{label:p,installments:r?.installments,installmentsType:r?.installmentsType,selectedInstallment:H,setSelectedInstallment:w,brand:B,cartTotal:e.cartTotal.value,setIsLoading:b,cardIndex:a}),0===U.length&&r?.walletEnabled&&(0,t.createElement)(M,{label:v,checked:A,onChange:T})))};_.propType={billing:a().object.isRequired,components:a().object.isRequired,backendConfig:a().object.isRequired,cardIndex:a().number.isRequired,eventRegistration:a().object.isRequired};const j=_;class H extends Error{constructor(e){super(e),this.name=this.constructor.name}}const B=(e,t,n)=>{const r=`${e.replace("request.","").replace("card.","")}: ${t}`;return n.hasOwnProperty(r)?n[r]:""};async function F(e,t,n,r,a,s){const[o,l]=p(n),i={card:{holder_name:t,number:b(e),exp_month:o,exp_year:l,cvv:r}};try{const e=`https://api.pagar.me/core/v5/tokens?appId=${a}`,t=await fetch(e,{method:"POST",body:JSON.stringify(i)});if(!t.ok){const e=await t.text();if(0===e.length)return{errorMessage:s.serviceUnavailable};const n=((e,t)=>{let n="";for(const r in e.errors)for(const a of e.errors[r]||[]){const e=B(r,a,t);0!==e.length&&(n+=`${e}
`)}return n})(JSON.parse(e),s);return{errorMessage:n}}return{token:(await t.json()).id}}catch(e){return{errorMessage:s.serviceUnavailable}}}const A=(e,n,r)=>{const{reset:a}=(0,q.useDispatch)(L),{onPaymentSetup:s}=r,o=(0,q.useSelect)((e=>e(L).getCards()));(0,t.useEffect)((()=>{a()}),[]),(0,t.useEffect)((()=>s((async()=>{try{let t=!1;if("object"==typeof o&&(t=Object.values(o).some((e=>Object.keys(e.errors).length>0))),t)return{type:n.responseTypes.ERROR,message:e.errorMessages.creditCardFormHasErrors};const r=await(async(e,t,n)=>{const r=[];for(let a=1;a0){r[a]={"wallet-id":d,brand:i,installment:u};continue}const p=await F(s,t,o,l,n.appId,n.errorMessages);if(p.errorMessage)throw new H(p.errorMessage);r[a]={token:p.token,brand:i,installment:u},c&&(r[a]["save-card"]=c)}return r})(o,1,e);return{type:n.responseTypes.SUCCESS,meta:{paymentMethodData:{pagarme:JSON.stringify({[e.key]:{cards:{...r}}}),payment_method:e.key}}}}catch(t){let r=e.errorMessages.serviceUnavailable;return t instanceof H&&(r=t.message),{type:n.responseTypes.ERROR,message:r}}}))),[s,o,e])},{registerPaymentMethod:U}=window.wc.wcBlocksRegistry,Y=wc.wcSettings.getSetting("woo-pagarme-payments-credit_card_data"),$=n=>{const{emitResponse:r,eventRegistration:a}=n;return A(Y,r,a),(0,t.createElement)(j,e({},n,{backendConfig:Y,cardIndex:1}))},W=({components:e})=>{const{PaymentMethodLabel:n}=e;return(0,t.createElement)(n,{text:Y.label})};$.propTypes={emitResponse:a().object,eventRegistration:a().object},W.propTypes={components:a().object},U({name:Y.name,label:(0,t.createElement)(W,null),content:(0,t.createElement)($,null),edit:(0,t.createElement)($,null),canMakePayment:()=>!0,ariaLabel:Y.ariaLabel})})()})(); \ No newline at end of file +(()=>{var e={21:function(e,t,n){e.exports=function(e){"use strict";var t=function(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}(e);function r(e,t,n,r){return new(n||(n=Promise))((function(a,o){function s(e){try{l(r.next(e))}catch(e){o(e)}}function i(e){try{l(r.throw(e))}catch(e){o(e)}}function l(e){var t;e.done?a(e.value):(t=e.value,t instanceof n?t:new n((function(e){e(t)}))).then(s,i)}l((r=r.apply(e,t||[])).next())}))}let a={};class o{constructor(e){this.handleClick=e=>r(this,void 0,void 0,(function*(){const t=this.config;if(!t)throw new Error("google-pay-button: Missing configuration");const n=this.createLoadPaymentDataRequest(t);try{if(t.onClick&&t.onClick(e),e.defaultPrevented)return;const r=yield this.client.loadPaymentData(n);t.onLoadPaymentData&&t.onLoadPaymentData(r)}catch(e){"CANCELED"===e.statusCode?t.onCancel&&t.onCancel(e):t.onError?t.onError(e):console.error(e)}})),this.options=e}getElement(){return this.element}isGooglePayLoaded(){var e,t;return"google"in(window||n.g)&&!!(null===(t=null===(e=null===google||void 0===google?void 0:google.payments)||void 0===e?void 0:e.api)||void 0===t?void 0:t.PaymentsClient)}mount(e){var t;return r(this,void 0,void 0,(function*(){if(!this.isGooglePayLoaded())try{yield function(e){const t=a[e];if(t)return t;const n=new Promise(((t,n)=>{const r=document.createElement("script");r.src=e,r.async=!0;const o=()=>{t()},s=()=>{r.removeEventListener("load",o),r.removeEventListener("error",s),delete a[e],r.remove(),n(new Error(`Unable to load script ${e}`))};r.addEventListener("load",o),r.addEventListener("error",s),document.body.appendChild(r)}));return a[e]=n,n}("https://pay.google.com/gp/p/js/pay.js")}catch(e){return void((null===(t=this.config)||void 0===t?void 0:t.onError)?this.config.onError(e):console.error(e))}this.element=e,e&&(this.appendStyles(),this.config&&this.updateElement())}))}unmount(){this.element=void 0}configure(e){let t;return this.config=e,this.oldInvalidationValues&&!this.isClientInvalidated(e)||(t=this.updateElement()),this.oldInvalidationValues=this.getInvalidationValues(e),null!=t?t:Promise.resolve()}createClientOptions(e){const t={environment:e.environment,merchantInfo:this.createMerchantInfo(e)};return(e.onPaymentDataChanged||e.onPaymentAuthorized)&&(t.paymentDataCallbacks={},e.onPaymentDataChanged&&(t.paymentDataCallbacks.onPaymentDataChanged=t=>e.onPaymentDataChanged(t)||{}),e.onPaymentAuthorized&&(t.paymentDataCallbacks.onPaymentAuthorized=t=>e.onPaymentAuthorized(t)||{})),t}createIsReadyToPayRequest(e){const t=e.paymentRequest;return{apiVersion:t.apiVersion,apiVersionMinor:t.apiVersionMinor,allowedPaymentMethods:t.allowedPaymentMethods,existingPaymentMethodRequired:e.existingPaymentMethodRequired}}createLoadPaymentDataRequest(e){return Object.assign(Object.assign({},e.paymentRequest),{merchantInfo:this.createMerchantInfo(e)})}createMerchantInfo(e){const t=Object.assign({},e.paymentRequest.merchantInfo);return t.softwareInfo||(t.softwareInfo={id:this.options.softwareInfoId,version:this.options.softwareInfoVersion}),t}isMounted(){return null!=this.element&&!1!==this.element.isConnected}removeButton(){if(this.element instanceof ShadowRoot||this.element instanceof Element)for(const e of Array.from(this.element.children))"STYLE"!==e.tagName&&e.remove()}updateElement(){return r(this,void 0,void 0,(function*(){if(!this.isMounted())return;const e=this.getElement();if(!this.config)throw new Error("google-pay-button: Missing configuration");this.removeButton();try{this.client=new google.payments.api.PaymentsClient(this.createClientOptions(this.config))}catch(e){return void(this.config.onError?this.config.onError(e):console.error(e))}const t={buttonType:this.config.buttonType,buttonColor:this.config.buttonColor,buttonRadius:this.config.buttonRadius,buttonSizeMode:this.config.buttonSizeMode,buttonLocale:this.config.buttonLocale,onClick:this.handleClick,allowedPaymentMethods:this.config.paymentRequest.allowedPaymentMethods},n=e.getRootNode();n instanceof ShadowRoot&&(t.buttonRootNode=n);const r=this.client.createButton(t);this.setClassName(e,[e.className,"not-ready"]),e.appendChild(r);let a,o=!1;try{a=yield this.client.isReadyToPay(this.createIsReadyToPayRequest(this.config)),o=a.result&&!this.config.existingPaymentMethodRequired||a.result&&a.paymentMethodPresent&&this.config.existingPaymentMethodRequired||!1}catch(e){this.config.onError?this.config.onError(e):console.error(e)}if(this.isMounted()){if(o){try{this.client.prefetchPaymentData(this.createLoadPaymentDataRequest(this.config))}catch(e){console.log("Error with prefetch",e)}this.setClassName(e,(e.className||"").split(" ").filter((e=>e&&"not-ready"!==e)))}if((this.isReadyToPay!==(null==a?void 0:a.result)||this.paymentMethodPresent!==(null==a?void 0:a.paymentMethodPresent))&&(this.isReadyToPay=!!(null==a?void 0:a.result),this.paymentMethodPresent=null==a?void 0:a.paymentMethodPresent,this.config.onReadyToPayChange)){const e={isButtonVisible:o,isReadyToPay:this.isReadyToPay};this.paymentMethodPresent&&(e.paymentMethodPresent=this.paymentMethodPresent),this.config.onReadyToPayChange(e)}}}))}setClassName(e,t){const n=t.filter((e=>e)).join(" ");n?e.className=n:e.removeAttribute("class")}appendStyles(){var e,t,n;if("undefined"==typeof document)return;const r=null===(e=this.element)||void 0===e?void 0:e.getRootNode(),a=`default-google-style-${this.options.cssSelector.replace(/[^\w-]+/g,"")}-${null===(t=this.config)||void 0===t?void 0:t.buttonLocale}`;if(r&&!(null===(n=r.getElementById)||void 0===n?void 0:n.call(r,a))){const e=document.createElement("style");e.id=a,e.type="text/css",e.innerHTML=`\n ${this.options.cssSelector} {\n display: inline-block;\n }\n ${this.options.cssSelector}.not-ready {\n width: 0;\n height: 0;\n overflow: hidden;\n }\n `,r instanceof Document&&r.head?r.head.appendChild(e):r.appendChild(e)}}isClientInvalidated(e){return!this.oldInvalidationValues||this.getInvalidationValues(e).some(((e,t)=>JSON.stringify(e)!==JSON.stringify(this.oldInvalidationValues[t])))}getInvalidationValues(e){var t,n;return[e.environment,e.existingPaymentMethodRequired,!!e.onPaymentDataChanged,!!e.onPaymentAuthorized,e.buttonType,e.buttonColor,e.buttonRadius,e.buttonLocale,e.buttonSizeMode,e.paymentRequest.merchantInfo.merchantId,e.paymentRequest.merchantInfo.merchantName,null===(t=e.paymentRequest.merchantInfo.softwareInfo)||void 0===t?void 0:t.id,null===(n=e.paymentRequest.merchantInfo.softwareInfo)||void 0===n?void 0:n.version,e.paymentRequest.allowedPaymentMethods]}}const s="google-pay-button-container";class i extends t.default.Component{constructor(){super(...arguments),this.manager=new o({cssSelector:`.${s}`,softwareInfoId:"@google-pay/button-react",softwareInfoVersion:"3.1.0"}),this.elementRef=t.default.createRef()}componentDidMount(){return r(this,void 0,void 0,(function*(){const e=this.elementRef.current;e&&(yield this.manager.configure(this.props),yield this.manager.mount(e))}))}componentWillUnmount(){this.manager.unmount()}componentDidUpdate(){this.manager.configure(this.props)}render(){return t.default.createElement("div",{ref:this.elementRef,className:[s,this.props.className].filter((e=>e)).join(" "),style:this.props.style})}}return i}(n(609))},694:(e,t,n)=>{"use strict";var r=n(925);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,s){if(s!==r){var i=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw i.name="Invariant Violation",i}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},556:(e,t,n)=>{e.exports=n(694)()},925:e=>{"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},844:(e,t,n)=>{e.exports=n(200)},200:(e,t,n)=>{"use strict";var r,a=(r=n(609))&&"object"==typeof r&&"default"in r?r.default:r,o=n(795);function s(){return(s=Object.assign||function(e){for(var t=1;tr.length&&p(e,t.length-1);)t=t.slice(0,t.length-1);return t.length}for(var a=r.length,o=t.length;o>=r.length;o--){var s=t[o];if(!p(e,o)&&m(e,o,s)){a=o+1;break}}return a}function g(e,t){return f(e,t)===e.mask.length}function v(e,t){var n=e.maskChar,r=e.mask,a=e.prefix;if(!n){for((t=y(e,"",t,0)).lengtht.length&&(t+=a.slice(t.length,r)),i.every((function(n){for(;c=n,p(e,u=r)&&c!==a[u];){if(r>=t.length&&(t+=a[r]),i=n,o&&p(e,r)&&i===o)return!0;if(++r>=a.length)return!1}var i,u,c;return!m(e,r,n)&&n!==o||(ra.start?d=(c=function(e,t,n,r){var a=e.mask,o=e.maskChar,s=n.split(""),i=r;return s.every((function(t){for(;s=t,p(e,n=r)&&s!==a[n];)if(++r>=a.length)return!1;var n,s;return(m(e,r,t)||t===o)&&r++,r=o.length?h=o.length:h=s.length&&h{"use strict";e.exports=window.React},795:e=>{"use strict";e.exports=window.ReactDOM}},t={};function n(r){var a=t[r];if(void 0!==a)return a.exports;var o=t[r]={exports:{}};return e[r].call(o.exports,o,o.exports,n),o.exports}n.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return n.d(t,{a:t}),t},n.d=(e,t)=>{for(var r in t)n.o(t,r)&&!n.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),n.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),(()=>{"use strict";function e(){return e=Object.assign?Object.assign.bind():function(e){for(var t=1;t{const s=o(a),i=o(t);return 1===n?`${e} (${s})`:`${n}x ${e} ${s} (${i}) ${r}`.trim()},i=e=>e.map((e=>({label:s(e),value:e.value}))),l=(e,n,r,a,o,s,l)=>{const[u,c]=(0,t.useState)(i(e)),d=(e=>{const n=(0,t.useRef)();return(0,t.useEffect)((()=>{n.current=e})),n.current})(a);return(0,t.useEffect)((()=>{(async()=>{if(2===n&&!r||1===n&&(!d||d===a))return;s(!0);const e=parseFloat(a/100).toFixed(2).replace(".",",");try{const t=await fetch("/wp-admin/admin-ajax.php?"+new URLSearchParams({action:"xqRhBHJ5sW",flag:r,total:e}),{headers:{"X-Request-Type":"Ajax"}});if(!t.ok)return void s(!1);const n=await t.json();if(!n?.installments?.length)return void s(!1);c(i(n.installments)),o(l,1),s(!1)}catch(e){return void s(!1)}})()}),[r,a,n,c,i,o,l]),(0,t.useEffect)((()=>{2===n&&c([{label:"...",value:""}])}),[n,c]),{installmentsOptions:u,filterHandler:e=>{u.filter((t=>t.label.toLowerCase().startsWith(e.toLowerCase())))},installmentsChangeHandler:e=>{o(l,e)}}},{ComboboxControl:u}=wp.components,c=({label:e,installments:n,installmentsType:r,selectedInstallment:a,setSelectedInstallment:o,brand:s,cartTotal:i,setIsLoading:c,cardIndex:d})=>{const{installmentsOptions:p,filterHandler:m,installmentsChangeHandler:h}=l(n,r,s,i,o,c,d);return(0,t.createElement)("div",{className:"wc-block-components-select-input pagarme-installments-combobox"},(0,t.createElement)("div",{className:"wc-block-components-combobox is-active"},(0,t.createElement)(u,{className:"wc-block-components-combobox-control",label:e,onChange:h,value:a,options:p,onFilterValueChange:m,allowReset:!1,autoComplete:"off"})))};c.propTypes={label:a().string.isRequired,installments:a().array.isRequired,installmentsType:a().number.isRequired,selectedInstallment:a().oneOfType([a().string,a().number]).isRequired,setSelectedInstallment:a().func.isRequired,brand:a().string.isRequired,cartTotal:a().number.isRequired,setIsLoading:a().func.isRequired,cardIndex:a().number.isRequired};const d=c;function p(e){return e.replace(/\s/g,"").split("/")}const m=(e,t,n,r)=>{const a=(e,t)=>(delete t.inputHolderName,e.length>0||(t.inputHolderName=r.holderName),t),o=(e,t)=>(delete t.inputNumber,16===(e=e.replace(/(\D)/g,"")).length||(t.inputNumber=r.cardNumber),t),s=(e,t)=>{if(delete t.inputExpiry,0===e.length)return t.inputExpiry=r.emptyExpiry,t;const[n,a]=p(e),o=new Date(`20${a}`,n-1);let s=new Date;return s=new Date(s.getFullYear(),s.getMonth()),n>=1&&n<=12||(t.inputExpiry=r.invalidExpiryMonth),!a.includes("_")||(t.inputExpiry=r.invalidExpiryYear),o(delete t.inputCvv,0===(e=e.replace(/(\D)/g,"")).length?(t.inputCvv=r.emptyCvv,t):(3===e.length||4===e.length||(t.inputCvv=r.invalidCvv),t));return{validateInputHolderName:r=>{const o=a(r,t);return n(e,{...o}),!!o.inputHolderName},validateInputNumber:r=>{const a=o(r,t);return n(e,{...a}),!!a.inputNumber},validateInputExpiry:r=>{const a=s(r,t);return n(e,{...a}),!!a.inputExpiry},validateInputCvv:r=>{const a=i(r,t);return n(e,{...a}),!!a.inputCvv},validateAllFields:(r,l,u,c)=>{let d={...t};return d=a(r,d),d=o(l,d),d=s(u,d),d=i(c,d),n(e,{...d}),0===Object.keys(d).length}}},h=({id:e,label:n,inputValue:r,setInputValue:a,cardIndex:o,errors:s,setErrors:i,fieldErrors:l})=>{const{setIsActive:u,cssClasses:c,inputChangeHandler:d,inputBlurHandler:p}=((e,n,r,a,o,s)=>{const{validateInputHolderName:i}=m(r,a,o,s);let l="wc-block-components-text-input";const[u,c]=(0,t.useState)(!1);return(u||e.length)&&(l+=" is-active"),a.hasOwnProperty("inputHolderName")&&(l+=" has-error"),{setIsActive:c,cssClasses:l,inputChangeHandler:e=>{const t=e.target.value.replace(/[^a-z ]/gi,"");n(r,t)},inputBlurHandler:e=>{i(e.target.value),c(!1)}}})(r,a,o,s,i,l);return(0,t.createElement)("div",{className:c},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)("input",{type:"text",id:e,value:r,onChange:d,onFocus:()=>u(!0),onBlur:p}),s.inputHolderName&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,s.inputHolderName)))};h.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,cardIndex:a().number.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const f=h;var g=n(844),v=n.n(g);function y(e){return e.replace(/\s|•/g,"")}const b=(e,n,r,a,o,s,i,l,u)=>{const{validateInputNumber:c}=m(s,i,l,u),[d,p]=(0,t.useState)("");let h="wc-block-components-text-input pagarme-credit-card-number-container";const[f,g]=(0,t.useState)(!1);(f||e.length)&&(h+=" is-active"),i.hasOwnProperty("inputNumber")&&(h+=" has-error");const v=()=>{a(s,""),p("")};return{setIsActive:g,cssClasses:h,brandImageSrc:d,inputChangeHandler:e=>{r(s,e.target.value)},inputBlurHandler:t=>{c(t.target.value),(async()=>{const t=y(e);if(16!==t.length)return void v();o(!0);const r=t.substring(0,6),i=`https://api.pagar.me/bin/v1/${r}`;try{const e=await fetch(i),t=await e.json();let l=t.brand;if(e.ok&&void 0!==t.brandName||(l=(e=>{let t="",r=null;for(const[a,o]of Object.entries(n))for(const n of o.prefixes){const o=n.toString();0===e.indexOf(o)&&t.length{const{setIsActive:m,cssClasses:h,brandImageSrc:f,inputChangeHandler:g,inputBlurHandler:y}=b(r,i,a,s,l,u,c,d,p);return(0,t.createElement)("div",{className:h},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)(v(),{className:"pagarme-card-form-card-number",type:"text",id:e,mask:"9999 9999 9999 9999",maskChar:"•",onFocus:()=>m(!0),onChange:g,value:r,onBlur:y}),f&&(0,t.createElement)("img",{src:f,alt:o}),c.inputNumber&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,c.inputNumber)))};E.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,brand:a().string.isRequired,setBrand:a().func.isRequired,brands:a().object.isRequired,setIsLoading:a().func.isRequired,cardIndex:a().number.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const w=E,C=({id:e,label:n,inputValue:r,setInputValue:a,cardIndex:o,validate:s,validateIndex:i,mask:l,maskChar:u=null,errors:c})=>{const{setIsActive:d,cssClasses:p,inputChangeHandler:m,inputBlurHandler:h}=((e,n,r,a,o,s)=>{let i="wc-block-components-text-input";const[l,u]=(0,t.useState)(!1);return(l||e.length)&&(i+=" is-active"),s.hasOwnProperty(o)&&(i+=" has-error"),{setIsActive:u,cssClasses:i,inputChangeHandler:e=>{n(r,e.target.value)},inputBlurHandler:e=>{a(e.target.value),u(!1)}}})(r,a,o,s,i,c);return(0,t.createElement)("div",{className:p},(0,t.createElement)("label",{htmlFor:e},n),(0,t.createElement)(v(),{type:"text",id:e,mask:l,maskChar:u,onChange:m,value:r,onFocus:()=>d(!0),onBlur:h}))};C.propTypes={id:a().string.isRequired,label:a().string.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,cardIndex:a().number.isRequired,mask:a().string.isRequired,maskChar:a().string,validate:a().func.isRequired,validateIndex:a().string.isRequired,errors:a().object.isRequired};const I=C,R=({id:e,label:n,cardIndex:r,inputValue:a,setInputValue:o,errors:s,setErrors:i,fieldErrors:l})=>{const{validateInputExpiry:u}=m(r,s,i,l);return(0,t.createElement)(t.Fragment,null,(0,t.createElement)(I,{id:e,label:n,mask:"99/99",maskChar:"_",inputValue:a,setInputValue:o,cardIndex:r,validate:u,validateIndex:"inputExpiry",errors:s}),s.inputExpiry&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,s.inputExpiry)))};R.propTypes={id:a().string.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const k=R,S=({id:e,label:n,cardIndex:r,inputValue:a,setInputValue:o,errors:s,setErrors:i,fieldErrors:l})=>{const{validateInputCvv:u}=m(r,s,i,l);return(0,t.createElement)(t.Fragment,null,(0,t.createElement)(I,{id:e,label:n,mask:"9999",inputValue:a,setInputValue:o,cardIndex:r,validate:u,validateIndex:"inputCvv",errors:s}),s.inputCvv&&(0,t.createElement)("div",{className:"wc-block-components-validation-error",role:"alert"},(0,t.createElement)("p",null,s.inputCvv)))};S.propTypes={id:a().string.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,inputValue:a().string.isRequired,setInputValue:a().func.isRequired,errors:a().object.isRequired,setErrors:a().func.isRequired,fieldErrors:a().object.isRequired};const x=S,{ComboboxControl:P}=wp.components,O=({cards:e,label:n,cardIndex:r,selectedCard:a,setSelectCard:o,setBrand:s})=>{const{filterHandler:i,cardChangeHandler:l}=((e,t,n,r)=>({filterHandler:t=>{e.filter((e=>e.label.toLowerCase().startsWith(t.toLowerCase())))},cardChangeHandler:a=>{if(n(t,a),!e)return;const o=e.find((e=>e.value===a));r(t,o?o.brand:"")}}))(e,r,o,s);return(0,t.createElement)("div",{className:"wc-block-components-select-input pagarme-installments-combobox"},(0,t.createElement)("div",{className:"wc-block-components-combobox is-active"},(0,t.createElement)(P,{className:"wc-block-components-combobox-control",label:n,onChange:l,value:a,options:e,onFilterValueChange:i,allowReset:!1,autoComplete:"off"})))};O.propTypes={cards:a().array.isRequired,label:a().string.isRequired,cardIndex:a().number.isRequired,selectedCard:a().string.isRequired,setSelectCard:a().func.isRequired,setBrand:a().func.isRequired};const N=O,T=window.wp.data,M={holderName:"",number:"",expirationDate:"",installment:1,brand:"",cvv:"",saveCard:!1,walletId:"",errors:{}},V={cards:{1:{...M},2:{...M}}},q=(0,T.createReduxStore)("pagarme-cards",{reducer(e=V,t){switch(t.type){case"SET_PROPERTY_VALUE":return 0===t.propertyName?.length?e:{...e,cards:{...e.cards,[t.cardIndex]:{...e.cards[t.cardIndex],[t.propertyName]:t.value}}};case"RESET":return V}return e},actions:{setHolderName:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"holderName"}),setNumber:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"number"}),setExpirationDate:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"expirationDate"}),setInstallment:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"installment"}),setBrand:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"brand"}),setCvv:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"cvv"}),setSaveCard:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"saveCard"}),setWalletId:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"walletId"}),setErrors:(e,t)=>({type:"SET_PROPERTY_VALUE",cardIndex:e,value:t,propertyName:"errors"}),reset:()=>({type:"RESET"})},selectors:{getHolderName:(e,t)=>e.cards[t].holderName,getNumber:(e,t)=>e.cards[t].number,getExpirationDate:(e,t)=>e.cards[t].expirationDate,getInstallment:(e,t)=>e.cards[t].installment,getBrand:(e,t)=>e.cards[t].brand,getCvv:(e,t)=>e.cards[t].cvv,getSaveCard:(e,t)=>e.cards[t].saveCard,getWalletId:(e,t)=>e.cards[t].walletId,getCards:e=>e.cards,getErrors:(e,t)=>e.cards[t].errors}});(0,T.register)(q);const D=q,{CheckboxControl:L}=window.wc.blocksComponents,_=({billing:e,components:n,backendConfig:r,cardIndex:a,eventRegistration:o})=>{const{LoadingMask:s}=n,{holderNameLabel:i,numberLabel:l,expiryLabel:u,cvvLabel:c,installmentsLabel:p,saveCardLabel:h,walletLabel:g}=r.fieldsLabels,{isLoading:v,setIsLoading:y,setHolderName:b,setNumber:E,setExpirationDate:C,setInstallment:I,setBrand:R,setCvv:S,setWalletId:P,setErrors:O,saveCardChangeHandler:M,formatFieldId:V,holderName:q,number:_,expirationDate:j,selectedInstallment:A,brand:B,cvv:F,saveCard:H,walletId:U,errors:Y}=((e,n,r)=>{const[a,o]=(0,t.useState)(!1),{setHolderName:s,setNumber:i,setExpirationDate:l,setInstallment:u,setBrand:c,setCvv:d,setSaveCard:p,setWalletId:h,setErrors:f}=(0,T.useDispatch)(D),g=(0,T.useSelect)((t=>t(D).getHolderName(e)),[e]),v=(0,T.useSelect)((t=>t(D).getNumber(e)),[e]),y=(0,T.useSelect)((t=>t(D).getExpirationDate(e)),[e]),b=(0,T.useSelect)((t=>t(D).getInstallment(e)),[e]),E=(0,T.useSelect)((t=>t(D).getBrand(e)),[e]),w=(0,T.useSelect)((t=>t(D).getCvv(e)),[e]),C=(0,T.useSelect)((t=>t(D).getSaveCard(e)),[e]),I=(0,T.useSelect)((t=>t(D).getWalletId(e)),[e]),R=(0,T.useSelect)((t=>t(D).getErrors(e)),[e]),{validateAllFields:k}=m(e,R,f,r.fieldErrors),{onCheckoutValidation:S}=n;return(0,t.useEffect)((()=>S((()=>(0===I.length&&k(g,v,y,w),!0)))),[S,g,v,y,w,r,I]),{isLoading:a,setIsLoading:o,setHolderName:s,setNumber:i,setExpirationDate:l,setInstallment:u,setBrand:c,setCvv:d,setWalletId:h,setErrors:f,saveCardChangeHandler:t=>{p(e,t)},formatFieldId:t=>`pagarme_credit_card_${e}_${t}`,holderName:g,number:v,expirationDate:y,selectedInstallment:b,brand:E,cvv:w,saveCard:C,walletId:I,errors:R}})(a,o,r);return(0,t.createElement)(s,{isLoading:v},(0,t.createElement)("div",{className:"wc-block-components-form"},r?.walletEnabled&&r?.cards?.length>0&&(0,t.createElement)(N,{label:g,selectedCard:U,cards:r.cards,cardIndex:a,setSelectCard:P,setBrand:R}),0===U.length&&(0,t.createElement)(t.Fragment,null,(0,t.createElement)(f,{id:V("holder_name"),label:i,inputValue:q,setInputValue:b,cardIndex:a,errors:Y,setErrors:O,fieldErrors:r?.fieldErrors}),(0,t.createElement)(w,{id:V("number"),label:l,inputValue:_,setInputValue:E,brand:B,setBrand:R,brands:r?.brands,setIsLoading:y,cardIndex:a,errors:Y,setErrors:O,fieldErrors:r?.fieldErrors}),(0,t.createElement)(k,{id:V("expiry"),label:u,inputValue:j,setInputValue:C,cardIndex:a,errors:Y,setErrors:O,fieldErrors:r?.fieldErrors}),(0,t.createElement)(x,{id:V("cvv"),label:c,inputValue:F,setInputValue:S,cardIndex:a,errors:Y,setErrors:O,fieldErrors:r?.fieldErrors})),(0,t.createElement)(d,{label:p,installments:r?.installments,installmentsType:r?.installmentsType,selectedInstallment:A,setSelectedInstallment:I,brand:B,cartTotal:e.cartTotal.value,setIsLoading:y,cardIndex:a}),0===U.length&&r?.walletEnabled&&(0,t.createElement)(L,{label:h,checked:H,onChange:M})))};_.propType={billing:a().object.isRequired,components:a().object.isRequired,backendConfig:a().object.isRequired,cardIndex:a().number.isRequired,eventRegistration:a().object.isRequired};const j=_;var A=n(21),B=n.n(A);const F={token:"",errors:{}},H=(0,T.createReduxStore)("pagarme-googlepay",{reducer(e=F,t){switch(t.type){case"SET_PROPERTY_VALUE":return t.propertyName?{...e,[t.propertyName]:t.value}:e;case"RESET":return F;default:return e}},actions:{setToken:e=>({type:"SET_PROPERTY_VALUE",value:e,propertyName:"token"}),setErrors:e=>({type:"SET_PROPERTY_VALUE",value:e,propertyName:"errors"}),reset:()=>({type:"RESET"})},selectors:{getToken:e=>e.token,getErrors:e=>e.errors}});(0,T.register)(H);const U=H,Y=e=>{const n=wc.wcSettings.getSetting("woo-pagarme-payments-googlepay_data"),r=n.isSandboxMode?"TEST":"PRODUCTION",a=e?.billing?.billingAddress,{setToken:o}=(0,T.useDispatch)(U);return(0,t.createElement)(B(),{environment:r,buttonLocale:"pt",buttonType:"pay",paymentRequest:{apiVersion:2,apiVersionMinor:0,allowedPaymentMethods:[{type:"CARD",parameters:{allowedAuthMethods:["PAN_ONLY"],allowedCardNetworks:n.allowedGoogleBrands},tokenizationSpecification:{type:"PAYMENT_GATEWAY",parameters:{gateway:"pagarme",gatewayMerchantId:n.accountId}}}],merchantInfo:{merchantId:n.merchantId,merchantName:n.merchantName},transactionInfo:{totalPriceStatus:"FINAL",totalPriceLabel:"Total",totalPrice:(e.billing.cartTotal.value/100).toString(),currencyCode:"BRL",countryCode:"BR"}},onLoadPaymentData:e=>{if(function(e){const t=["first_name","last_name","email","phone","address_1","city","postcode","state","country"];for(const n of t)if(!e[n])return!1;return!0}(a)){let t=e.paymentMethodData.tokenizationData.token;o(t)}jQuery(".wc-block-components-checkout-place-order-button").click()}})};class $ extends Error{constructor(e){super(e),this.name=this.constructor.name}}const W=(e,t,n)=>{const r=`${e.replace("request.","").replace("card.","")}: ${t}`;return n.hasOwnProperty(r)?n[r]:""};async function z(e,t,n,r,a,o){const[s,i]=p(n),l={card:{holder_name:t,number:y(e),exp_month:s,exp_year:i,cvv:r}};try{const e=`https://api.pagar.me/core/v5/tokens?appId=${a}`,t=await fetch(e,{method:"POST",body:JSON.stringify(l)});if(!t.ok){const e=await t.text();if(0===e.length)return{errorMessage:o.serviceUnavailable};const n=((e,t)=>{let n="";for(const r in e.errors)for(const a of e.errors[r]||[]){const e=W(r,a,t);0!==e.length&&(n+=`${e}
`)}return n})(JSON.parse(e),o);return{errorMessage:n}}return{token:(await t.json()).id}}catch(e){return{errorMessage:o.serviceUnavailable}}}const J=(e,n,r,a)=>{const{reset:o}=(0,T.useDispatch)(D),{reset:s}=(0,T.useDispatch)(U),{onPaymentSetup:i}=r,l=(0,T.useSelect)((e=>e(D).getCards()));(0,t.useEffect)((()=>{o()}),[]),(0,t.useEffect)((()=>i((async()=>{try{if(a)return s(),{type:n.responseTypes.SUCCESS,meta:{paymentMethodData:{pagarme:JSON.stringify({googlepay:{googlepay:{payload:a}}}),payment_method:"googlepay"}}};let t=!1;if("object"==typeof l&&(t=Object.values(l).some((e=>Object.keys(e.errors).length>0))),t)return{type:n.responseTypes.ERROR,message:e.errorMessages.creditCardFormHasErrors};const r=await(async(e,t,n)=>{const r=[];for(let a=1;a0){r[a]={"wallet-id":d,brand:l,installment:u};continue}const p=await z(o,t,s,i,n.appId,n.errorMessages);if(p.errorMessage)throw new $(p.errorMessage);r[a]={token:p.token,brand:l,installment:u},c&&(r[a]["save-card"]=c)}return r})(l,1,e);return{type:n.responseTypes.SUCCESS,meta:{paymentMethodData:{pagarme:JSON.stringify({[e.key]:{cards:{...r}}}),payment_method:e.key}}}}catch(t){let r=e.errorMessages.serviceUnavailable;return t instanceof $&&(r=t.message),{type:n.responseTypes.ERROR,message:r}}}))),[i,l,e,a])},{registerPaymentMethod:X}=window.wc.wcBlocksRegistry,G=wc.wcSettings.getSetting("woo-pagarme-payments-credit_card_data"),Z=wc.wcSettings.getSetting("woo-pagarme-payments-googlepay_data"),Q=n=>{const r=(0,T.useSelect)((e=>e(U).getToken())),{emitResponse:a,eventRegistration:o}=n,s=Z.enabled,i=Z.hasSubscriptionInCart;return J(G,a,o,r),(0,t.createElement)("div",null,s&&!i&&(0,t.createElement)("div",null,(0,t.createElement)(Y,n),(0,t.createElement)("div",{className:"pagarme_creditcard_divider"},(0,t.createElement)("p",null,"Ou pague com cartão"))),!r&&(0,t.createElement)(j,e({},n,{backendConfig:G,cardIndex:1})))},K=({components:e})=>{const{PaymentMethodLabel:n}=e;return(0,t.createElement)(n,{text:G.label})};Q.propTypes={emitResponse:a().object,eventRegistration:a().object},K.propTypes={components:a().object},X({name:G.name,label:(0,t.createElement)(K,null),content:(0,t.createElement)(Q,null),edit:(0,t.createElement)(Q,null),canMakePayment:()=>!0,ariaLabel:G.ariaLabel})})()})(); \ No newline at end of file diff --git a/composer.json b/composer.json index 877f8fe5..8ad10a68 100644 --- a/composer.json +++ b/composer.json @@ -2,7 +2,7 @@ "name": "pagarme/woocommerce-pagarme-payments", "description": "Pagar.me module for Woocommerce", "type": "wordpress-plugin", - "version": "3.4.0", + "version": "3.4.2", "license": "GPL", "autoload": { "psr-4": { diff --git a/constants.php b/constants.php index afeea9f2..2040114e 100644 --- a/constants.php +++ b/constants.php @@ -12,7 +12,7 @@ function wc_pagarme_define($name, $value) wc_pagarme_define('WCMP_SLUG', 'woo-pagarme-payments'); wc_pagarme_define('WCMP_PREFIX', 'pagarme'); -wc_pagarme_define('WCMP_VERSION', '3.4.0'); +wc_pagarme_define('WCMP_VERSION', '3.4.2'); wc_pagarme_define('WCMP_ROOT_PATH', dirname(__FILE__) . '/'); wc_pagarme_define('WCMP_ROOT_SRC', WCMP_ROOT_PATH . 'src/'); wc_pagarme_define('WCMP_ROOT_FILE', WCMP_ROOT_PATH . WCMP_SLUG . '.php'); diff --git a/languages/woo-pagarme-payments-pt_BR.mo b/languages/woo-pagarme-payments-pt_BR.mo index 0ac64586..d499cf07 100644 Binary files a/languages/woo-pagarme-payments-pt_BR.mo and b/languages/woo-pagarme-payments-pt_BR.mo differ diff --git a/languages/woo-pagarme-payments-pt_BR.po b/languages/woo-pagarme-payments-pt_BR.po index 03a5be28..53a30872 100644 --- a/languages/woo-pagarme-payments-pt_BR.po +++ b/languages/woo-pagarme-payments-pt_BR.po @@ -5,7 +5,7 @@ msgstr "" "Project-Id-Version: WooCommerce Pagar.me Payments 1.0\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/woo-pagarme-payments\n" "POT-Creation-Date: 2018-06-22 13:58-0300\n" -"PO-Revision-Date: 2024-10-01 09:55-0300\n" +"PO-Revision-Date: 2024-10-24 16:33-0300\n" "Last-Translator: Pagar.me\n" "Language-Team: \n" "Language: pt_BR\n" @@ -423,6 +423,16 @@ msgstr "Logs" msgid "Log Pagar.me events, you can check this log in WooCommerce>Status>Logs." msgstr "Registra eventos da Pagar.me, você pode conferir esse arquivo de log em WooCommerce>Status>Logs." +msgid "Modify address fields" +msgstr "Modificar campos de endereço" + +msgid "" +"Corrects the 'label' and 'placeholder' attributes of the 'Address' and 'Complement' fields to instruct users on how " +"to fill them in correctly." +msgstr "" +"Corrige os atributos 'label' e 'placeholder' dos campos de 'Endereço' e 'Complemento' para instruir os usuários no " +"preenchimento correto dos mesmos." + msgid "Allow order without address" msgstr "Permitir compras sem endereço" @@ -849,8 +859,12 @@ msgid "The following checkout fields are required, but were not found:" msgstr "Os seguintes campos de checkout são obrigatórios, mas não foram encontrados:" #: woo-pagarme-payments.php:194 -msgid "Please, make sure to include them for Pagar.me module to work." -msgstr "Por favor, certifique-se de incluí-los para que o módulo da Pagar.me funcione." +msgid "" +"Please, make sure to include them for Pagar.me plugin to work. If you are customizing the checkout, the address " +"fields must have the 'name' attribute exactly as listed above. %sRead documentation »%s" +msgstr "" +"Por favor, certifique-se de incluí-los para que o plugin Pagar.me funcione. Se você estiver personalizando o " +"checkout, os campos de endereço devem ter o atributo 'name' exatamente como listado acima. %sLeia a documentação »%s" msgid "You can install %s or any other plugin of your choice to add the missing fields. %sRead documentation »%s" msgstr "" @@ -1226,22 +1240,6 @@ msgstr "" "Sua conta está desativada na Dash da Pagar.me. Por favor, entre em contato com o nosso time de atendimento para " "habilitá-la." -#: src/Controller/HubAccounts.php:90 src/Controller/HubAccounts.php:96 -msgid "" -"No domain registered on Pagar.me Dash. Please enter your website's domain on the Dash to be able to process payment " -"in your store." -msgstr "" -"Nenhum domínio cadastrado na Dash da Pagar.me. Por favor, insira o domínio do seu site na Dash para poder processar o " -"pagamento em sua loja." - -#: src/Controller/HubAccounts.php:90 src/Controller/HubAccounts.php:96 -msgid "" -"The registered domain is different from the URL of your website. Please correct the domain configured on the Dash to " -"be able to process payment in your store." -msgstr "" -"O domínio cadastrado é diferente da URL do seu site. Por favor, corrija o domínio configurado na Dash para poder " -"processar o pagamento em sua loja." - msgid "" "Pix payment method is enabled on your store, but disabled on Pagar.me Dash. Please, access the Dash configurations " "and enable it to be able to process Pix payment on your store." @@ -1505,7 +1503,7 @@ msgid "Check the Pagar.me Dashboard at: Settings → Keys → Account ID" msgstr "Consulte na Dashboard Pagar.me em: Configurações → Chaves → ID da Conta" msgid "Google Merchant Identifier, get yours here." -msgstr "Identificador de comerciante do Google, adquira o seu aqui" +msgstr "Identificador de comerciante do Google, adquira o seu aqui." msgid "Your store name that will be displayed to the customer while purchasing through Google Pay." msgstr "Nome da sua loja que será exibido ao cliente enquanto compra através do Google Pay." @@ -1515,3 +1513,44 @@ msgstr "Nome da loja na Google Pay" msgid "Pagar.me account ID" msgstr "ID da conta Pagar.me" + +msgid "Document" +msgstr "Documento" + +msgid "CPF or CNPJ" +msgstr "CPF ou CNPJ" + +msgctxt "checkout-document-error" +msgid "Billing" +msgstr "faturamento" + +msgctxt "checkout-document-error" +msgid "Shipping" +msgstr "envio" + +msgid "Please, enter a valid document number." +msgstr "Por favor, digite um número de documento válido." + +msgid "Please, enter a valid %s number." +msgstr "Por favor, digite um número de %s válido." + +msgid "Please, enter a valid document number in the %s Document." +msgstr "Por favor, digite um número de documento válido no campo Documento de %s." + +msgid "Please, enter a valid %s number in the %s Document." +msgstr "Por favor, digite um número de %s válido no campo "Documento" do endereço de %s." + +msgid "%s Document" +msgstr "Documento de %s" + +msgid "Billing" +msgstr "Faturamento" + +msgid "Shipping" +msgstr "Envio" + +msgid "Street, number and neighbourhood" +msgstr "Rua, número e bairro" + +msgid "Additional address data" +msgstr "Complemento" diff --git a/package.json b/package.json index 3632d998..ed7d31b8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "woo-pagarme-payments", - "version": "3.4.0", + "version": "3.4.2", "description": "Pagar.me module for Woocommerce", "main": "woo-pagarme-payments.php", "devDependencies": { diff --git a/readme.txt b/readme.txt index fdc61ca6..1e69bba5 100644 --- a/readme.txt +++ b/readme.txt @@ -4,7 +4,7 @@ Tags: payment, pagarme, ecommerce, brasil, woocommerce Requires at least: 4.1 Tested up to: 6.5.5 Requires PHP: 7.1 -Stable tag: 3.4.0 +Stable tag: 3.4.2 License: MIT License URI: https://github.com/pagarme/woocommerce/blob/master/LICENSE @@ -25,30 +25,24 @@ Nosso processo de instalação é simples e bem detalhado: == Changelog == Lançamos versões regularmente com melhorias, correções e atualizações. -= 3.4.0 (01/10/2024) = -Você pode conferir essas atualizações aqui: [Github](https://github.com/pagarme/woocommerce/releases/tag/3.4.0) +👻 3.4.2 (31/10/2024) 👻 +Você pode conferir essas atualizações aqui: [Github](https://github.com/pagarme/woocommerce/releases/tag/3.4.2) * **Novas funcionalidades:** - * Meio de pagamento Google Pay. + * Adição de identificador da bandeira. * **Melhorias:** - * Passando pedido e meio de pagamento para o cálculo do split; - * Checkout assincrono; - + * Bandeira de Ticket; + * Mudanças em relação ao processo de renovação ao plugin de Subscriptions. * **Correções:** - * Link para desintregar chamando endpoint incorretamente - * Problemas com tokenização - -= 3.3.3 (14/08/2024) = -Você pode conferir essas atualizações aqui: [Github](https://github.com/pagarme/woocommerce/releases/tag/3.3.3) + * Problema ao importar JS de GooglePay. -* **Melhorias:** - * Passando pedido e meio de pagamento para o cálculo do split += 3.4.1 (03/10/2024) = +Você pode conferir essas atualizações aqui: [Github](https://github.com/pagarme/woocommerce/releases/tag/3.4.1) * **Correções:** - * Perdendo informação de bandeira ao trocar meios de pagamento no checkout - + * Problema de sintax em versões de PHP 7.4.x ou menor. == Upgrade Notice == -Agora é possível transacionar Via Google Pay +Agora é possível transacionar com Ticket diff --git a/src/Action/ActionsRunner.php b/src/Action/ActionsRunner.php index c19ae217..b08e23b8 100644 --- a/src/Action/ActionsRunner.php +++ b/src/Action/ActionsRunner.php @@ -2,10 +2,14 @@ namespace Woocommerce\Pagarme\Action; +/** + * @uses CustomerFieldsActions, OrderActions + */ class ActionsRunner implements RunnerInterface { private $actionClasses = [ - "OrderActions" + "OrderActions", + "CustomerFieldsActions" ]; public function run() diff --git a/src/Action/CustomerFieldsActions.php b/src/Action/CustomerFieldsActions.php new file mode 100644 index 00000000..20be485f --- /dev/null +++ b/src/Action/CustomerFieldsActions.php @@ -0,0 +1,181 @@ +customerFields = new CustomerFields(); + } + + public function run() + { + add_filter('woocommerce_checkout_init', array($this, 'enqueueScript')); + add_filter('woocommerce_checkout_fields', array($this, 'addDocumentField')); + add_action('woocommerce_checkout_process', array($this, 'validateDocument')); + add_action('woocommerce_init', array($this, 'addDocumentFieldOnCheckoutBlocks')); + add_action('woocommerce_validate_additional_field', array($this, 'validateCheckoutBlocksDocument'), 10, 3); + add_action( + 'woocommerce_admin_order_data_after_billing_address', + array($this, 'displayBillingDocumentOrderMeta') + ); + add_action( + 'woocommerce_admin_order_data_after_shipping_address', + array($this, 'displayShippingDocumentOrderMeta') + ); + add_filter('woocommerce_default_address_fields', array($this, 'overrideAddressFields')); + } + + public function enqueueScript() + { + $parameters = Utils::getRegisterScriptParameters('front/checkout', 'checkoutFields', ['jquery.mask']); + wp_register_script( + 'pagarme_customer_fields', + $parameters['src'], + $parameters['deps'], + $parameters['ver'], + true + ); + wp_enqueue_script('pagarme_customer_fields'); + } + + /** + * @param array $fields + * + * @return array + */ + public function addDocumentField(array $fields): array + { + if ($this->customerFields->hasDocumentField($fields)) { + return $fields; + } + + foreach ($this->customerFields::ADDRESS_TYPES as $addressType) { + $fields[$addressType]["{$addressType}_document"] = array( + 'label' => __('Document', 'woo-pagarme-payments'), + 'placeholder' => __('CPF or CNPJ', 'woo-pagarme-payments'), + 'required' => true, + 'class' => array('form-row-wide'), + 'priority' => 25 + ); + } + + return $fields; + } + + /** + * @throws Exception + */ + public function addDocumentFieldOnCheckoutBlocks() + { + if ( + $this->customerFields->hasCheckoutBlocksDocumentField() + || !function_exists('woocommerce_register_additional_checkout_field') + ) { + return; + } + + woocommerce_register_additional_checkout_field( + array( + 'id' => 'address/document', + 'label' => __('CPF or CNPJ', 'woo-pagarme-payments'), + 'location' => 'address', + 'type' => 'text', + 'class' => array('form-row-wide'), + 'required' => true, + 'index' => 25, + 'show_in_order_confirmation' => true + ) + ); + } + + /** + * @return void + */ + public function validateDocument() + { + $this->customerFields->validateDocument(); + } + + /** + * @param WP_Error $errors + * @param $fieldKey + * @param $documentNumber + * + * @return void + */ + public function validateCheckoutBlocksDocument(WP_Error $errors, $fieldKey, $documentNumber) + { + if ($fieldKey == 'address/document') { + $this->customerFields->validateCheckoutBlocksDocument($errors, $documentNumber); + } + } + + /** + * @param $order + * + * @return void + */ + public function displayBillingDocumentOrderMeta($order) + { + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[0]); + } + + /** + * @param $order + * + * @return void + */ + public function displayShippingDocumentOrderMeta($order) + { + $this->customerFields->displayDocumentOrderMeta($order, $this->customerFields::ADDRESS_TYPES[1]); + } + + /** + * @param array $fields + * + * @return array + */ + public function overrideAddressFields(array $fields): array + { + $config = new Config(); + + if (!$config->getModifyAddress()) { + return $fields; + } + + $fields['address_1']['placeholder'] = __( + 'Street, number and neighbourhood', + 'woo-pagarme-payments' + ); + $fields['address_2']['label'] = __( + 'Additional address data', + 'woo-pagarme-payments' + ); + $fields['address_2']['label_class'] = ''; + + return $fields; + } +} diff --git a/src/Action/OrderActions.php b/src/Action/OrderActions.php index 254e6fe6..0cc21820 100644 --- a/src/Action/OrderActions.php +++ b/src/Action/OrderActions.php @@ -4,6 +4,9 @@ use Woocommerce\Pagarme\Model\Order; +/** + * @used-by ActionsRunner + */ class OrderActions implements RunnerInterface { @@ -32,7 +35,7 @@ public function showInstallmentFeesToCustomer($total_rows, $order, $tax_display) if (!$orderPagarme->isPagarmePaymentMethod()) { return $total_rows; } - + $total = $order->get_total(); $installmentsValue = $orderPagarme->get_meta('pagarme_card_tax'); if (empty($installmentsValue)) { diff --git a/src/Block/ReactCheckout/GooglePay.php b/src/Block/ReactCheckout/GooglePay.php index 794df740..2aeffbec 100644 --- a/src/Block/ReactCheckout/GooglePay.php +++ b/src/Block/ReactCheckout/GooglePay.php @@ -3,6 +3,7 @@ namespace Woocommerce\Pagarme\Block\ReactCheckout; use Woocommerce\Pagarme\Model\Config; +use Woocommerce\Pagarme\Model\Subscription; use Woocommerce\Pagarme\Model\Payment\GooglePay as GooglePayModel; class GooglePay extends AbstractPaymentMethodBlock @@ -13,6 +14,7 @@ class GooglePay extends AbstractPaymentMethodBlock /** @var string */ const PAYMENT_METHOD_KEY = 'googlepay'; + const GOOGLE_BRANDS = ['VISA', 'ELECTRON', 'MASTERCARD', 'MAESTRO', 'ELO']; /** @var string */ const ARIA_LABEL = 'Google Pay'; @@ -29,13 +31,36 @@ public function __construct() parent::__construct($paymentModel); } + private function getGooglepayBrands() + { + $allowedBrands = []; + foreach ($this->config->getCcFlags() as $brand) { + $brand = strtoupper($brand); + if( in_array($brand, self::GOOGLE_BRANDS) ) { + $allowedBrands[] = $brand; + } + } + return $allowedBrands; + } + + /** + * @return boolean + */ + protected function jsUrl() + { + return false; + } + public function getAdditionalPaymentMethodData() { return [ + 'enabled' => $this->config->getEnableGooglepay() === 'yes', 'accountId' => $this->config->getAccountId(), 'merchantName' => $this->config->getGooglepayGoogleMerchantName(), 'merchantId' => $this->config->getGooglepayGoogleMerchantId(), - 'isSandboxMode' => $this->config->getIsSandboxMode() + 'isSandboxMode' => $this->config->getIsSandboxMode(), + 'allowedGoogleBrands' => $this->getGooglepayBrands(), + 'hasSubscriptionInCart' => Subscription::hasSubscriptionProductInCart() ]; } } diff --git a/src/Concrete/WoocommercePlatformOrderDecorator.php b/src/Concrete/WoocommercePlatformOrderDecorator.php index 87e16c61..84f734e2 100644 --- a/src/Concrete/WoocommercePlatformOrderDecorator.php +++ b/src/Concrete/WoocommercePlatformOrderDecorator.php @@ -460,7 +460,8 @@ private function getRegisteredCustomer($woocommerceCustomerId) if (empty($document['value'])) { $customerPlatform = new WC_Customer($woocommerceCustomerId); $document['value'] = $customerPlatform->get_meta("billing_cpf") ?? - $customerPlatform->get_meta("billing_cnpj"); + $customerPlatform->get_meta("billing_cnpj") ?? + $customerPlatform->get_meta("billing_document"); } $homeNumber = $phones["home_phone"]["complete_phone"]; $mobileNumber = $phones["mobile_phone"]["complete_phone"]; @@ -534,7 +535,7 @@ private function getGuestCustomer() $cleanDocument = preg_replace( '/\D/', '', - $document["value"] + $document['value'] ); $customer->setDocument($cleanDocument); @@ -763,7 +764,7 @@ private function extractPaymentDataFromGooglepay( } $newPaymentData->amount = $moneyService->floatToCents($this->getGrandTotal()); $newPaymentData->googlepayData = $cleanJson; - $newPaymentData->billing_address = $this->getCustomer()?->getAddress()?->convertToSDKRequest(); + $newPaymentData->billing_address = $this->getCustomer()->getAddress()->convertToSDKRequest(); $newPaymentData->additionalInformation = ["googlepayData" => $cleanJson]; $googlepayIndex = 'googlepay'; if (!isset($paymentData[$googlepayIndex])) { @@ -847,6 +848,7 @@ private function extractBasePaymentData() $newPaymentData->identifier = $identifier; $newPaymentData->installments = intval($this->formData["installments"]); $newPaymentData->recurrenceCycle = $this->formData["recurrence_cycle"] ?? null; + $newPaymentData->paymentOrigin = $this->formData["payment_origin"] ?? null; $newPaymentData->saveOnSuccess = isset($this->formData["save_credit_card"]); $amount = $this->formData["card_order_value"] ?? $this->getGrandTotal(); $amount = number_format($amount, 2, '.', ''); @@ -1152,6 +1154,9 @@ public function getShipping() return $shipping; } + /** + * @throws Exception + */ protected function getAddress($platformAddress) { $config = new Config(); @@ -1165,13 +1170,11 @@ protected function getAddress($platformAddress) $address->setStreet($platformAddress["street"]); $address->setNumber($platformAddress["number"]); - $address->setNeighborhood($platformAddress["neighborhood"]); $address->setComplement($platformAddress["complement"]); - + $address->setNeighborhood($platformAddress["neighborhood"]); $address->setCity($platformAddress["city"]); $address->setCountry($platformAddress["country"]); $address->setZipCode($platformAddress["zip_code"]); - $address->setState($platformAddress["state"]); return $address; @@ -1203,8 +1206,6 @@ private function validateAddressFields($platformAddress) { $requiredFields = [ 'street', - 'number', - 'neighborhood', 'city', 'country', 'zip_code', diff --git a/src/Controller/Checkout/CustomerFields.php b/src/Controller/Checkout/CustomerFields.php new file mode 100644 index 00000000..5c0c910d --- /dev/null +++ b/src/Controller/Checkout/CustomerFields.php @@ -0,0 +1,374 @@ +get(CheckoutFields::class); + $possibleNames = array_merge( + self::DOCUMENT_TYPES, + [ + 'document' + ] + ); + + foreach ($possibleNames as $possibleName) { + $hasDocument = preg_grep("/{$possibleName}/", $checkoutFields->get_address_fields_keys()); + + if ($hasDocument) { + return true; + } + } + + return false; + } + + /** + * @param $fields + * + * @return bool + */ + public function hasDocumentField($fields): bool + { + return array_key_exists('billing_cpf', $fields['billing']) + || array_key_exists('billing_cnpj', $fields['billing']); + } + + /** + * @return void + */ + public function validateDocument() + { + foreach (self::ADDRESS_TYPES as $addressType) { + $fieldName = "{$addressType}_document"; + $document = $_POST[$fieldName] ?? ''; + + if (empty($document)) { + continue; + } + + $documentNumber = preg_replace('/\D/', '', $document); + + if (!$this->isValidDocumentLength($documentNumber)) { + $errorMessage = sprintf( + __( + 'Please, enter a valid document number in the %s Document.', + 'woo-pagarme-payments' + ), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + continue; + } + + if (!$this->isValidDocument($documentNumber)) { + $documentType = $this->getDocumentType($documentNumber); + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number in the %s Document.', + 'woo-pagarme-payments' + ), + strtoupper($documentType), + _x( + ucfirst($addressType), + 'checkout-document-error', + 'woo-pagarme-payments' + ) + ); + wc_add_notice($errorMessage, 'error', ['pagarme-error' => $fieldName]); + } + } + } + + /** + * @param $documentNumber + * + * @return bool + */ + private function isValidDocumentLength($documentNumber): bool + { + $documentLength = strlen($documentNumber); + + return $documentLength === 11 || $documentLength === 14; + } + + /** + * @param $documentNumber + * + * @return mixed + * @uses isValidCnpj() + * @uses isValidCpf() + */ + private function isValidDocument($documentNumber) + { + $documentType = $this->getDocumentType($documentNumber); + $functionName = $this->getDocumentValidationFunctionName($documentType); + + return $this->{$functionName}($documentNumber); + } + + /** + * @param $documentNumber + * + * @return string + */ + private function getDocumentType($documentNumber): string + { + return Utils::getDocumentTypeByDocumentNumber($documentNumber); + } + + /** + * @param string $documentType Must be one of the two values: `cpf` or `cnpj` + * + * @return string + */ + private function getDocumentValidationFunctionName(string $documentType): string + { + if (in_array($documentType, self::ADDRESS_TYPES, true)) { + throw new InvalidArgumentException(); + } + + return 'isValid' . ucfirst($documentType); + } + + /** + * @param WP_Error $errors + * @param $documentNumber + * + * @return WP_Error + */ + public function validateCheckoutBlocksDocument(WP_Error $errors, $documentNumber) + { + $documentNumber = preg_replace('/\D/', '', $documentNumber); + $errorCode = 'pagarme_invalid_document'; + + if (!$this->isValidDocumentLength($documentNumber)) { + $errorMessage = __( + 'Please, enter a valid document number.', + 'woo-pagarme-payments' + ); + + $errors->add( + $errorCode, + $errorMessage + ); + + return $errors; + } + + if (!$this->isValidDocument($documentNumber)) { + $documentType = $this->getDocumentType($documentNumber); + $errorMessage = sprintf( + __( + 'Please, enter a valid %s number.', + 'woo-pagarme-payments' + ), + strtoupper($documentType) + ); + + $errors->add( + $errorCode, + $errorMessage + ); + + return $errors; + } + + $errors->remove($errorCode); + + return $errors; + } + + /** + * @param $order + * @param $addressType + * + * @return void + */ + public function displayDocumentOrderMeta($order, $addressType) + { + if (!$order) { + return; + } + + $documentNumber = esc_html($order->get_meta($this->getDocumentMetaNameByAddressType($addressType), true)); + + if (!$documentNumber) { + return; + } + + $metaLabel = sprintf( + __( + '%s Document', + 'woo-pagarme-payments' + ), + __( + ucfirst($addressType), + 'woo-pagarme-payments' + ) + ); + + echo "

{$metaLabel}: {$documentNumber}

"; + } + + /** + * @param string $addressType + * + * @return string + */ + private function getDocumentMetaNameByAddressType(string $addressType): string + { + return "_{$addressType}_document"; + } + + /** + * @param string $cpf + * + * @return bool + */ + private function isValidCpf(string $cpf): bool + { + if (!$this->isValidCpfFormat($cpf)) { + return false; + } + + for ($digit = 9; $digit < 11; $digit ++) { + if (!$this->isValidCpfDigit($cpf, $digit)) { + return false; + } + } + + return true; + } + + /** + * @param string $cpf + * + * @return bool + */ + private function isValidCpfFormat(string $cpf): bool + { + // Check if CPF length is exactly 11 and not all digits are the same + return strlen($cpf) === 11 && !preg_match('/(\d)\1{10}/', $cpf); + } + + /** + * @param string $cpf + * @param int $digit + * + * @return bool + */ + private function isValidCpfDigit(string $cpf, int $digit): bool + { + $calculatedDigit = $this->calculateCpfDigit($cpf, $digit); + + return $cpf[$digit] == $calculatedDigit; + } + + /** + * @param string $cpf + * @param int $digit + * + * @return int + */ + private function calculateCpfDigit(string $cpf, int $digit): int + { + $sum = 0; + + for ($i = 0; $i < $digit; $i ++) { + $sum += $cpf[$i] * (($digit + 1) - $i); + } + + $remainder = (10 * $sum) % 11; + + return ($remainder === 10) ? 0 : $remainder; + } + + /** + * @param string $cnpj + * + * @return bool + */ + private function isValidCnpj(string $cnpj): bool + { + if (!$this->isValidCnpjFormat($cnpj)) { + return false; + } + + $firstCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 12), 5); + if ($cnpj[12] != $firstCheckDigit) { + return false; + } + + $secondCheckDigit = $this->calculateCnpjCheckDigit(substr($cnpj, 0, 13), 6); + + return $cnpj[13] == $secondCheckDigit; + } + + /** + * @param string $cnpj + * + * @return bool + */ + private function isValidCnpjFormat(string $cnpj): bool + { + // Check if CNPJ is 14 characters long and not a sequence of repeated digits + return strlen($cnpj) == 14 && !preg_match('/(\d)\1{13}/', $cnpj); + } + + /** + * @param string $cnpj + * @param int $initialWeight + * + * @return int + */ + private function calculateCnpjCheckDigit(string $cnpj, int $initialWeight): int + { + $sum = 0; + $weight = $initialWeight; + + for ($i = 0; $i < strlen($cnpj); $i ++) { + $sum += $cnpj[$i] * $weight; + $weight = ($weight == 2) ? 9 : $weight - 1; + } + + $remainder = $sum % 11; + + return ($remainder < 2) ? 0 : 11 - $remainder; + } +} diff --git a/src/Controller/Gateways/CreditCard.php b/src/Controller/Gateways/CreditCard.php index a7bf4072..5fb1873d 100644 --- a/src/Controller/Gateways/CreditCard.php +++ b/src/Controller/Gateways/CreditCard.php @@ -148,7 +148,7 @@ public function field_cc_operation_type() 'type' => 'select', 'title' => __('Operation Type', 'woo-pagarme-payments'), 'class' => 'wc-enhanced-select', - 'default' => $this->config->getCcOperationType() ?? 1, + 'default' => $this->config->getCcOperationType() ?? 2, 'options' => array( 1 => __('Authorize', 'woo-pagarme-payments'), 2 => __('Authorize and Capture', 'woo-pagarme-payments'), diff --git a/src/Controller/Gateways/Voucher.php b/src/Controller/Gateways/Voucher.php index 28b0f670..d35e73c8 100644 --- a/src/Controller/Gateways/Voucher.php +++ b/src/Controller/Gateways/Voucher.php @@ -36,7 +36,7 @@ class Voucher extends AbstractGateway const VOUCHER_CARD_BRANDS_FIELD_NAME = 'Voucher Card Brands'; - const DEFAULT_BRANDS = ['alelo', 'sodexo', 'vr']; + const DEFAULT_BRANDS = ['alelo', 'sodexo', 'ticket', 'vr']; /** * @return void diff --git a/src/Controller/HubAccounts.php b/src/Controller/HubAccounts.php index 178c19e0..a1cffbe5 100644 --- a/src/Controller/HubAccounts.php +++ b/src/Controller/HubAccounts.php @@ -171,16 +171,6 @@ private function getHubAccountErrorsNotices() $noticesList = [ Account::ACCOUNT_DISABLED => 'Your account is disabled on Pagar.me Dash. ' . 'Please, contact our support team to enable it.', - Account::DOMAIN_EMPTY => [ - 'message' => 'No domain registered on Pagar.me Dash. Please enter your website\'s domain on the Dash ' - . 'to be able to process payment in your store.', - 'buttons' => $this->getHubNoticeButtons('account-config') - ], - Account::DOMAIN_INCORRECT => [ - 'message' => 'The registered domain is different from the URL of your website. Please correct the ' - . 'domain configured on the Dash to be able to process payment in your store.', - 'buttons' => $this->getHubNoticeButtons('account-config') - ], Account::WEBHOOK_INCORRECT => [ 'message' => 'The URL for receiving webhook registered in Pagar.me Dash is different from the URL of ' . 'your website. Please, click the button below to access the Hub and click the Delete > Confirm ' diff --git a/src/Controller/Settings.php b/src/Controller/Settings.php index 2177667a..30383725 100644 --- a/src/Controller/Settings.php +++ b/src/Controller/Settings.php @@ -143,6 +143,18 @@ private function setSectionsFields(array $value = null) 'options' => $this->yesNoOptions->toLabelsArray(), 'default' => strtolower(Yesno::NO), ], + [ + 'fieldObject' => Select::class, + 'id' => 'modify_address', + 'title' => 'Modify address fields', + 'options' => $this->yesNoOptions->toLabelsArray(), + 'default' => strtolower(Yesno::YES), + 'description' => [ + 'format' => "Corrects the 'label' and 'placeholder' attributes of the 'Address' and " + . "'Complement' fields to instruct users on how to fill them in correctly.", + 'values' => [] + ], + ], [ 'fieldObject' => Select::class, 'id' => 'allow_no_address', diff --git a/src/Helper/Utils.php b/src/Helper/Utils.php index c1c74a62..776103c0 100644 --- a/src/Helper/Utils.php +++ b/src/Helper/Utils.php @@ -487,28 +487,43 @@ public static function build_customer_address_from_order(Order $order) * * @return array|string[] */ - public static function build_document_from_order(Order $order) - { - if (!empty($order->get_meta('billing_cpf'))) { - return array( - 'type' => 'individual', - 'value' => $order->get_meta('billing_cpf'), - ); - } - - if (!empty($order->get_meta('billing_cnpj'))) { - return array( - 'type' => 'company', - 'value' => $order->get_meta('billing_cnpj'), - ); + public static function build_document_from_order(Order $order): array + { + $documentFields = [ + 'billing_cpf', + 'billing_cnpj', + 'billing_document', + 'wc_billing/address/document' + ]; + + foreach ($documentFields as $field) { + if (!empty($order->get_meta($field))) { + $document = $order->get_meta($field); + return [ + 'type' => self::getCustomerTypeByDocumentNumber($document), + 'value' => $document + ]; + } } return array( 'type' => '', - 'value' => '', + 'value' => '' ); } + public static function getCustomerTypeByDocumentNumber($document): string + { + $documentNumber = preg_replace('/\D/', '', $document ?? ''); + return strlen($documentNumber) === 14 ? 'company' : 'individual'; + } + + public static function getDocumentTypeByDocumentNumber($document): string + { + $documentNumber = preg_replace('/\D/', '', $document ?? ''); + return strlen($documentNumber) === 14 ? 'cnpj' : 'cpf'; + } + /** * @param Order $order * @@ -606,4 +621,60 @@ public static function isCheckoutBlock() { return WC_Blocks_Utils::has_block_in_page(wc_get_page_id('checkout'), 'woocommerce/checkout'); } + + /** + * @param $path + * @param $fileName + * + * @return string + */ + private static function getScriptUrl($path, $fileName): string + { + return Core::plugins_url('assets/javascripts/' . $path . '/' . $fileName . '.js'); + } + + /** + * @param array $deps + * + * @return array + */ + private static function setScriptDeps(array $deps = []): array + { + $defaultDeps = ['jquery']; + $mergedDeps = array_merge($defaultDeps, $deps); + + return array_unique($mergedDeps); + } + + /** + * @param $path + * @param $fileName + * + * @return false|int + */ + private static function getScriptVersion($path, $fileName) + { + return Core::filemtime('assets/javascripts/' . $path . '/' . $fileName . '.js'); + } + + /** + * + * + * @param string $path The path to the script file, starting after the folders `assets/javascript/[path]` + * @param string $fileName The file name, without the extension `.js` + * @param array $deps Array of dependencies. `jquery` is added automatically + * + * @return array Returns an array with three keys: `src`, `deps` and `ver`, to be used with `wp_register_script` + */ + public static function getRegisterScriptParameters(string $path, string $fileName, array $deps = []): array + { + $path = rtrim($path, '/'); + $fileName = trim($fileName); + + return [ + 'src' => self::getScriptUrl($path, $fileName), + 'deps' => self::setScriptDeps($deps), + 'ver' => self::getScriptVersion($path, $fileName) + ]; + } } diff --git a/src/Model/Checkout.php b/src/Model/Checkout.php index e684f52f..7fa8bca9 100644 --- a/src/Model/Checkout.php +++ b/src/Model/Checkout.php @@ -21,6 +21,7 @@ use Woocommerce\Pagarme\Model\Payment\Data\Card; use Woocommerce\Pagarme\Model\Payment\Data\Multicustomers; use Woocommerce\Pagarme\Model\Payment\Data\PaymentRequestInterface; +use Woocommerce\Pagarme\Service\CardService; class Checkout { @@ -72,6 +73,7 @@ public function __construct( public function validateCheckout($fields, $errors) { if ( + isset($fields['billing_number']) && $fields['billing_number'] === 0 && !key_exists('billing_number_required', $errors->errors) ) { @@ -82,6 +84,7 @@ public function validateCheckout($fields, $errors) } if ( $fields['ship_to_different_address'] && + isset($fields['shipping_number']) && $fields['shipping_number'] === 0 && !key_exists('shipping_number_required', $errors->errors) ) { @@ -123,6 +126,7 @@ public function process(WC_Order $wc_order = null, string $type = CheckoutTypes: if ($type === CheckoutTypes::TRANSPARENT_VALUE) { $fields = $this->convertCheckoutObject($_POST[PaymentRequestInterface::PAGARME_PAYMENT_REQUEST_KEY]); $fields['recurrence_cycle'] = Subscription::getRecurrenceCycle(); + $this->formatFieldsWhenIsSubscription($fields, $wc_order); $attempts = intval($wc_order->get_meta('_pagarme_attempts') ?? 0) + 1; $wc_order->update_meta_data("_pagarme_attempts", $attempts); $response = $this->orders->create_order( @@ -142,8 +146,8 @@ public function process(WC_Order $wc_order = null, string $type = CheckoutTypes: $order->update_meta("attempts", $attempts); $this->addAuthenticationOnMetaData($order, $fields); if ($response) { + do_action("on_pagarme_response", $response); WC()->cart->empty_cart(); - do_action("on_pagarme_response", $wc_order->get_id(), $response); $order->update_meta('transaction_id', $response->getPagarmeId()->getValue()); $order->update_meta('pagarme_id', $response->getPagarmeId()->getValue()); $order->update_meta('pagarme_status', $response->getStatus()->getStatus()); @@ -158,6 +162,30 @@ public function process(WC_Order $wc_order = null, string $type = CheckoutTypes: return false; } } + private function formatFieldsWhenIsSubscription(&$fields, $wc_order) + { + if(Subscription::hasSubscriptionProductInCart() == false){ + return; + } + if ($fields['payment_method'] === 'credit_card') { + $fields['card_id'] = $this->getCardId($fields, $wc_order); + // If same, return payment_origin in $fields + $subscription = new Subscription(); + $subscription->isSameCardInSubscription($fields, $wc_order); + unset($fields['pagarmetoken1']); + } + } + + private function getCardId($fields, $wc_order) + { + if($fields['card_id']){ + return $fields['card_id']; + } + $customer = new Customer($wc_order->get_customer_id()); + $cardService = new CardService(); + $pagarmeCard = $cardService->create($fields['pagarmetoken1'], $customer->getPagarmeCustomerId()); + return $pagarmeCard['cardId']; + } private function convertCheckoutObject(PaymentRequestInterface $paymentRequest) { @@ -212,6 +240,9 @@ private function convertCheckoutObject(PaymentRequestInterface $paymentRequest) private function extractGooglePayToken(&$fields, $paymentRequest) { + if(!$paymentRequest->getDataByKey('googlepay')){ + return; + } $fields['googlepay']['token'] = $paymentRequest->getDataByKey('googlepay'); } diff --git a/src/Model/Config.php b/src/Model/Config.php index 65fb1123..88f76dca 100644 --- a/src/Model/Config.php +++ b/src/Model/Config.php @@ -269,6 +269,11 @@ public function getMulticustomers() return $this->isEnabled('multicustomers'); } + public function getModifyAddress() + { + return $this->isEnabled('modify_address'); + } + public function getAllowNoAddress() { return $this->isEnabled('allow_no_address'); diff --git a/src/Model/Customer.php b/src/Model/Customer.php index 5b4e20a7..1259cbe9 100644 --- a/src/Model/Customer.php +++ b/src/Model/Customer.php @@ -7,7 +7,6 @@ exit(0); } -use Woocommerce\Pagarme\Helper\Utils; use Pagarme\Core\Payment\Repositories\SavedCardRepository as CoreSavedCardRepository; use Pagarme\Core\Payment\Repositories\CustomerRepository as CoreCustomerRepository; use Woocommerce\Pagarme\Service\CustomerService; @@ -33,11 +32,11 @@ class Customer * @param CoreCustomerRepository $customerRepository */ /** phpcs:disable */ - public function __construct($ID, $cardRepository, $customerRepository) + public function __construct($ID, $cardRepository = null, $customerRepository = null) { $this->ID = (int) $ID; - $this->cardRepository = $cardRepository; - $this->customerRepository = $customerRepository; + $this->cardRepository = $cardRepository ?? new CoreSavedCardRepository(); + $this->customerRepository = $customerRepository ?? new CoreCustomerRepository(); } public function __get($prop_name) @@ -125,6 +124,11 @@ public function getPagarmeCustomerId() return $customer->getPagarmeId()->getValue(); } + /** + * @param string $code + * @param string $pagarmeId + * @return void + */ public function savePagarmeCustomerId($code, $pagarmeId) { $customerService = new CustomerService(); @@ -133,4 +137,22 @@ public function savePagarmeCustomerId($code, $pagarmeId) $customer->setPagarmeId($pagarmeId); $customerService->saveOnPlatform($customer); } + + /** + * @param \WC_Order $wcOrder + * @param boolean|null $createIfNotExists create customer on Pagar.me if not exists + * @return string|\Exception + */ + public function getPagarmeCustomerIdByOrder($wcOrder, $createIfNotExists = true) + { + $customer = $this->customerRepository->findByCode($wcOrder->get_customer_id()); + if ($customer) { + return $customer->getPagarmeId()->getValue(); + } + if (!$createIfNotExists) { + throw new \Exception('Customer not found'); + } + $customer = new CustomerService(); + return $customer->createCustomerByOrder($wcOrder); + } } \ No newline at end of file diff --git a/src/Model/Payment/AbstractPayment.php b/src/Model/Payment/AbstractPayment.php index e0a45ffc..e0260b73 100644 --- a/src/Model/Payment/AbstractPayment.php +++ b/src/Model/Payment/AbstractPayment.php @@ -236,6 +236,7 @@ protected function getBillingAddressFromCustomer($customer, WC_Order $wc_order) if (empty($addressArray)) { $addressArray = $this->getCustomerAddressFromWcOrder($wc_order); } + return [ 'street' => $addressArray["street"], 'complement' => $addressArray["complement"], diff --git a/src/Model/Payment/Voucher/Brands/Ticket.php b/src/Model/Payment/Voucher/Brands/Ticket.php new file mode 100644 index 00000000..a790a6dd --- /dev/null +++ b/src/Model/Payment/Voucher/Brands/Ticket.php @@ -0,0 +1,32 @@ +orders = new Orders; $this->addSupportToSubscription(); $this->setPaymentEnabled(); + $this->logger = new LogService('Renew Subscription'); + parent::__construct($this->logger); } private function addSupportToSubscription(): void @@ -80,9 +80,9 @@ private function addSupportToSubscription(): void ); add_action( 'on_pagarme_response', - [$this, 'addMetaDataCardByResponse'], + [$this, 'saveCardInSubscriptionUsingOrderResponse'], 10, - 2 + 1 ); add_filter( 'woocommerce_subscriptions_update_payment_via_pay_shortcode', @@ -102,31 +102,6 @@ private function setPaymentEnabled() } } - /** - * @return Config - */ - public function getConfig() - { - return $this->config; - } - - public function addMetaDataCardByResponse($orderId, $response) - { - $cardData = $this->getCardDataByResponse($response); - $this->addMetaDataCard($orderId, $cardData); - } - - public function addMetaDataCard($orderId, $cardData) - { - if (!$cardData) { - return; - } - $subscriptions = wcs_get_subscriptions_for_order($orderId); - foreach ($subscriptions as $subscription) { - $this->saveCardInSubscription($cardData, $subscription); - } - } - /** * @param float $amountToCharge * @param WC_Order $order @@ -140,8 +115,7 @@ public function processSubscription($amountToCharge, WC_Order $wc_order) wp_send_json_error(__('Invalid order', 'woo-pagarme-payments')); } $order = new Order($wc_order->get_id()); - $this->createCustomerPagarmeIdOnPlatformIfNotExists($wc_order->get_customer_id(), - $order->get_meta('subscription_renewal')); + $this->getPagarmeCustomer($wc_order); $fields = $this->convertOrderObject($order); $response = $this->orders->create_order( @@ -150,8 +124,9 @@ public function processSubscription($amountToCharge, WC_Order $wc_order) $fields ); - $order->payment_method = $fields['payment_method']; + $order->update_meta('payment_method', $fields['payment_method']); if ($response) { + $this->addChargeIdInProcessSubscription($response, $wc_order->get_id()); $order->update_meta('transaction_id', $response->getPagarmeId()->getValue()); $order->update_meta('pagarme_id', $response->getPagarmeId()->getValue()); $order->update_meta('pagarme_status', $response->getStatus()->getStatus()); @@ -175,17 +150,32 @@ public function processSubscription($amountToCharge, WC_Order $wc_order) } } + public function addChargeIdInProcessSubscription($response, $orderId){ + $subscription = $this->getSubscription($orderId); + + if ($subscription->get_payment_method() != 'woo-pagarme-payments-credit_card') { + return; + } + $cardData = $this->getCardToProcessSubscription($subscription); + + if (isset($cardData['chargeId']) && !empty($cardData['chargeId'])) { + return; + } + $this->saveCardInSubscriptionUsingOrderResponse($response); + } + public function processChangePaymentSubscription($subscription) { try { - $subscription = new \WC_Subscription($subscription); + $subscription = new WC_Subscription($subscription); $newPaymentMethod = wc_clean($_POST['payment_method']); + $this->saveCardInSubscriptionOrder(["payment_method" => $newPaymentMethod], $subscription); if ('woo-pagarme-payments-credit_card' == $newPaymentMethod) { $pagarmeCustomer = $this->getPagarmeCustomer($subscription); $cardResponse = $this->createCreditCard($pagarmeCustomer); - $this->saveCardInSubscription($cardResponse, $subscription); - \WC_Subscriptions_Change_Payment_Gateway::update_payment_method($subscription, $newPaymentMethod); + $this->saveCardInSubscriptionOrder($cardResponse, $subscription); } + \WC_Subscriptions_Change_Payment_Gateway::update_payment_method($subscription, $newPaymentMethod); return [ 'result' => 'success', 'redirect' => $this->payment->get_return_url($subscription) @@ -213,7 +203,7 @@ public function processFreeTrialSubscription($wcOrder) if ('credit_card' == $paymentMethod) { $pagarmeCustomer = $this->getPagarmeCustomer($wcOrder); $cardResponse = $this->createCreditCard($pagarmeCustomer); - $this->addMetaDataCard($wcOrder->get_id(), $cardResponse); + $this->saveCardDataToOrderAndSubscriptions($wcOrder->get_id(), $cardResponse); } WC()->cart->empty_cart(); $order = new Order($wcOrder->get_id()); @@ -239,98 +229,74 @@ public function processFreeTrialSubscription($wcOrder) } } - private function createCustomerPagarmeIdOnPlatformIfNotExists($customerCode, $subscriptionId) + /** + * @return boolean + */ + public static function hasSubscriptionProductInCart() { - $customer = new Customer($customerCode, new SavedCardRepository(), new CustomerRepository()); - if($customer->getPagarmeCustomerId() !== false) { - return; + if (!self::hasSubscriptionPlugin()) { + return false; } - $subscription = new \WC_Subscription($subscriptionId); - $customerId = $this->getPagarmeIdFromLastValidOrder($subscription); - $customer->savePagarmeCustomerId($customerCode, $customerId); + return \WC_Subscriptions_Cart::cart_contains_subscription() || wcs_cart_contains_renewal(); } - private function getPagarmeIdFromLastValidOrder($subscription) + /** + * @return boolean + */ + public function hasOneInstallmentPeriodInCart() { - foreach ($subscription->get_related_orders() as $orderId) { - $order = new Order($orderId); - if(!$order->get_meta('pagarme_response_data')){ - continue; - } - $pagarmeResponse = json_decode($order->get_meta('pagarme_response_data'), true); - if(!array_key_exists('customer', $pagarmeResponse)) { - continue; - } - return $pagarmeResponse['customer']['pagarmeId']; + if (!$this->hasSubscriptionPlugin()) { + return false; } - throw new \Exception("Unable to find a PagarId in previous request responses"); - } - - private function getPagarmeCustomer($subscription) - { - $customer = new Customer($subscription->get_user_id(), new SavedCardRepository(), new CustomerRepository()); - if (!$customer->getPagarmeCustomerId()) { - $customer = new CustomerService(); - return $customer->createCustomerByOrder($subscription); + $cartProducts = WC()->cart->cart_contents; + $productsPeriods = []; + foreach ($cartProducts ?? [] as $product) { + $productsPeriods[] = WC_Subscriptions_Product::get_period($product['product_id']); } - return $customer->getPagarmeCustomerId(); - } - private function createCreditCard($pagarmeCustomer) - { - $data = wc_clean($_POST['pagarme']); - $card = new CardService(); - if ($data['credit_card']['cards'][1]['wallet-id']) { - $cardId = $data['credit_card']['cards'][1]['wallet-id']; - return $card->getCard($cardId, $pagarmeCustomer); - } - $cardInfo = $data['credit_card']['cards'][1]; - $response = $card->create($cardInfo['token'], $pagarmeCustomer); - if (array_key_exists('save-card', $cardInfo) && $cardInfo['save-card'] === "1") { - $card->saveOnWalletPlatform($response); + $noInstallmentsPeriods = array_intersect(self::ONE_INSTALLMENT_PERIODS, $productsPeriods); + if (!empty($noInstallmentsPeriods)) { + return true; } - return $response; - } + return false; + } /** - * Save card information on table post_meta - * @param array $card - * @param \WC_Subscription $subscription - * @return void + * @return boolean */ - private function saveCardInSubscription(array $card, \WC_Subscription $subscription) + public static function hasSubscriptionFreeTrial() { - $key = '_pagarme_payment_subscription'; - $value = json_encode($card); - if (FeatureCompatibilization::isHposActivated()) { - $subscription->update_meta_data($key, Utils::rm_tags($value)); - $subscription->save(); - return; + if (!self::hasSubscriptionPlugin()) { + return false; } - update_metadata('post', $subscription->get_id(), $key, $value); - $subscription->save(); + return self::hasSubscriptionProductInCart() && \WC_Subscriptions_Cart::all_cart_items_have_free_trial(); } /** - * @param WC_Order $order + * @param Order $order + * * @return array */ private function convertOrderObject(Order $order) { $fields = [ - 'payment_method' => $this->formatPaymentMethod($order->wc_order->get_payment_method()) + 'payment_method' => $this->formatPaymentMethod($order->getWcOrder()->get_payment_method()) ]; - $card = $this->getCardSubscriptionData($order); - if ($card !== null) { - $fields['card_order_value'] = $order->wc_order->get_total(); + + $card = $this->getCardData($order->getWcOrder()); + + if (!empty($card)) { + $fields['card_order_value'] = $order->getWcOrder()->get_total(); $fields['brand'] = $card['brand']; $fields['installments'] = 1; $fields['card_id'] = $card['cardId']; $fields['pagarmetoken'] = $card['cardId']; $fields['recurrence_cycle'] = "subsequent"; + $fields['payment_origin'] = isset($card['chargeId']) ? ["charge_id" => $card['chargeId']] : null; } + return $fields; } @@ -344,34 +310,38 @@ private function formatPaymentMethod($paymentMethod) return str_replace('-', '_', $paymentMethod); } - private function getCardSubscriptionData($order) + /** + * @param $orderId + * + * @return WC_Subscription|null + */ + protected function getSubscription($orderId) { - $cardData = $order->get_meta("pagarme_payment_subscription"); - if (!$cardData) { - return false; + $subscription = $this->getAllSubscriptionsForOrder($orderId); + if(!$subscription) { + return null; } - return json_decode($cardData, true); + return current($subscription); } - - private function getCardDataByResponse($response) + /** + * @param $order int + * @return array + */ + protected function getAllSubscriptionsForOrder($orderId) { - $charges = $this->getChargesByResponse($response); - $transactions = $this->getTransactionsByCharges($charges); - $cardData = $this->getCardDataByTransaction($transactions); - if (!$cardData) { - return $cardData; + $order = wc_get_order($orderId); + $subscriptions = wcs_get_subscriptions_for_renewal_order($order); + if (!$subscriptions) { + $subscriptions = wcs_get_subscriptions_for_order($order); } - return [ - 'cardId' => $cardData->getPagarmeId(), - 'brand' => $cardData->getBrand()->getName(), - 'holder_name' => $cardData->getOwnerName(), - 'first_six_digits' => $cardData->getFirstSixDigits()->getValue(), - 'last_four_digits' => $cardData->getLastFourDigits()->getValue() - ]; + return $subscriptions; } - private function getChargesByResponse($response) + /** + * @return \Pagarme\Core\Kernel\Aggregates\Charge|boolean; + */ + protected function getChargesByResponse($response) { if (!$response) { return false; @@ -379,46 +349,32 @@ private function getChargesByResponse($response) return current($response->getCharges()); } - private function getTransactionsByCharges($charge) - { - if (!$charge) { - return false; - } - return current($charge->getTransactions()); - } - - private function getCardDataByTransaction($transactions) - { - if (!$transactions) { - return false; - } - return $transactions->getCardData(); - } - /** - * @return boolean + * @param \Pagarme\Core\Kernel\Aggregates\Charge $charge + * @return \Pagarme\Core\Kernel\Aggregates\Transaction|boolean */ - public static function hasSubscriptionProductInCart() + protected function getTransactionsByCharges($charge) { - if (!self::hasSubscriptionPlugin()) { + if (!$charge) { return false; } - return \WC_Subscriptions_Cart::cart_contains_subscription() || wcs_cart_contains_renewal(); + return current($charge->getTransactions()); } /** - * @return boolean + * @param \Pagarme\Core\Kernel\Aggregates\Transaction $transactions + * @return \Pagarme\Core\Payment\Aggregates\SavedCard|boolean */ - public static function hasSubscriptionFreeTrial() + protected function getCardDataByTransaction($transactions) { - if (!self::hasSubscriptionPlugin()) { + if (!$transactions) { return false; } - return self::hasSubscriptionProductInCart() && \WC_Subscriptions_Cart::all_cart_items_have_free_trial(); + return $transactions->getCardData(); } /** - * @return boolean + * @return string|null */ public static function getRecurrenceCycle() { @@ -453,10 +409,7 @@ public static function isChangePaymentSubscription() public static function canUpdatePaymentMethod($update, $new_payment_method, $subscription) { - if ('woo-pagarme-payments-credit_card' === $new_payment_method) { - $update = false; - } - return $update; + return false; } /** @@ -466,25 +419,34 @@ public function allowInstallments(): bool { return wc_string_to_bool($this->config->getData('cc_subscription_installments')); } + /** - * @return boolean + * @param $fields array + * @param $order WC_Order + * @return void */ - public function hasOneInstallmentPeriodInCart(): bool { - if (!$this->hasSubscriptionPlugin()) { - return false; - } - - $cartProducts = WC()->cart->cart_contents; - $productsPeriods = []; - foreach ($cartProducts ?? [] as $product) { - $productsPeriods[] = WC_Subscriptions_Product::get_period($product['product_id']); + public function isSameCardInSubscription(&$fields, $order) + { + $subscription = $this->getSubscription($order->get_id()); + $dataCard = $this->getCardToProcessSubscription($order); + if(empty($dataCard)){ + return; } - - $noInstallmentsPeriods = array_intersect(self::ONE_INSTALLMENT_PERIODS, $productsPeriods); - if (!empty($noInstallmentsPeriods)) { - return true; + if($dataCard['cardId'] == $fields['card_id']){ + $fields['payment_origin'] = ["charge_id" => $dataCard['chargeId']]; + return; } + unset($dataCard['chargeId']); + $this->saveCardInSubscriptionOrder($dataCard, $subscription); + } - return false; + /** + * @param \WC_Order $wcOrder + * @return string|\Exception + */ + private function getPagarmeCustomer($wcOrder) + { + $customer = new Customer($wcOrder->get_customer_id()); + return $customer->getPagarmeCustomerIdByOrder($wcOrder, true); } } diff --git a/src/Model/SubscriptionMeta.php b/src/Model/SubscriptionMeta.php new file mode 100644 index 00000000..042416cb --- /dev/null +++ b/src/Model/SubscriptionMeta.php @@ -0,0 +1,158 @@ +logger = $logger; + } + /** + * @param int $orderId + * @param \Pagarme\Core\Kernel\Aggregates\Order $response + * @return void + */ + public function saveCardInSubscriptionUsingOrderResponse($response) + { + $platformOrder = $response->getPlatformOrder()->getPlatformOrder(); + $subscription = $this->getSubscription($platformOrder->get_id()); + if($subscription == null) { + return; + } + $subscriptionCard = $this->getCardToProcessSubscription($subscription); + $cardData = $this->getCardDataByResponse($response); + if ( + isset($subscriptionCard['chargeId']) && + wcs_order_contains_early_renewal($platformOrder) == true + ) { + return; + } + $this->saveCardDataToOrderAndSubscriptions($platformOrder->get_id(), $cardData); + } + + public function saveCardDataToOrderAndSubscriptions($orderId, $cardData) + { + if (!$cardData) { + return; + } + + $order = wc_get_order($orderId); + $this->saveCardInSubscriptionOrder($cardData, $order); + $subscriptions = $this->getAllSubscriptionsForOrder($orderId); + foreach ($subscriptions as $subscription) { + $this->saveCardInSubscriptionOrder($cardData, $subscription); + } + } + + protected function createCreditCard($pagarmeCustomer) + { + $data = wc_clean($_POST['pagarme']); + $card = new CardService(); + if ($data['credit_card']['cards'][1]['wallet-id']) { + $cardId = $data['credit_card']['cards'][1]['wallet-id']; + return $card->getCard($cardId, $pagarmeCustomer); + } + $cardInfo = $data['credit_card']['cards'][1]; + $response = $card->create($cardInfo['token'], $pagarmeCustomer); + if (array_key_exists('save-card', $cardInfo) && $cardInfo['save-card'] === "1") { + $card->saveOnWalletPlatform($response); + } + return $response; + } + + /** + * Save card information on table post_meta or wc_order_meta + * + * @param array $card + * @param WC_Subscription|WC_Order $order + * + * @return void + */ + protected function saveCardInSubscriptionOrder(array $card, $order) + { + if ( + empty($card) + || (!is_a($order, 'WC_Order') && !is_a($order, 'WC_Subscription')) + ) { + return; + } + $value = json_encode($card); + if (FeatureCompatibilization::isHposActivated()) { + $order->update_meta_data(self::PAYMENT_DATA_KEY, Utils::rm_tags($value)); + $order->save(); + return; + } + update_metadata('post', $order->get_id(), self::PAYMENT_DATA_KEY, $value); + $order->save(); + } + + /** + * @param \WC_Order | \WC_Subscription $order + * @return array + */ + protected function getCardToProcessSubscription($order) + { + $cardData = get_metadata( + 'post', + $order->get_id(), + self::PAYMENT_DATA_KEY, + true + ); + + if (empty($cardData) && FeatureCompatibilization::isHposActivated()) { + $cardData = $order->get_meta(self::PAYMENT_DATA_KEY); + } + + if (empty($cardData)) { + $this->logger->info('Card data not found in the current order.'); + return null; + } + + return json_decode($cardData, true); + } + + /** + * @param mixed $response + * @return mixed + */ + protected function getCardDataByResponse($response) + { + $charges = $this->getChargesByResponse($response); + $transactions = $this->getTransactionsByCharges($charges); + $cardData = $this->getCardDataByTransaction($transactions); + if (!$cardData) { + return $cardData; + } + return [ + 'cardId' => $cardData->getPagarmeId(), + 'brand' => $cardData->getBrand()->getName(), + 'holder_name' => $cardData->getOwnerName(), + 'first_six_digits' => $cardData->getFirstSixDigits()->getValue(), + 'last_four_digits' => $cardData->getLastFourDigits()->getValue(), + 'chargeId' => $charges->getPagarmeId(), + ]; + } + + /** + * @param $order + * @return array|null + */ + protected function getCardData($order) + { + $card = $this->getCardToProcessSubscription($order); + + if (empty($card)) { + $subscription = $this->getSubscription($order->ID); + return $this->getCardToProcessSubscription($subscription); + } + + return $card; + } +} \ No newline at end of file diff --git a/src/Service/CustomerService.php b/src/Service/CustomerService.php index 2b12432f..e04ed5cc 100644 --- a/src/Service/CustomerService.php +++ b/src/Service/CustomerService.php @@ -3,6 +3,7 @@ namespace Woocommerce\Pagarme\Service; use WC_Customer; +use Woocommerce\Pagarme\Helper\Utils; use Woocommerce\Pagarme\Model\CoreAuth; use Pagarme\Core\Middle\Model\Customer; use Pagarme\Core\Middle\Proxy\CustomerProxy; @@ -63,33 +64,47 @@ public function createAddress($addressData) $address->setStreet($addressData['street']); $address->setNumber($addressData['number']); $address->setComplement($addressData['complement']); + return $address; } - + public function extractCustomerDataByWcOrder($wcOrder) { $billingData = $wcOrder->get_data()['billing']; + $document = $wcOrder->get_meta('_billing_cpf'); if (empty($document)) { $document = $wcOrder->get_meta('_billing_cnpj'); } - return [ + if (empty($document)) { + $document = $wcOrder->get_meta('_billing_document'); + } + + $customerData = [ 'code' => $wcOrder->get_customer_id(), 'email' => $billingData['email'], 'name' => $billingData['first_name'] . ' ' . $billingData['last_name'], 'document' => $document, - 'document_type' => empty($wcOrder->get_meta('_billing_cnpj')) ? 'cpf' : 'cnpj', + 'document_type' => Utils::getDocumentTypeByDocumentNumber($document), 'home_phone' => $billingData['phone'], 'mobile_phone' => $wcOrder->get_meta('_billing_cellphone'), 'street' => $billingData['street'], - 'neighborhood' => $billingData['neighborhood'], - 'number' => $billingData['number'], 'country' => $billingData['country'], 'city' => $billingData['city'], 'state' => $billingData['state'], 'complement' => $billingData['complement'], 'zipcode' => $billingData['postcode'] ]; + + if (!empty($billingData['number'])) { + $customerData['number'] = $billingData['number']; + } + + if (!empty($billingData['neighborhood'])) { + $customerData['neighborhood'] = $billingData['neighborhood']; + } + + return $customerData; } public function saveOnPlatform($customer) @@ -116,4 +131,4 @@ public function save($customer) $wcCustomer->add_meta_data('_pagarme_customer_id', $customer->getPagarmeId(), true); $wcCustomer->save(); } -} \ No newline at end of file +} diff --git a/tests/Block/Checkout/GatewayTest.php b/tests/Block/Checkout/GatewayTest.php index 8259af90..51fc3f3e 100644 --- a/tests/Block/Checkout/GatewayTest.php +++ b/tests/Block/Checkout/GatewayTest.php @@ -49,7 +49,7 @@ public function testCartTotalsWithoutOrderPayShouldReturnCartTotal() $orderMock = Mockery::mock(WC_Order::class); $orderMock->shouldReceive('get_total') - ->andReturn(10); + ->andReturn(10); Brain\Monkey\Functions\stubs([ 'wc_get_order' => $orderMock diff --git a/tests/Model/CheckoutTest.php b/tests/Model/CheckoutTest.php index a6410e90..c160efa2 100644 --- a/tests/Model/CheckoutTest.php +++ b/tests/Model/CheckoutTest.php @@ -11,6 +11,7 @@ use Woocommerce\Pagarme\Model\Gateway; use Woocommerce\Pagarme\Model\Checkout; use Woocommerce\Pagarme\Controller\Orders; +use Woocommerce\Pagarme\Model\Subscription; use Woocommerce\Pagarme\Model\WooOrderRepository; use Woocommerce\Pagarme\Model\Payment\Data\PaymentRequestInterface; use Woocommerce\Pagarme\Model\Payment\Data\PaymentRequest; @@ -44,6 +45,7 @@ public function tearDown(): void Brain\Monkey\tearDown(); } + public function testProcessWithTdsAuthenticatedCreditCardPaymentMethodShouldSetAuthenticationNode() { $gatewayMock = Mockery::mock(Gateway::class); @@ -51,6 +53,10 @@ public function testProcessWithTdsAuthenticatedCreditCardPaymentMethodShouldSetA $ordersMock = Mockery::mock(Orders::class); $wooOrderRepositoryMock = Mockery::mock(WooOrderRepository::class); + $subscriptionMock = Mockery::mock('alias:'.Subscription::class); + $subscriptionMock->shouldReceive('hasSubscriptionProductInCart')->andReturn(false); + $subscriptionMock->shouldReceive('getRecurrenceCycle')->andReturn(null); + $_SERVER['HTTP_X_REQUESTED_WITH'] = 'xmlhttprequest'; $_SERVER['REQUEST_METHOD'] = 'POST'; @@ -85,6 +91,9 @@ public function testProcessWithTdsAuthenticatedCreditCardPaymentMethodShouldSetA $subscriptionMock = Mockery::mock('alias:Woocommerce\Pagarme\Model\Subscription'); $subscriptionMock->shouldReceive('getRecurrenceCycle') ->andReturnNull(); + + $subscriptionMock->shouldReceive('getPaymentOrigin') + ->andReturnNull(); $orderIdMock = Mockery::mock(OrderId::class); $orderIdMock->shouldReceive('getValue') @@ -130,6 +139,7 @@ public function testProcessWithTdsAuthenticatedCreditCardPaymentMethodShouldSetA ->andReturn($wcOrderMock); $orderModelMock->shouldReceive('update_meta') ->andReturn([]); + $wcCheckoutMock = Mockery::mock(WC_Cart::class); $wcCheckoutMock->shouldReceive('empty_cart') ->andReturnSelf(); diff --git a/vendor/pagarme/ecommerce-module-core/src/Kernel/Services/APIService.php b/vendor/pagarme/ecommerce-module-core/src/Kernel/Services/APIService.php index 5611cc92..3a9f2cc9 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Kernel/Services/APIService.php +++ b/vendor/pagarme/ecommerce-module-core/src/Kernel/Services/APIService.php @@ -2,6 +2,7 @@ namespace Pagarme\Core\Kernel\Services; +use Automattic\WooCommerce\Blocks\Utils\CartCheckoutUtils; use Exception; use PagarmeCoreApiLib\APIException; use PagarmeCoreApiLib\Configuration; @@ -171,6 +172,7 @@ private function getRequestMetaData($orderRequest) $metadata->moduleVersion = $versionService->getModuleVersion(); $metadata->coreVersion = $versionService->getCoreVersion(); $metadata->platformVersion = $versionService->getPlatformVersion(); + $metadata->checkoutBlocks = CartCheckoutUtils::is_checkout_block_default(); if($this->hasCreditCardInPayments($orderRequest->payments) && !empty(MPSetup::getInstallmentType())){ $metadata->interestType = MPSetup::getInstallmentType(); } diff --git a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/CardBrand.php b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/CardBrand.php index 165e8850..18fb4dbe 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/CardBrand.php +++ b/vendor/pagarme/ecommerce-module-core/src/Kernel/ValueObjects/CardBrand.php @@ -26,6 +26,7 @@ final class CardBrand extends AbstractValueObject CONST SODEXO_PREMIUM = "SodexoPremium"; CONST SODEXO_REFEICAO = "SodexoRefeicao"; CONST SODEXO_COMBUSTIVEL = "SodexoCombustivel"; + CONST TICKET = "Ticket"; CONST VR = "VR"; CONST ALELO = "Alelo"; CONST BANESE = "Banese"; @@ -134,6 +135,11 @@ static public function sodexocombustivel() return new self(self::SODEXO_COMBUSTIVEL); } + static public function ticket() + { + return new self(self::TICKET); + } + static public function vr() { return new self(self::VR); diff --git a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php index b4f61292..6bcedd5f 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php +++ b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Account.php @@ -11,10 +11,6 @@ class Account extends ModelWithErrors { const ACCOUNT_DISABLED = 'accountDisabled'; - const DOMAIN_EMPTY = 'domainEmpty'; - - const DOMAIN_INCORRECT = 'domainIncorrect'; - const WEBHOOK_INCORRECT = 'webhookIncorrect'; const MULTIPAYMENTS_DISABLED = 'multiPaymentsDisabled'; @@ -242,7 +238,6 @@ public function setDebitCardSettings($debitCardSettings) public function validate($storeSettings = null) { $this->validateAccountEnabled(); - $this->validateDomain($storeSettings); $this->validateWebhooks($storeSettings); $this->validateMultiBuyer(); $this->validateMultiPayments(); @@ -265,34 +260,6 @@ private function validateAccountEnabled() } } - /** - * @param StoreSettings|null $storeSettings - * @return void - */ - private function validateDomain($storeSettings = null) - { - $domains = $this->getDomains(); - if (empty($domains) && (empty($storeSettings) || !$storeSettings->isSandbox())) { - $this->addError(self::DOMAIN_EMPTY); - return; - } - - if ($this->canNotValidateUrlSetting($storeSettings)) { - return; - } - - $siteUrls = $storeSettings->getStoreUrls(); - foreach ($domains as $domain) { - foreach ($siteUrls as $siteUrl) { - if (strpos($siteUrl, $domain) !== false) { - return; - } - } - } - - $this->addError(self::DOMAIN_INCORRECT); - } - /** * @param StoreSettings|null $storeSettings * @return void diff --git a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php index 10c777a7..e0609ca9 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Middle/Model/Customer/Address.php @@ -93,15 +93,24 @@ public function getNumber() { return $this->number ?? ""; } - + public function getComplement() { return $this->complement ?? ""; } - + public function getLine1() { - $address = [$this->getNumber(), $this->getStreet(), $this->getNeighborhood()]; + if (!empty($this->getNumber())) { + $address[] = $this->getNumber(); + } + + $address[] = $this->getStreet(); + + if (!empty($this->getNeighborhood())) { + $address[] = $this->getNeighborhood(); + } + return implode(self::ADDRESS_SEPARATOR, $address); } diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php index a692f65a..b1ac1372 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Address.php @@ -78,8 +78,7 @@ public function setNumber($number) $this->number = substr($numberWithoutLineBreaks, 0, 15); - if (empty($this->number) && ($this->number === null || !is_numeric(trim($this->number)))) { - + if (!empty($this->number) && !is_numeric(trim($this->number))) { $inputName = $this->i18n->getDashboard('number'); $message = $this->i18n->getDashboard( "The %s should not be empty!", @@ -107,14 +106,8 @@ public function getStreet() */ public function setStreet($street) { - $streetWithoutComma = str_replace( - self::ADDRESS_LINE_SEPARATOR, - '', - $street ?? '' - ); - $streetWithoutLineBreaks = StringFunctionsHelper::removeLineBreaks( - $streetWithoutComma + $street ); $this->street = substr($streetWithoutLineBreaks, 0, 64); @@ -137,7 +130,7 @@ public function setStreet($street) */ public function getNeighborhood() { - return $this->neighborhood; + return $this->neighborhood ?? ''; } /** @@ -159,17 +152,6 @@ public function setNeighborhood($neighborhood) $this->neighborhood = substr($neighborhoodWithoutLineBreaks, 0, 64); - if (empty($this->neighborhood)) { - - $inputName = $this->i18n->getDashboard('neighborhood'); - $message = $this->i18n->getDashboard( - "The %s should not be empty!", - $inputName - ); - - throw new \Exception($message, 400); - } - return $this; } @@ -289,12 +271,17 @@ public function setCountry($country) public function getLine1() { - $line = []; - $line[] = $this->getNumber(); + if ($this->getNumber()) { + $line[] = $this->getNumber(); + } + $line[] = $this->getStreet(); - $line[] = $this->getNeighborhood(); - return implode (self::ADDRESS_LINE_SEPARATOR, $line); + if ($this->getNeighborhood()) { + $line[] = $this->getNeighborhood(); + } + + return implode(self::ADDRESS_LINE_SEPARATOR, $line); } public function getLine2() @@ -336,7 +323,7 @@ public function setState($state) /** * Specify data which should be serialized to JSON * @link https://php.net/manual/en/jsonserializable.jsonserialize.php - * @return string data which can be serialized by json_encode, + * @return \stdClass data which can be serialized by json_encode, * which is a value of any type other than a resource. * @since 5.4.0 */ @@ -345,10 +332,10 @@ public function jsonSerialize() { $obj = new \stdClass(); - $obj->number = $this->number; $obj->street = $this->street; - $obj->neighborhood = $this->neighborhood; + $obj->number = $this->number; $obj->complement = $this->complement; + $obj->neighborhood = $this->neighborhood; $obj->zipCode = $this->zipCode; $obj->city = $this->city; $obj->state = $this->state; @@ -366,16 +353,16 @@ public function convertToSDKRequest() { $addressRequest = new CreateAddressRequest(); - $addressRequest->city = $this->getCity(); + $addressRequest->street = $this->getStreet(); + $addressRequest->number = $this->getNumber(); $addressRequest->complement = $this->getComplement(); - $addressRequest->country = $this->getCountry(); - $addressRequest->line1 = $this->getLine1(); - $addressRequest->line2 = $this->getLine2(); $addressRequest->neighborhood = $this->getNeighborhood(); - $addressRequest->number = $this->getNumber(); + $addressRequest->city = $this->getCity(); $addressRequest->state = $this->getState(); - $addressRequest->street = $this->getStreet(); + $addressRequest->country = $this->getCountry(); $addressRequest->zipCode = $this->getZipCode(); + $addressRequest->line1 = $this->getLine1(); + $addressRequest->line2 = $this->getLine2(); return $addressRequest; } diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Payments/AbstractCreditCardPayment.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Payments/AbstractCreditCardPayment.php index c2fcf176..a3d5dbf2 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Payments/AbstractCreditCardPayment.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Aggregates/Payments/AbstractCreditCardPayment.php @@ -24,6 +24,8 @@ abstract class AbstractCreditCardPayment extends AbstractPayment /** @var string */ protected $recurrenceCycle; /** @var string */ + protected $paymentOrigin; + /** @var string */ protected $statementDescriptor; /** @var boolean */ protected $capture; @@ -140,6 +142,16 @@ public function setRecurrenceCycle($recurrenceCycle) $this->recurrenceCycle = $recurrenceCycle; } + public function getPaymentOrigin() + { + return $this->paymentOrigin; + } + + public function setPaymentOrigin($paymentOrigin) + { + $this->paymentOrigin = $paymentOrigin; + } + /** * @return string */ @@ -262,6 +274,7 @@ protected function convertToPrimitivePaymentRequest() $cardRequest->capture = $this->isCapture(); $cardRequest->installments = $this->getInstallments(); $cardRequest->recurrenceCycle = $this->getRecurrenceCycle(); + $cardRequest->paymentOrigin = $this->getPaymentOrigin(); $cardRequest->statementDescriptor = $this->getStatementDescriptor(); if (!empty($this->getAuthentication())) { $cardRequest->authentication = $this->getAuthenticationSDK(); diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php index 7e8b4403..7ada97b5 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/AddressFactory.php @@ -14,8 +14,8 @@ public function createFromJson($json) $address->setStreet($data->street); $address->setNumber($data->number); - $address->setNeighborhood($data->neighborhood); $address->setComplement($data->complement); + $address->setNeighborhood($data->neighborhood); $address->setCity($data->city); $address->setState($data->state); $address->setZipCode($data->zipCode); @@ -23,4 +23,4 @@ public function createFromJson($json) return $address; } -} \ No newline at end of file +} diff --git a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/PaymentFactory.php b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/PaymentFactory.php index 62e419e0..74f86d7f 100644 --- a/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/PaymentFactory.php +++ b/vendor/pagarme/ecommerce-module-core/src/Payment/Factories/PaymentFactory.php @@ -128,6 +128,7 @@ private function createBasePayments( $payment->setAmount($cardData->amount); $payment->setInstallments($cardData->installments); $payment->setRecurrenceCycle($cardData->recurrenceCycle ?? null); + $payment->setPaymentOrigin($cardData->paymentOrigin ?? null); if (!empty($cardData->authentication)) { $payment->setAuthentication(Authentication::createFromStdClass($cardData->authentication)); } diff --git a/vendor/pagarme/pagarmecoreapi/src/Models/CreateCreditCardPaymentRequest.php b/vendor/pagarme/pagarmecoreapi/src/Models/CreateCreditCardPaymentRequest.php index 3852ade3..7c665ca4 100644 --- a/vendor/pagarme/pagarmecoreapi/src/Models/CreateCreditCardPaymentRequest.php +++ b/vendor/pagarme/pagarmecoreapi/src/Models/CreateCreditCardPaymentRequest.php @@ -120,6 +120,13 @@ class CreateCreditCardPaymentRequest implements JsonSerializable */ public $recurrenceCycle; + /** + * Defines whether the card has been used one or more times. + * @maps payment_origin + * @var string|null $paymentOrigin public property + */ + public $paymentOrigin; + /** * Constructor to set initial or default values of member properties * @param integer $installments Initialization value for $this->installments @@ -145,11 +152,13 @@ class CreateCreditCardPaymentRequest implements JsonSerializable * >recurrencyCycle * @param string $recurrenceCycle Initialization value for $this- * >recurrenceCycle + * @param string $paymentOrigin Initialization value for $this- + * >paymentOrigin */ public function __construct() { switch (func_num_args()) { - case 16: + case 17: $this->installments = func_get_arg(0); $this->statementDescriptor = func_get_arg(1); $this->card = func_get_arg(2); @@ -166,6 +175,7 @@ public function __construct() $this->operationType = func_get_arg(13); $this->recurrencyCycle = func_get_arg(14); $this->recurrenceCycle = func_get_arg(15); + $this->paymentOrigin = func_get_arg(16); break; default: @@ -198,6 +208,7 @@ public function jsonSerialize() $json['operation_type'] = $this->operationType; $json['recurrency_cycle'] = $this->recurrencyCycle; $json['recurrence_cycle'] = $this->recurrenceCycle; + $json['payment_origin'] = $this->paymentOrigin; return $json; } diff --git a/webpack.config.js b/webpack.config.js index 658602b4..3ccbb043 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -11,7 +11,6 @@ module.exports = { new DependencyExtractionWebpackPlugin(), ], entry: { - // googlepay: './assets/javascripts/front/reactCheckout/payments/GooglePay/index.js', pix: './assets/javascripts/front/reactCheckout/payments/Pix/index.js', billet: './assets/javascripts/front/reactCheckout/payments/Billet/index.js', credit_card: './assets/javascripts/front/reactCheckout/payments/CreditCard/index.js', diff --git a/woo-pagarme-payments.php b/woo-pagarme-payments.php index 51b2d877..04ad4b0b 100644 --- a/woo-pagarme-payments.php +++ b/woo-pagarme-payments.php @@ -1,7 +1,7 @@ + ?>
@@ -79,7 +79,7 @@ function wcmpRenderAdminNoticeHtml($message, $buttons = [], $type = 'error', $in
- $label, - 'url' => $url, - 'type' => $type, + 'label' => $label, + 'url' => $url, + 'type' => $type, 'target' => $target, - 'class' => $class + 'class' => $class ); } /** * @param array $buttons Array of arrays, each containing the keys `label`, `url`, `type`, `target` and `class`. + * * @return string */ function wcmpAddNoticeButton($buttons) @@ -138,20 +140,23 @@ function wcmpAdminNoticePhpVersion() if (version_compare(PHP_VERSION, '7.1', '<')) { wcmpLoadNotice('AdminNoticePhpVersion'); + return; } -function wcmpIsPluginInstalled($pluginBasename) { +function wcmpIsPluginInstalled($pluginBasename) +{ $isInstalled = false; if (function_exists('get_plugins')) { - $allPlugins = get_plugins(); + $allPlugins = get_plugins(); $isInstalled = !empty($allPlugins[$pluginBasename]); } return $isInstalled; } -function wcmpGetPluginButton($pluginBasename, $pluginName) { +function wcmpGetPluginButton($pluginBasename, $pluginName) +{ $button = []; if (wcmpIsPluginInstalled($pluginBasename) && current_user_can('install_plugins')) { @@ -195,7 +200,7 @@ function wcmpAdminNoticePermalink() wcmpRenderAdminNoticeHtml( __( 'Permalink structure in Wordpress Settings must be different from “Plain”. ' . - 'Please correct this setting to be able to transact with Pagar.me.', + 'Please correct this setting to be able to transact with Pagar.me.', 'woo-pagarme-payments' ), array( @@ -213,35 +218,36 @@ function wcmpAdminNoticeCheckoutFields() return; } + WC()->session = new WC_Session_Handler; + WC()->customer = new WC_Customer; + $billingFields = WC()->checkout->get_checkout_fields()['billing']; + $missingFields = []; $requiredFields = [ 'billing_cpf', 'billing_cnpj', + 'billing_document', 'billing_first_name', - 'billing_last_name', + 'billing_last_name' ]; + if (!(new Config())->getAllowNoAddress()) { $requiredFields[] = 'billing_address_1'; - $requiredFields[] = 'billing_number'; $requiredFields[] = 'billing_address_2'; - $requiredFields[] = 'billing_neighborhood'; $requiredFields[] = 'billing_country'; $requiredFields[] = 'billing_city'; $requiredFields[] = 'billing_state'; $requiredFields[] = 'billing_postcode'; } - $checkoutFields = WC()->countries->get_address_fields(WC()->countries->get_base_country()); foreach ($requiredFields as $field) { - if (!array_key_exists($field, $checkoutFields)) { + if (!array_key_exists($field, $billingFields)) { $missingFields[] = $field; } } - if ((in_array('billing_cpf', $missingFields) && !in_array('billing_cnpj', $missingFields)) || - (in_array('billing_cnpj', $missingFields) && !in_array('billing_cpf', $missingFields)) - ) { - array_shift($missingFields); + if (hasAnyBillingDocument($missingFields)) { + $missingFields = array_slice($missingFields, 2); } if (empty($missingFields)) { @@ -256,21 +262,17 @@ function wcmpAdminNoticeCheckoutFields() } $message .= '

'; - $message .= __('Please, make sure to include them for Pagar.me module to work.', 'woo-pagarme-payments'); - $message .= '

'; $message .= sprintf( - __('You can install %s or any other plugin of your choice to add the missing fields. %sRead ' - . 'documentation »%s', 'woo-pagarme-payments'), - sprintf( - 'Brazilian Market on WooCommerce', - BRAZILIAN_MARKET_URL - ), + __("Please, make sure to include them for Pagar.me plugin to work. If you are customizing the " + . "checkout, the address fields must have the 'name' attribute exactly as listed above. %sRead " + . "documentation »%s", "woo-pagarme-payments"), sprintf( '', PAGARME_REQUIREMENTS_URL ), '' ); + $message .= '

'; wcmpRenderAdminNoticeHtml($message); } @@ -289,6 +291,12 @@ function wcmpLoadInstances() do_action('wcmp_init'); } +/** + * @return void + * @uses wcmpAdminNoticeWoocommerce() + * @uses wcmpAdminNoticePermalink() + * @uses wcmpAdminNoticeCheckoutFields() + */ function wcmpPluginsLoadedCheck() { $woocommerce = class_exists('WooCommerce'); @@ -311,9 +319,20 @@ function wcmpPluginsLoadedCheck() } add_action('plugins_loaded', 'wcmpPluginsLoadedCheck', 0); -add_action( 'before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); +add_action('before_woocommerce_init', 'checkCompatibilityWithFeatures', 0); add_action('woocommerce_blocks_loaded', 'addWoocommerceSupportedBlocks'); +function hasAnyBillingDocument($missingFields) +{ + $hasCpf = in_array('billing_cpf', $missingFields); + $hasCnpj = in_array('billing_cnpj', $missingFields); + $hasDocument = in_array('billing_document', $missingFields); + + return ($hasCpf && (!$hasCnpj || !$hasDocument)) + || ($hasCnpj && (!$hasCpf || !$hasDocument)) + || ($hasDocument && (!$hasCpf || !$hasCnpj)); +} + function checkCompatibilityWithFeatures() { $compatibilization = new FeatureCompatibilization(); @@ -334,8 +353,8 @@ function versionUpdateWarning($currentVersion, $newVersion) if ($currentVersionMajorPart >= $newVersionMajorPart) { return; } -?> -
+ ?> +

@@ -347,9 +366,9 @@ function versionUpdateWarning($currentVersion, $newVersion) printf( esc_html__( 'This new release contains crucial architecture and functionality updates. ' . - 'We highly recommend you %1$sbackup your site before upgrading%2$s. ' . - 'It is highly recommended to perform and validate the update first in the staging ' . - 'environment before performing the update in production.', + 'We highly recommend you %1$sbackup your site before upgrading%2$s. ' . + 'It is highly recommended to perform and validate the update first in the staging ' . + 'environment before performing the update in production.', 'woo-pagarme-payments' ), '', @@ -359,7 +378,7 @@ function versionUpdateWarning($currentVersion, $newVersion)
-get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_configuration'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -408,7 +427,7 @@ function wcmpCreateCoreCustomerTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_customer'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -427,7 +446,7 @@ function wcmpCreateCoreChargeTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_charge'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -454,7 +473,7 @@ function wcmpCreateCoreOrderTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_order'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -474,7 +493,7 @@ function wcmpCreateCoreTransactionTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_transaction'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -506,7 +525,7 @@ function wcmpCreateCoreSavedCardTable($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_saved_card'; $query = "CREATE TABLE IF NOT EXISTS {$tableName} @@ -530,7 +549,7 @@ function wcmpCreateCoreHubInstallToken($upgradePath) require_once $upgradePath; - $charset = $wpdb->get_charset_collate(); + $charset = $wpdb->get_charset_collate(); $tableName = $wpdb->prefix . 'pagarme_module_core_hub_install_token'; $query = "CREATE TABLE IF NOT EXISTS {$tableName}